Error: 101 object not found for update - parse-platform

I've got the follwing parse.com cloud code
Parse.Cloud.afterSave("Action", function (request) {
var BookStatus = Parse.Object.extend("BookStatus");
var Book = Parse.Object.extend("Book");
var book = new Book();
var actionType = request.object.get("actionTypePointer").id;
var bookId = request.object.get("bookPointer").id;
var queryBook = new Parse.Query("Book");
var newBookStatus;
queryBook.get(bookId,{
success: function (gottenBook) {
newBookStatus = "idOfTheBookStatus";
book.id = bookId;
book.set("bookStatus", new BookStatus({id: newBookStatus}));
gottenBook.set("bookStatus", new BookStatus({id: newBookStatus}));
//OPTION 1
gottenBook.save(null,{
success: function(data) {
console.log("Bookstatus updated1");
},
error: function (data,error) {
// error is a Parse.Error with an error code and description.
console.log("Error: " + error.code + " " + error.message);
}
});
//OPTION 2
book.save(null,{
success: function(data) {
console.log("Bookstatus updated2");
},
error: function (data,error) {
// error is a Parse.Error with an error code and description.
console.log("Error: " + error.code + " " + error.message);
}
});
},
error: function (object, error) {
// The object was not retrieved successfully.
// error is a Parse.Error with an error code and description.
console.log("Error: " + error.code + " " + error.message);
}
});
OPTION1
I try to save the queried book after setting the bookStatus to the returned book.
OPTION2
I try to save the new book object after setting the book.Id
book.id = bookId;
book.set("bookStatus", new BookStatus({id: newBookStatus}));
However with any of the 2 options I end up getting in the parse.com logs:
Error: 101 object not found for update
Error: 101 object not found for update
Any idea of what I am doing wrong?
Thanks in advance!
--EDIT
New implementation with fetch:
Parse.Cloud.afterSave("Action", function (request) {
var BookStatus = Parse.Object.extend("BookStatus");
var Book = Parse.Object.extend("Book");
var book = new Book();
var actionType = request.object.get("actionTypePointer").id;
var bookId = request.object.get("bookPointer").id;
book.id = bookId;
console.log("before fetch book.id" + book.id);
var newBookStatus;
book.fetch({
success: function (book) {
newBookStatus = "XMFkXS9NVv";
book.set("bookStatus", new BookStatus({id: newBookStatus}));
console.log("book" + book);
console.log("book.id" + book.id);
console.log("book.isValid()" + book.isValid());
book.save(null,{
success: function(data) {
console.log("Book Status updated to:" +newBookStatus);
},
error: function (data,error) {
// error is a Parse.Error with an error code and description.
console.log("Error: " + error.code + " " + error.message);
}
});
},
error: function (object, error) {
// The object was not retrieved successfully.
// error is a Parse.Error with an error code and description.
console.log("Error: " + error.code + " " + error.message);
}
});
});
With result:
Input: {"place":{"__type":"GeoPoint","latitude":41.354643806134625,"longitude":2.121594674804572},"bookLocationDescription":"sad","bookPointer":{"__type":"Pointer","className":"Book","objectId":"kWcALge4az"},"actionTypePointer":{"__type":"Pointer","className":"ActionType","objectId":"kJC954w9iO"},"userPointer":{"__type":"Pointer","className":"_User","objectId":"6xpiAHX9Ju"},"createdAt":"2013-05-16T13:59:33.810Z","updatedAt":"2013-05-16T13:59:33.810Z","objectId":"PwlXhKL51l","ACL":{"6xpiAHX9Ju":{"read":true,"write":true},"*":{"read":true}}}
Result: Success
I2013-05-15T20:52:19.170Z] before fetch book.idc1iKxw3NLD
I2013-05-15T20:52:19.273Z] book[object Object]
I2013-05-15T20:52:19.273Z] book.idc1iKxw3NLD
I2013-05-15T20:52:19.273Z] book.isValid()true
I2013-05-15T20:52:19.325Z] Error: 101 object not found for update

Your afterSave hook is overwriting the fetched Book's object id. Even if you're setting the same object id on it, the object now thinks it's dirty and it's no longer a valid reference.
Avoid this by using the book returned by get() and not updating it's id:
Parse.Cloud.afterSave("Action", function (request) {
var BookStatus = Parse.Object.extend("BookStatus");
var Book = Parse.Object.extend("Book");
var book = new Book();
var actionType = request.object.get("actionTypePointer").id;
var bookId = request.object.get("bookPointer").id;
var queryBook = new Parse.Query("Book");
var newBookStatus;
queryBook.get(bookId,{
success: function (book) {
newBookStatus = "idOfTheBookStatus";
book.set("bookStatus", new BookStatus({id: newBookStatus}));
book.save(null,{
success: function(data) {
console.log("Bookstatus updated1");
},
error: function (data,error) {
// error is a Parse.Error with an error code and description.
console.log("Error: " + error.code + " " + error.message);
}
});
},
error: function (object, error) {
// The object was not retrieved successfully.
// error is a Parse.Error with an error code and description.
console.log("Error: " + error.code + " " + error.message);
}
});
});
Since you already know the id for this book, instead of using a query, you can create a pointer and fetch it directly.
Final afterSave hook:
Parse.Cloud.afterSave("Action", function (request) {
var BookStatus = Parse.Object.extend("BookStatus");
var Book = Parse.Object.extend("Book");
var book = new Book();
var actionType = request.object.get("actionTypePointer").id;
var bookId = request.object.get("bookPointer").id;
book.id = bookId;
var newBookStatus;
book.fetch({
success: function (book) {
newBookStatus = "idOfTheBookStatus";
book.set("bookStatus", new BookStatus({id: newBookStatus}));
book.save(null,{
success: function(data) {
console.log("Bookstatus updated1");
},
error: function (data,error) {
// error is a Parse.Error with an error code and description.
console.log("Error: " + error.code + " " + error.message);
}
});
},
error: function (object, error) {
// The object was not retrieved successfully.
// error is a Parse.Error with an error code and description.
console.log("Error: " + error.code + " " + error.message);
}
});
});

Here's how I did it after some running around
ParseCrashReporting.enable(this);
// Enable Local Datastore.
Parse.enableLocalDatastore(this);
// Add your initialization code here
Parse.initialize(this, "*******", "******");
ParseUser.enableAutomaticUser();
ParseACL defaultACL = new ParseACL();
ParseACL.setDefaultACL(defaultACL, true);
// save the installation
ParseInstallation.getCurrentInstallation().saveInBackground();
More info on the issue in my blog post here:
http://aprogrammersday.blogspot.com/2015/02/fix-parse-101-error-object-not-found.html

Whilst looking for this error I found this thread the most useful. I wanted to add that object not found for get can also essentially mean foreign key reference not found.
The not found for get error can be incredibly unhelpful; for me it wasn't even giving a line number where the error was occurring, the error message is very vague and I could not find reference to the phrase in any of the documentation.
If you are getting this error, you will find a lot of reference to permissions issues, but if you are already using the master key then you need to find the object that is being referenced by a foreign key on your selected object.

Related

Parse Javascript Platform Change Password Error

I defined a cloud codeļ¼š
Parse.Cloud.define("updateUser", async (request) => {
const query = new Parse.Query("User");
query.get(request.params.id, {useMasterKey:true})
.then(function(user) {
user.set("username", request.params.username);
user.set("password", request.params.password);
user.set("gender", request.params.gender);
return user.save(null, {useMasterKey:true});
}).catch(function(error) {
console.error("Got an error " + error.code + " : " + error.message);
});
});
Return has been changed successfully.
But, using the new password to log in on the mobile app, the password is incorrect.
{"code":101, "stack": "Error": Invalide username/password}
I think you need to return the first promise. Also try to use setUsername and setPassword. It would be something like this:
Parse.Cloud.define("updateUser", async (request) => {
const query = new Parse.Query("User");
return query.get(request.params.id, {useMasterKey:true})
.then(function(user) {
user.setUsername(request.params.username);
user.setPassword(request.params.password);
user.set("gender", request.params.gender);
return user.save(null, {useMasterKey:true});
}).catch(function(error) {
console.error("Got an error " + error.code + " : " + error.message);
});
});

My jquery and ajax call is not responding and showing unexpected error in console

I don't know why my code is giving error while making the ajax call and not responding or working at all. I ran this on an html file. I took this function - getParameterByName() from another stackoverflow answer.tweet-container tag is down the code below outside this script and an empty division.I tried some jquery also.
<script>
function getParameterByName(name, url) {
if (!url) url = window.location.href;
name = name.replace(/[\[\]]/g, "\\$&");
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, " "));
}
$(document).ready(function(){
console.log("working");
var query = getParameterByName("q")
// console.log("query");
var tweetList = [];
function parseTweets(){
if (tweetList == 0){
$("#tweet-container").text("No tweets currently found.")
} else {
//tweets are existing, so parse and display them
$.each(parseTweets, function(key, value){
//console.log(key)
// console.log(value.user)
// console.log(value.content)
var tweetKey = value.key;
var tweetUser = value.user;
var tweetContent = value.content;
$("#tweet-container").append(
"<div class=\"media\"><div class=\"media-body\">" + tweetContent + "</br> via " + tweetUser.username + " | " + View + "</div></div><hr/>"
)
})
}
}
$.ajax({
url:"/api/tweet/",
data:{
"q": query
},
method: "GET",
success:function(data){
//console.log(data)
tweetList = data
parseTweets()
},
error:
function(data){
console.log("error")
console.log(data)
}
})
});
</script>
strong text
Fix the quotes to resolve your syntax error:
$("#tweet-container").append("<div class=\"media\"><div class=\"media-body\">" + tweetContent + " </br> via " + tweetUser.username + " | " + "View</div></div><hr/>")

Parse cloud code afterSave gets triggered twice

I have a aftersave on Parse cloud code. I have made changes to the table once but the aftersave hook triggers twice
1st Update (Actual update)
Input: {"object":{"addedBy":"tt","albumTitle":"ggh","approved":true,
"createdAt":"2015-12-14T03:07:27.253Z","image":
{"__type":"File","name":"tfss-e26ec608-5a0b-46a2-91db-33590139c4b3-
newImage.jpg","url":"http://files.parsetfss.com/0accbdba-e3f2-493d-
ac70-1c6bccc367b9/tfss-e26ec608-5a0b-46a2-91db-33590139c4b3-
newImage.jpg"},"objectId":"p4pLO70gQY","updatedAt":"2015-12-
14T03:07:37.733Z"}}
2nd Update (Shouldn't happen)
Input: {"object":{"addedBy":"tt","albumTitle":"ggh","approved":true,
"createdAt":"2015-12-14T03:07:27.253Z","image":
{"__type":"File","name":"tfss-e26ec608-5a0b-46a2-91db-33590139c4b3-
newImage.jpg","url":"http://files.parsetfss.com/0accbdba-e3f2-493d-
ac70-1c6bccc367b9/tfss-e26ec608-5a0b-46a2-91db-33590139c4b3-
newImage.jpg"},"objectId":"p4pLO70gQY","updatedAt":"2015-12-
14T03:07:38.038Z"}}
The only difference between the two updates is the updatedAt time. Will aftersave be triggered even if the update time changes?
How can I avoid the second aftersave execution?
Here is my cloud code :
Parse.Cloud.afterSave("Photos", function (request) {
var albumNameA = "";
var publicUser = "";
var albumOwner = "";
var photoUniqueId = "";
var isApproved = "";
albumNameA = request.object.get("albumTitle");
publicUser = request.object.get("addedBy");
photoUniqueId = request.object.id;
isApproved = request.object.get("approved");
if (request.object.get("createdAt").getTime() == request.object.get("updatedAt").getTime()) {
var getAlbumOwner = new Parse.Object.extend("Albums");
var q3 = new Parse.Query(getAlbumOwner);
q3.equalTo("title", albumNameA);
q3.first({
success: function (results) {
console.log("Checking for Creator name " + results.get("creatorName"));
albumOwner = results.get("creatorName");
console.log("Uploading a Photo Final " + albumNameA + "-by-" + publicUser + "--ownedby--" + albumOwner);
console.log("Uploading a Photo" + albumNameA + "-by-" + publicUser + "--" + photoUniqueId + "--" + isApproved);
var install = new Parse.Object.extend("Installation");
var q2 = new Parse.Query(install);
q2.equalTo("privacy", privateUserNo);
q2.equalTo("username", albumOwner);
q2.find({
success: function (results) {
if (!isApproved) {
Parse.Push.send({
where: q2, // Set our Installation query
data: {
alert: "New Photo uploaded by " + publicUser + " ,waiting for approval"
}
}, {
success: function () {
// Push was successful
console.log("Push success");
},
error: function (error) {
// Handle error
console.log("Push error");
}
})
}
},
error: function (error) {
console.log("Error: " + error.code + " " + error.message);
}
});
},
error: function (error) {
console.log("Error: " + error.code + " " + error.message);
}
});
} else if (!(request.object.get("createdAt").getTime() == request.object.get("updatedAt").getTime())) {
console.log("all case scenarios");
var getAlbumOwner1 = new Parse.Object.extend("Albums");
var q6 = new Parse.Query(getAlbumOwner1);
q6.equalTo("title", albumNameA);
q6.first({
success: function (results) {
albumOwner = results.get("creatorName");
var sendApproval = new Parse.Object.extend("Photos");
var q4 = new Parse.Query(sendApproval);
q4.descending("updatedAt");
q4.first({
success: function (results) {
var objectIDNeeded = results.id;
var isChanged = results.get("approved");
var currentUpdateTime = results.get("updatedTime");
console.log("Your Photo, " + publicUser + " ,has been approved by " + albumOwner);
var install = new Parse.Object.extend("Installation");
var q5 = new Parse.Query(install);
q5.equalTo("privacy", privateUserNo);
q5.equalTo("username", publicUser);
q5.find({
success: function (results) {
Parse.Push.send({
where: q5, // Set our Installation query
data: {
alert: "Your Photo has been approved by " + albumOwner
}
}, {
success: function () {
// Push was successful
console.log("Push success");
},
error: function (error) {
// Handle error
console.log("Push error");
}
})
},
error: function (error) {
console.log("Error: " + error.code + " " + error.message);
}
});
},
error: function (error) {
console.log("Error: " + error.code + " " + error.message);
}
});
},
error: function (error) {
console.log("Error: " + error.code + " " + error.message);
}
});
}
});

why save event is not working in cloud code?

Find my code below which working very fine. but only problem facing by me is that save event is not working for me.Also you can see my log file in the picture. In each method i tried success and error function which working fine as you can see in picture. I tried this code alot but still... it is not working for me.
It always shows error message.
Code :
Parse.Cloud.afterSave("HouserDetailed", function(request, response)
{
var obj = request.object.id;
//console.log(obj);
// code !
var houserdetailed = new Parse.Object("HouserDetailed");
var query = new Parse.Query("HouserDetailed");
query.equalTo("objectId", obj);
query.first({
success: function(results) {
//alert("updates objectId " +request.object.id + " " + "input" + " "+ request.object.bet_title );
var bet_title = results.get("bet_title");
var match_id = results.get("match_id");
var level_coin = results.get("level_coin");
if(bet_title !== "false")
{
console.log("bet_title :- "+bet_title+", match_id:- "+match_id+", level_coin:- "+level_coin);
// nested query
var better = new Parse.Object("Better");
var query1 = new Parse.Query("Better");
query1.equalTo("match_id", match_id);
query1.first({
success: function(result){
var bet_title_better = result.get("bet_title");
var user_id = result.get("user_id");
var bet_OnNoOfticket = result.get("bet_OnNoOfticket");
var bet_price = result.get("bet_price");
var money_got = bet_OnNoOfticket * bet_price;
console.log("bet_title_better :-"+bet_title_better);
if(bet_title !== bet_title_better)
{
console.log("Condition does not match!");
}
else
{
console.log("Condition match!" + "money got :- "+money_got);
// checking for existing user in parse DB
var wallet = new Parse.Object("Wallet");
var query2 = new Parse.Query("Wallet");
query2.equalTo("user_id", user_id);
query2.first({
success: function(result)
{
console.log("User found");
var wallet_coins_number = result.get("wallet_coins_number");
var objectId = result.get("objectId");
total_amount = +wallet_coins_number + +money_got;
console.log("Total amount got :- " + total_amount );
// saving amount in wallet
var Wallet = Parse.Object.extend("Wallet");
var wallet = new Wallet();
wallet.set("user_id", user_id);
wallet.set("wallet_coins_number", total_amount);
wallet.save(null, {
success: function(wallet){
console.log("amount saved in wallet!");
},
error: function(wallet)
{
console.log("amount not saved in wallet!");
}
});
},
error: function(error)
{
console.log("User not found");
}
});
}
},error: function(error)
{
}
});
}
// nested query end
},
error: function(error) {
console.log("Error: " + error.code + " " + error.message);
}
});
// code !
});][1]][1]
I don't see any log, probably it would tell you what is wrong. But you are attempting to save existing ParseObject with dirty objectId, which is bad idea. You are not allowed to change objectId of existing object. Try to remove wallet.set("objectId", objectId) from your code.
You should not use result.get("objectId") either, use result.id instead.

Parse JavaScript SDK Query Not Working

I would like to know why could you get this error:
Error code: 102, error message: $in requires an array
I'm using Parse JavaScript SDK.
The data structure it this one:
The source code of the function is this one:
Parse.Cloud.define(
"unfollow",
function(request, response) {
var currentUserID = request.params.currentuser;
var followedUserID = new Array(request.params.followeduser);
var queryRemoveFollower = new Parse.Query("userRelation");
queryRemoveFollower.containedIn("userObjectId", followedUserID);
queryRemoveFollower.find({
success: function(result) {
for(var i=0; i<result.length; i++) {
result[i].remove("followers", currentUserID);
result[i].save();
}
var stopFollowingQuery = new Parse.Query("userRelation");
stopFollowingQuery.equalTo("userObjectId", currentUserID);
stopFollowingQuery.find({
success: function(result) {
for(var i=0; i<result.length; i++) {
result[i].remove("following", followedUserID);
result[i].save();
}
response.success("Unfollow succesful!");
},
error: function(error) {
response.success("Something went wrong. Error code: " + error.code + ", error message: " + error.message);
}
});
},
error: function(error) {
response.success("Something went wrong. Error code: " + error.code + ", error message: " + error.message);
}
});
}
);
I know that the data is being currently sent:
fn_unfollow.parse_data_user_id = ruWNYycty7
fn_unfollow.idOfTheUserToUnfollow = KcCNa39sgk
Thanks in advance for the help!!
The problem in your code is the line:
var followedUserID = new Array(request.params.followeduser);
JavaScript's Array constructor has two possible constructors:
new Array(element0, element1, ..., elementN)
new Array(arrayLength)
Since request.params.followeduser is an integer, folowedUserID is being initalized as a EMPTY array with length of request.params.followeduser.
The fix is to use either of the following (untested...):
var followedUserID = new Array(1, request.params.followedUser);
or (preferred):
var followedUserId = [request.params.followedUser];

Resources