Saving or updating ParseUser in cloud code - parse-platform

I am getting the error response as "user objects cannot allow writes from other users" when trying to signUp or update a ParseUser in cloud code.
As specified by the Parse team I am using Parse.Cloud.useMasterKey() so that I can bypass the restrictions.
Where possibly am I going wrong? I am confused as this code was previously working.
Thanks in advance.

If it is possible, can you provide some codes related with your problem? For example below code is updating the Parse User name column successfully (tested on Parse cloud);
Parse.Cloud.define("test", function(request, response) {
Parse.Cloud.useMasterKey();
var query = new Parse.Query(Parse.User);
query.equalTo("objectId", request.params.objectId);
query.first({
success: function(object) {
object.set("name", request.params.name);
object.save();
response.success("Success Message");
},
error: function(error) {
response.error("Error Message");
}
});
});
However, if one of the ParseUser tries to update another then it is highly possible the problem is related with the ACL. If you provide codes, it is really helpful. Hope this helps,
Regards.

Related

Parse Cloud Code beforeSave timeout

When adding an email address to a list I'd like to check in a beforeSave function in my cloud code if the address belong to an existing user. If it doesn't I'd like to stop the save call and return an error response to my mobile app.
When I run the below code I have no problem while entering a valid email address. As soon as I enter an invalid address however the beforeSave function goes into a tizzy and times out after some time, returning a load of rubbish to the the client.
Parse.Cloud.beforeSave("EventUsers", function(request, response) {
var email = request.object.get("email");
console.log("starting beforeSave for user: " + email);
Parse.Cloud.useMasterKey();
var userQuery = new Parse.Query(Parse.User);
userQuery.equalTo("email", email);
userQuery.first().then(function(user) {
console.log("user: " + user.get("email"));
if (user) {
console.log("User exists");
response.success();
}
console.error("No user with that email");
response.error("199");
}, function(error) {
console.error(error);
response.error("198");
});
});
When I run this with an invalid email address I only get the very first console.log calls reported to my console - none of the others are showing.
I'm running my parse server on Heroku.
Are you running this on parse.com or on your own mongo db backend?
In any event, your problem is that email is likely not indexed so it is doing a full table scan. If it is your own backend, you can put an index on email in the collection.
If you're running your own db, not sure if anyone has done it yet (I haven't yet, but should), but you can probably also just put a unique constraint on email and then you can simply catch the rejected promise on user.save() and not worry about the beforeSave hook at all.

Getting Parse Objects via pointers

I am trying to get a Reservation object which contains a pointer to Restaurant.
In Parse Cloud code, i am able to get the restaurants objects associated with Reservations via query.include('Restaurant') in log just before response.success. However, the Restaurants reverted back to pointer when i receive the response on client app.
I tried reverted JSSDK version to 1.4.2 & 1.6.7 as suggested in some answers, but it doesn't work for me.
Parse.Cloud.define('getreservationsforuser', function(request, response) {
var user = request.user
console.log(user)
var query = new Parse.Query('Reservations')
query.equalTo('User', user)
query.include('Restaurant')
query.find({
success : function(results) {
console.log(JSON.stringify(results))
response.success(results)
},
error : function (error) {
response.error(error)
}
})
})
response :
..."restaurant":{"__type":"Pointer",
"className":"Restaurants",
"objectId":"kIIYe7Z0tD"},...
You can't directly send the pointer objects back from cloud code even though you have included it. You need to manually copy the content of that pointer object to a javascript object. Like below:
var restaurant = {}
restaurant["id"] = YOUR_POINTER_OBJECT.id;
restaurant["createdAt"] = YOUR_POINTER_OBJECT.createdAt;
restaurant["custom_field"] = YOUR_POINTER_OBJECT.get("custom_field");
ps: in your code you seem do nothing else other than directly send the response back. I think parse REST api might be a better choice in that case.
It turned out that my code implementation was correct.

request.object.id not returning in afterSave() in Cloud Code

Parse.Cloud.afterSave(function(request) {
var type = request.object.get("type");
switch (type) {
case 'inspiration':
var query = new Parse.Query("Inspiration");
break;
case 'event':
var query = new Parse.Query("Event");
break;
case 'idea':
var query = new Parse.Query("Idea");
break;
case 'comment':
break;
default:
return;
}
if (query) {
query.equalTo("shares", request.object.id);
query.first({
success: function(result) {
result.increment("sharesCount");
result.save();
},
error: function(error) {
throw "Could not save share count: " + error.message;
}
});
}
});
For some reason request.object.id is not returning the object id from the newly created record. I've tested this code out throughly and have isolated it down to the request.object.id variable. I've even successfully ran it with using a pre-existing object ID and it worked fine. Am I using the wrong variable for the object ID?
Thanks in advanced for any help!
Had this exact problem a few weeks ago.
It turned out to be a bug in Parse's newest Javascript SDK. Please have a look at your CloudCode folder - it should contain a global.json file where you can specify the JavaScript SDK version. By default, it states "latest", change it to "1.4.2" and upload your CloudCode folder again.
In case the global.json file is missing in your cloud code folder, please have a look at this thread, where I described how to create it manually.
Thanks for the reply. I found out another work around for this for version 1.6.5. I should probably also mention that my use case for this code is to increment a count column (comments count) when a new relation has been added to a particular record (post).
Instead of implementing an afterSave method on my relation class (comment), I instead implemented a beforeSave method on my class (Post) and used request.object.dirtyKeys() to get my modified columns. From there I check to see if my dirty key was comments and if it is I increment my count column. It works pretty well actually.

How can I correct an invalid key type in Parse Cloud Code?

We made a mistake in our client code where some users attempt to save a false boolean flag (by mistake) and others save a string to the same key in our Parse database.
I'm getting error code from Parse from everyone setting the false boolean as follows:
{"code":111,"error":"invalid type for key premiumType, expected string, but got boolean"}
Until we can release the next version of our client code, I want to intercept and correct this error IN CLOUD CODE. I'm trying this:
Parse.Cloud.beforeSave('GameScore', function(request, response) {
console.log("Entered function");
var premiumType = request.object.get("premiumType");
if (premiumType) {
request.object.set("premiumType", null);
response.success();
} else {
response.success();
}
});
But, the beforeSave function does not get entered unless the key type is correct, so I cannot modify the object here.
Are there any other locations where I can intercept this and modify the code in the cloud?

What kind of object does a Parse.Query.get()

Using the JavaScript SDK, what kind of object would be returned on the following query:
var groupQuery = new Parse.Query('some_valid_class');
var group = groupQuery.get('some_valid_object_id');
console.log(group);
I only see [object Object] in the log.
thanks!
On Cloud Code - You can't print objects directly as we usually does in console of browser.
You have to use console.log(JSON.stringify(yourObject))
Although the documentation doesn't say so, I believe the get method returns a Promise. Here is an example for getting the actual object taken from the documentation:
var query = new Parse.Query(MyClass);
query.get(myId, {
success: function(object) {
// object is an instance of Parse.Object.
},
error: function(object, error) {
// error is an instance of Parse.Error.
}
});
In the success-function a Parse.Object is provided.
You can find all the info at the Parse JavaScript SDK & Cloud Code Reference
Specific Parse.Query.get() documentation here: https://parse.com/docs/js/symbols/Parse.Query.html#get

Resources