In my ParseServer migrated into the Heroko + mLab stack,
I have a beforeSave function set for a custom "OBSERVATION" Class as below.
Parse.Cloud.beforeSave("OBSERVATION", function(request, response) {
... ...
var currUser = request.user;
console.log(request);
console.log("*** User objectId: " + currUser.id + "; " + currUser.getSessionToken());
... ...
});
I want to get the user name triggering the Save event. According to the Parse JavaScript SDK Reference, a "BeforeSaveRequest" takes a "user" as a member, which represents the User triggering the "Save" event.
However, this is always "undefined" for me. Is there anything I missed or did wrong?
Please include a detailed list of steps that reproduce the issue. Include curl commands when applicable.
{ triggerName: 'beforeSave',
**user: {ParseObject {
sessionToken: 'xxxxxxxxxxxxxxx',
id: 'hDijlsmDP'
}},**
object:
ParseObject {
_objCount: 1538,
className: 'OBSERVATION',
id: 'xUskfmanDY' },
master: true,
log: FileLoggerAdapter {},
original:
ParseObject {
_objCount: 1541,
className: 'OBSERVATION',
id: 'xUskfmanDY' }
}
{ triggerName: 'beforeSave',
object:
ParseObject {
_objCount: 1538,
className: 'OBSERVATION',
id: 'xUskfmanDY' },
master: true,
log: FileLoggerAdapter {},
original:
ParseObject {
_objCount: 1541,
className: 'OBSERVATION',
id: 'xUskfmanDY' }
}
You can turn on additional logging by configuring VERBOSE=1 in your environment.
I see that master is set to true here, how did you save the object that this beforeSave should be called on? Is a user authenticated?
I see the same behaviour in afterSave cloud functions. request.user is always undefined
Please answer all my questions. How is the object saved? Is there a currently authenticated user at all?
I see my error. Was using it when user was signing up. thanks.
@bohemima I used "Parse.Cloud.useMasterKey();" in the beforeSave function. Did this make the object saved correctly?
Also the "OBSERVATION" class has both the Public Access and Write.
Why was this issue closed? Has it already been solved? Where is the solution please?
Can you provide a curl example of the request you're sending to your server?
Parse.Cloud.useMasterKey() is not available in Parse Server.
@hramos I am not sure how to generate a curl command as it was from the beforeSave function. Isn't it automatically triggered by the Parse Server before a new document is inserted to the table?
As Parse.Cloud.useMasterKey() is not available in Parse Server, can I get rid of this line from the code?
Can you provide the logs when running with VERBOSE=1?
@flovilmart Where should I set VERBOSE = 1? In Heroku or ParseServer? My ParseServer was deployed to Heroku from the GitHub repository ParseServerExample.
In the heroku environment variables.
I added VERBOSE=1 to the config. vars in Heroku settings; and added a new record to the OBSERVATION table with only APP-ID and MASTER-KEY set in the curl headers.
The Heroku console printed:
Oct 27 16:39:08 nemp-nsw-dev heroku/router: at=info method=POST path="/parse/classes/OBSERVATION" host=nemp-nsw-dev.herokuapp.com request_id=36c9b811-cdb0-4599-99d9-0d3feb79429b fwd="107.178.194.77" dyno=web.1 connect=2ms service=125ms status=500 bytes=546
Oct 27 16:39:09 nemp-nsw-dev app/web.1: { triggerName: 'beforeSave',
Oct 27 16:39:09 nemp-nsw-dev app/web.1: object: ParseObject { _objCount: 731, className: 'OBSERVATION' },
Oct 27 16:39:09 nemp-nsw-dev app/web.1: master: true,
Oct 27 16:39:09 nemp-nsw-dev app/web.1: log: FileLoggerAdapter {} }
Oct 27 16:39:09 nemp-nsw-dev app/web.1: verbose: error: TypeError: Cannot read property 'id' of undefined
Oct 27 16:39:09 nemp-nsw-dev app/web.1: at /app/cloud/main.js:444:49
Oct 27 16:39:09 nemp-nsw-dev app/web.1: at /app/node_modules/parse-server/lib/triggers.js:202:5
Oct 27 16:39:09 nemp-nsw-dev app/web.1: at new Promise (/app/node_modules/babel-polyfill/node_modules/core-js/modules/es6.promise.js:193:7)
Oct 27 16:39:09 nemp-nsw-dev app/web.1: at Object.maybeRunTrigger (/app/node_modules/parse-server/lib/triggers.js:193:10)
Oct 27 16:39:09 nemp-nsw-dev app/web.1: at /app/node_modules/parse-server/lib/RestWrite.js:186:21
Oct 27 16:39:09 nemp-nsw-dev app/web.1: at run (/app/node_modules/babel-polyfill/node_modules/core-js/modules/es6.promise.js:89:22)
Oct 27 16:39:09 nemp-nsw-dev app/web.1: at /app/node_modules/babel-polyfill/node_modules/core-js/modules/es6.promise.js:102:28
Oct 27 16:39:09 nemp-nsw-dev app/web.1: at flush (/app/node_modules/babel-polyfill/node_modules/core-js/modules/_microtask.js:18:9)
Oct 27 16:39:09 nemp-nsw-dev app/web.1: at _combinedTickCallback (internal/process/next_tick.js:67:7)
Oct 27 16:39:09 nemp-nsw-dev app/web.1: at process._tickDomainCallback (internal/process/next_tick.js:122:9)
Oct 27 16:39:09 nemp-nsw-dev app/web.1: error: Uncaught internal server error. [TypeError: Cannot read property 'id' of undefined] TypeError: Cannot read property 'id' of undefined
Oct 27 16:39:09 nemp-nsw-dev app/web.1: at /app/cloud/main.js:444:49
Oct 27 16:39:09 nemp-nsw-dev app/web.1: at /app/node_modules/parse-server/lib/triggers.js:202:5
Oct 27 16:39:09 nemp-nsw-dev app/web.1: at new Promise (/app/node_modules/babel-polyfill/node_modules/core-js/modules/es6.promise.js:193:7)
Oct 27 16:39:09 nemp-nsw-dev app/web.1: at Object.maybeRunTrigger (/app/node_modules/parse-server/lib/triggers.js:193:10)
Oct 27 16:39:09 nemp-nsw-dev app/web.1: at /app/node_modules/parse-server/lib/RestWrite.js:186:21
Oct 27 16:39:09 nemp-nsw-dev app/web.1: at run (/app/node_modules/babel-polyfill/node_modules/core-js/modules/es6.promise.js:89:22)
Oct 27 16:39:09 nemp-nsw-dev app/web.1: at /app/node_modules/babel-polyfill/node_modules/core-js/modules/es6.promise.js:102:28
Oct 27 16:39:09 nemp-nsw-dev app/web.1: at flush (/app/node_modules/babel-polyfill/node_modules/core-js/modules/_microtask.js:18:9)
Oct 27 16:39:09 nemp-nsw-dev app/web.1: at _combinedTickCallback (internal/process/next_tick.js:67:7)
Oct 27 16:39:09 nemp-nsw-dev app/web.1: at process._tickDomainCallback (internal/process/next_tick.js:122:9)
@grassland-curing-cfa a curl request that creates the object that is covered by this beforeSave hook would suffice. The curl request should show that the object is in fact being saved as part of an authenticated user session.
The curl request is:
curl -X POST -H "X-Parse-Application-Id: {APP_ID}" -H "X-Parse-Master-Key: {MASTER_KEY}" -H "Content-Type: application/json" -d "{\"ObservationStatus\":0, \"AreaCuring\":20,\"Comments\":\"Entered to Parse-server-example API on Heroku\"}" https://nemp-nsw-dev.herokuapp.com/parse/classes/OBSERVATION
As I've been saying from the start, there is no user authenticated here (No Session-Token sent) and you are using the Master-Key.
as @bohemima said, the request.user is only set if you pass a valid session token to your request.
If I pass in a valid session-token to creating an object, does the beforeSave function picks up the user?
Yes, that's pretty much the only way
Thanks to all for your help! @flovilmart @bohemima @hramos
I should have used REST-API-KEY and SESSION-TOKEN.
wait....:) the request.object in beforeSave is not the object as it used to be in parse hosted
this is my log when asking for:request.object:
ParseObject {_objCount: 133, className: "Address"}
here is my cloud code:
//this function put admins role in address of users
Parse.Cloud.beforeSave("Address", function(request, response)
{
var oldAcl = request.object.get('ACL');
var addressACL = oldAcl;
addressACL.setRoleReadAccess("admins", true);
request.object.setACL(addressACL);
response.success();
});
what am i missing here?
this is the log when i ask for request:
Object {triggerName: "beforeSave", object: ParseObject, master: false 鈥
installationId:"93569ef0-8acd-4d33-9fb8-d2ce43ecc051"
log:LoggerController {options: undefined, appId: "kAnTpwWcbY1oYOzvvsOcp5E1mvS8J8IFttaM6qbp", undefined: WinstonLoggerAdapter}
master:false
object:ParseObject {_objCount: 133, className: "Address"}
triggerName:"beforeSave"
user:ParseUser {_objCount: 122, className: "_User", id: "L7qdo0iCzk"}
__proto__:Object {constructor: function Object() { [native code] }, toString: function toString() { [native code] }, toLocaleString: function toLocaleString() { [native code] } 鈥
@kalitas I highly recommend asking on Stack Overflow as this issue has already been closed.
I am also seeing request.user as undefined on all beforeSave functions, even though request.user is correctly set on the Parse Cloud functions that trigger the beforeSave. I am using parse-server v2.2.4 and running it locally. Also seen on v2.2.22.
@josholdham as this is a closed issue please open a separate one if you feel this is a bug.
Please make sure you actually have a authenticated user before AND that you are sending the sessionToken down on any further save/find/get/etc. (As described here: https://github.com/ParsePlatform/parse-server/wiki/Compatibility-with-Hosted-Parse#no-current-user)
Most helpful comment
I am also seeing request.user as undefined on all beforeSave functions, even though request.user is correctly set on the Parse Cloud functions that trigger the beforeSave. I am using parse-server v2.2.4 and running it locally. Also seen on v2.2.22.