i'm trying to make a simple check before saving an object on Parse. I'm using the "beforeSave" method to check if object has necessary fields setup correctly before saving.
The problem is that when i try to get a field of my object it return always undefined even if it is setup correcly in log!
Input: {"original":null,"update":{"ACL":{"abcdefghi":{"read":true,"write":true}},"isDeleted":false,"lastEdit":0,"name":"testobject","uuid":"109d0b30-1ad5-408b-ba49-2ce024935476"}}
and cloud code:
Parse.Cloud.beforeSave("MyObject", function (request, response) {
// return always an error with uuid printed
response.error("Object uuid: " + request.object.get("uuid"));
}
This is a sample code, not my real code but as you can see the object passed to this function has "uuid" field inside but request.object.get("uuid") return always "undefined":
Console log:
Result: Object uuid: undefined
Official documentation say to access object fields in this way, so is this a Parse bug or i'm doing some mistakes?
EDIT 1:
As suggested i tryied to log the object in this way:
console.log("Object: " + JSON.stringify(request.object));
console.log("Request: " + JSON.stringify(request));
The result is:
Object: {}
Request: {"object":{}, <some other fields..>}
Any idea?
EDIT 2:
I reproduced correcly the error and it seems to be a bug with ACL; First i created a new object extending ParseObject (i'm working on Android):
@ParseClassName("Person")
public class ParsePerson extends ParseObject {
public void setName(String name) {
put("name", name);
}
public void setAge(int age) {
put("age", age);
}
public String getName() {
return getString("name");
}
public int getAge() {
return getInt("age");
}
}
And than my background thread it will create and save a test object in this way:
ParsePerson parsePerson = new ParsePerson();
parsePerson.setName("Tom");
parsePerson.setAge(45);
try {
parsePerson.save();
} catch (ParseException e) {
Debug.e("Error code: "+ e.getCode(), e);
}
Than i uploaded this cloud code that does nothing else than log:
Parse.Cloud.beforeSave("Person", function (request, response) {
// log person object
console.log("Object: " + JSON.stringify(request.object));
// respond always success to save the object
response.success();
});
Parse.Cloud.afterSave("Person", function(request) {
// log person object again
console.log("Object: " + JSON.stringify(request.object));
// respond success
response.success();
});
After running it works and it saves correctly the object in the new table. Logs:
Input: {"original":null,"update":{"age":45,"name":"Tom"}}
Result: Update changed to {"age":45,"name":"Tom"}
Object: {"age":45,"name":"Tom"}
The last thing i tryid to do was to set ACL to this object editing android code in this way:
ParsePerson parsePerson = new ParsePerson();
parsePerson.setName("Tom");
parsePerson.setAge(45);
parsePerson.setACL(new ParseACL(ParseUser.getCurrentUser())); // new line
try {
parsePerson.save();
} catch (ParseException e) {
Debug.e("Error code: "+ e.getCode(), e);
}
And after running everything this is the log:
Input: {"original":null,"update":{"ACL":{"userAcl":{"read":true,"write":true}},"age":45,"name":"Tom"}}
Result: Update changed to {}
Object: {}
So is this enough?
EDIT 3:
The only solution i found (this is more a workaround) is to save the object without ACL from Android code and then set ACL in beforeSave on cloud code:
Parse.Cloud.beforeSave("Person", function (request, response) {
// setup ACL for this object
var user = request.user;
var newACL = new Parse.ACL();
newACL.setPublicReadAccess(false);
newACL.setPublicWriteAccess(false);
newACL.setReadAccess(user.id, true);
newACL.setWriteAccess(user.id, true);
request.object.setACL(newACL);
// log person object again
console.log("Object: " + JSON.stringify(request.object));
}
JSON.stringify(request.object)
– Othello