Update or insert new parse object using cloud code - parse-platform

As many who came before me, I'm trying to run a bit of cloud code that will check for uniqueness and then insert or update the object as necessary.
The code correctly determines whether or not there is an existing object in the db with the same device token as the request.object
However, the existing object will not update it's countdownValue to 200.
I have tried adding and omitting the object.save() function
I have tried adding, omitting, and exchanging the response.error and response.success functions
The preexisting object remains untouched in all cases.
I have tried Updating existing Parse object in Cloud Code and many others.
Any help or thoughts would be greatly appreciated.
var Countdown = Parse.Object.extend("Countdown");
Parse.Cloud.beforeSave("Countdown", function(request, response) {
if (!request.object.get("devicetoken")) {
response.error('A Countdown must have a devicetoken.');
} else {
var query = new Parse.Query(Countdown);
query.equalTo("devicetoken", request.object.get("devicetoken"));
query.first({
success: function(object) {
if (object) {
object.set("countdownValue", "200");
object.save();
response.error("Failing on purpose");
}
else
{
response.success();
}
},
error: function(error) {
response.error("Could not validate uniqueness for this Countdown object.");
}
});
}
});

Related

Parse.com background job fail the service is currently unavailable

I am using Cloud Code to update all users, everyday. It used to work, but now getting error after 5 minute processing. "the service is currently unavailable" without any reason. I have checked status.parse.com and there is no relevant down. I have 10 000 users.
Parse.Cloud.job("makeUsersPassiveAndSendPushes", function(request, status) {
Parse.Cloud.useMasterKey();
var activeUsers = [];
var limitDoneUsers = [];
var nowDate=new Date();
var updatedUsers = [];
var query = new Parse.Query(Parse.User);
query.equalTo("passive",false);
query.each(function(user) {
if(user.get("passive") === false){
activeUsers.push(user);
user.set("passive", true);
user.set("passiveDate",nowDate);
}
if(user.get("isLimitDone")){
limitDoneUsers.push(user);
}
user.set("isLimitDone",false);
user.set("activeMatch",null);
user.set("canGetMatch",true);
user.set("dailyMatchEndCount",0);
//user.set("lastMatchLimit",false);
user.set("todaysMatches",[]);
updatedUsers.push(user);
return user.save();
})
Could you help me? Thanks.
You may want to try modifying the last line from:
return user.save();
to use callbacks for the save function, to ensure they are firing in sequence:
return user.save(null, {
success: function (user) {
return user;
},
error: function (error) {
return Parse.Promise.error(new Error("error"));
}
});
Another alternative would be to use the saveAll function like this:
return Parse.Object.saveAll(updatedUsers).then(function() {
//code that fires after all objects are saved
});
Also, are you using the hosted Parse.com environment or have you transitioned to another provider like Heroku & mLab?
As a fellow Parse user with this same issue (background job failing with this error when performing many inserts), I look forward to any comments you may have.

PARSE check original object on BeforeSave

I need to check the original object on before save to see what value has changed. currently i have this:
Parse.Cloud.beforeSave("Stats", function(request, response) {
if (!request.object.isNew()){
var query = new Parse.Query("Stats");
query.get(request.object.id, {
success: function(oldObject) {
alert('OLD:' + oldObject.get("Score") + "new:" + request.object.get("Score"));
/*Do My Stuff Here*/
response.success();
},
error: function(oldObject, error) {
response.error(error.message);
}
});
}else{
response.success();
}
});
The problem is that oldObject is equal to request.object.
Also the alert result is this: OLD:10 new:10, but the real old score was 5. Also according to the before save input log the original is really 5.
Any ideia what i am doing wrong?
Edit:
Here is the before save log.
before_save triggered for Stats as master:
Input: {"original":{"achievements":[],"Score":"100"updatedAt":"2015-11-02T10:09:24.170Z"},"update":{"Score":"110"}}
Result: Update changed to {"Score":"110"}
Edit2:
Is there any way to get the dirty value?
console.log("dirty: "+ request.object.dirty("score"));
I2015-11-03T14:23:12.198Z]dirty: true
The official way to know if a field was modified is to call dirty().
My guess is that querying for that particular object somehow updates all "instances" of that object in the current scope, and that's way dirty() works only if called before the query.
An option to get both the old and the new value is to mantain it in a separate field. For example, from your client you could call (pseudocoding, but you get the point):
// OldScore here is 0
statObject.put("Score") = 100;
statObject.saveInBackground();
Then in Cloud Code:
Parse.Cloud.beforeSave("Stats", function(request, response) {
var stat = request.object;
if (!stat.isNew()){
if (stat.dirty("Score")) {
var newValue = stat.get("Score") // 100
var oldValue = stat.get("OldScore") // 0
// Do other stuff here
stat.put("OldScore", newValue);
response.success();
} else {
response.success();
}
} else {
response.success();
}
});
However the issue you are describing is somewhat strange. Maybe you could try with the fetch() command; it should return the old value. However it will invalidate every other dirty field.

Using a query count inside an afterSave trigger (Parse.com cloud code)

I have a small afterSave trigger in my parse cloud code. The trigger just re-counts items that are flagged as deleted=false.
When I update my object, the count goes just fine, except when I update the deleted flag. It seems like the count is considering objects BEFORE the save event, which is not what I would expect from an "afterSave" trigger.
On the other hand, by using a "find" instead of a "count" on the very same query, I will always get the right number of objects. Of course the "find" way will go just when the query stays below 1000 objects.
Is there something wrong in my code? Is it the expected behavior? Is it a bug? Any alternative way to count objects the right way?
Thank you so much for your attention
Parse.Cloud.afterSave("BranchLike", function(request) {
console.log("Managing branchLike after save...");
Parse.Cloud.useMasterKey();
var branch = request.object.get("branch");
var branchLikeClass = Parse.Object.extend("BranchLike");
var type = request.object.get("type");
var branchLikeQuery = new Parse.Query(branchLikeClass);
branchLikeQuery.equalTo("branch",branch);
branchLikeQuery.equalTo("deleted",false);
branchLikeQuery.equalTo("type",type);
branchLikeQuery.count({
success: function(count) {
console.log("count = "+count); //works fine except on "delete" flag updates
/* ... */
},
error: function(error) {
/* ... */
}
});
branchLikeQuery.find({
success: function(branchLikes) {
console.log("ALTERNATIVE COUNT = "+branchLikes.length); //works fine when having less than 1000 objects
},
error: function(error) {
/* ... */
}
});
});

Parse, JS Updates in Real Time

I have the following code, where I have a myBool (a boolean) in my Data Browser initially set to false,
however sometime while I'm still viewing my page I have code set to turn it to true.
How can I make a real time update that will automatically hide my #div when myBool turns to true?
var myBool = currentUser.get("myBool");
if(myBool) {
$('#div').hide();
}
I did some research and found that the Parse.Cloud.afterSave() function may be useful, but I don't see how it will update the content automatically?
Hope I've been clear!
Thanks.
Edit:
Possibly something like this in my main.js?
Parse.Cloud.afterSave("setBool", function() {
var query = new Parse.Query(Parse.Installation);
query.equalTo('myBool', true);
Parse.Push.send({
where: query,
}, {
success: function() {
$('#div').hide();
},
error: function(error) {
$('#div').show();
}
});
});
Your problem with your afterSave function is that your calling it for a function rather than a class.
AfterSave is called after an object from a certain class is saved. If your bool
Parse.Cloud.afterSave(Parse.Installation, function(request) {
// Send push here, use request to target correct user
});
Additionally your push listener should be the one modifying the divs, not the CloudCode.

Parse - afterSave and accessing request object?

I send a request to parse that includes a Comment object that has a pointer to a User named "from".
In afterSave I need to read this and I'm having all kinds of problems. beforeSave works just fine, but I want to execute this code in afterSave;
Parse.Cloud.afterSave("Comment", function(request) {
var userQuery = new Parse.Query("User");
userQuery.get(request.object.get("from").id, {
success: function(user) {
},
error : function(error) {
console.error("errrrrrrrr" + error);
}
});
});
Here is the log I'm seeing on parse
errrrrrrrrr [object Object]
EDIT:
I also tried
var userQuery = new Parse.Query("_User");
Seems like I had to call useMasterKey, since I was fetching a user data.
I'm not entirely sure about this though so I'll keep this question open.
Parse.Cloud.useMasterKey();
Have you tried this?
var userQuery = new Parse.Query(Parse.User);
Try to fetch the pointer directly:
var fromUserPointer = request.object.get("from");
fromUserPointer.fetch().then(function(fetchedFromUser){
},function(error){
});
Slightly different approach.
This assumes that you have the comment object available right there, or at least its id.
Instead of querying the User collection, how about this:
var commentQuery = new Parse.Query("Comment");
commentQuery.include("from");
commentQuery.get(<commentId>, {
success: function (comment)
{
var user = comment.get("from"); // Here you have the user object linked to the comment :)
},
error: function (error)
{
console.log("ERROR: ");
console.log(error);
}
});

Resources