Parse-server: ParseObject attributes of the ParseObject in afterSave/beforeSave triggers aren't valid for using in queries.

Created on 7 Jun 2016  路  6Comments  路  Source: parse-community/parse-server

In an afterSave trigger I get an attribute that is ParseObject request.object.get('pointerToOtherParseObject'). I then use that object in a query and get this error: You cannot use [object Object] as a query parameter.

If I convert the object that was an attribute to the triggered object to a new ParseObject everything works as normal.

On the Parse.com hosted service I can use these attributes for performing a query.

Steps to reproduce

Please include a detailed list of steps that reproduce the issue. Include curl commands when applicable.

_Trigger Setup_

  1. Create an afterSave trigger function for "Comment".
  2. In the function get an attribute that is a Pointer to another ParseObject ("Post")
  3. Use that Object in an query.
Parse.Cloud.afterSave("Comment", function(request) {
  var post = request.object.get("post");
  var query = new Parse.Query("DailyPostCommentCount");
  query.equalTo("dayInt",20160607);
  console.log(post);
  query.equalTo("post",post);
  query.first().then(function(commentCount) {
    console.log("successfully found the object that we want to update");
    commentCount.increment("count");
    return commentCount.save();
  }).then(function(savedCommentCount) {
    console.log("saved comment count");
  },function(error) {
    console.log("failed to find the object and update it with error:");
    console.log(error);
  });
});

_Environment Setup_

  1. Use Rest API to create a 'Post'
  2. Use Rest API to create a 'DailyPostCommentCount'
curl -X POST \
  -H "X-Parse-Application-Id: <appId>" \
  -H "X-Parse-REST-API-Key: , <RestKey>" \
  -H "Content-Type: application/json" \
  -d '{"title":"I am Hungry","content":"Where should we go for lunch"}' \
  http://localhost:1337/parse/classes/Post


  curl -X POST \
  -H "X-Parse-Application-Id: <appId>" \
  -H "X-Parse-REST-API-Key: <RestKey>" \
  -H "Content-Type: application/json" \
  -d '{"dayInt":20160607,"post":{"__type":"Pointer","className":"Post","objectId":"objecIdFromFirstRestCall"}}' \
  http://localhost:1337/parse/classes/DailyPostCommentCount

_Hitting the trigger_

  1. Use Rest API to create a 'Comment' and trigger afterSave Function
curl -X POST \
  -H "X-Parse-Application-Id: <appId>" \
  -H "X-Parse-REST-API-Key: <RestKey>" \
  -H "Content-Type: application/json" \
  -d '{"content":"How about Sushirrito", "post":{"__type":"Pointer","className":"Post","objectId":"objecIdFromFirstRestCall"}}' \
  http://localhost:1337/parse/classes/Comment  

Expected Results

THe DailyPostCommentCount to increment 'count' counter.

Actual Outcome

ParseObject { _objCount: 1, className: 'Post', id: 'EJz6jexLbL' }
failed to find the object and update it with error:
ParseError {
code: 107,
message: 'You cannot use [object Object] as a query parameter.' }

If I convert the object to new ParseObject of the correct class everything works as normal:

exports.parseObjectFromParseDictObject = function(dict) {
    var ObjectClass = Parse.Object.extend(dict.className);
    var newObject = new ObjectClass();
    newObject.id = dict.id;
    return newObject;
}

Environment Setup

  • Server

    • parse-server version: 2.2.11
    • Operating System: OSX El Capitan
    • Hardware: MacBook Pro
    • Localhost or remote server? (AWS, Heroku, Azure, Digital Ocean, etc): Localhost

    Same result when tried on Heroku


  • Database


    • MongoDB version: 3.0.9

    • Storage engine: MMAP

    • Hardware: ?

    • Localhost or remote server? (AWS, mLab, ObjectRocket, Digital Ocean, etc): ObjectRocket

      Logs/Trace


You can turn on additional logging by configuring VERBOSE=1 in your environment.

10:11:01 web.1    | verbose: POST /parse/classes/Comment { host: 'localhost:1337',
10:11:01 web.1    |   'user-agent': 'curl/7.43.0',
10:11:01 web.1    |   accept: '*/*',
10:11:01 web.1    |   'x-parse-application-id': 'adsfasdf',
10:11:01 web.1    |   'x-parse-rest-api-key': 'asdfas',
10:11:01 web.1    |   'content-type': 'application/json',
10:11:01 web.1    |   'content-length': '106' } {
10:11:01 web.1    |   "content": "How about Sushirrito",
10:11:01 web.1    |   "post": {
10:11:01 web.1    |     "__type": "Pointer",
10:11:01 web.1    |     "className": "Post",
10:11:01 web.1    |     "objectId": "EJz6jexLbL"
10:11:01 web.1    |   }
10:11:01 web.1    | }
10:11:02 web.1    | ParseObject { _objCount: 1, className: 'Post', id: 'EJz6jexLbL' }
10:11:02 web.1    | verbose: {
10:11:02 web.1    |   "status": 201,
10:11:02 web.1    |   "response": {
10:11:02 web.1    |     "objectId": "ntAEASQLm7",
10:11:02 web.1    |     "createdAt": "2016-06-07T16:11:01.580Z"
10:11:02 web.1    |   },
10:11:02 web.1    |   "location": "http://localhost:1337/parse/classes/Comment/ntAEASQLm7"
10:11:02 web.1    | }
10:11:02 web.1    | verbose: GET /parse/classes/DailyPostCommentCount { 'user-agent': 'node-XMLHttpRequest, Parse/js1.6.14 (NodeJS 4.4.0)',
10:11:02 web.1    |   accept: '*/*',
10:11:02 web.1    |   'content-type': 'text/plain',
10:11:02 web.1    |   host: 'localhost:1337',
10:11:02 web.1    |   'content-length': '320',
10:11:02 web.1    |   connection: 'close' } {
10:11:02 web.1    |   "where": {
10:11:02 web.1    |     "dayInt": 20160607,
10:11:02 web.1    |     "post": {
10:11:02 web.1    |       "_objCount": 1,
10:11:02 web.1    |       "className": "Post",
10:11:02 web.1    |       "id": "EJz6jexLbL"
10:11:02 web.1    |     }
10:11:02 web.1    |   },
10:11:02 web.1    |   "limit": 1
10:11:02 web.1    | }
10:11:02 web.1    | verbose: error: code=107, message=You cannot use [object Object] as a query parameter.
10:11:02 web.1    | failed to find the object and update it with error:
10:11:02 web.1    | ParseError {
10:11:02 web.1    |   code: 107,
10:11:02 web.1    |   message: 'You cannot use [object Object] as a query parameter.' }

Most helpful comment

But the inactivity's from your side! In that case surely it should stay open?

All 6 comments

I think I am seeing something related but a different error - I'm getting {"code":119,"message":"Permission denied for this action."}

I have an Account, which has an owning Customer. In the afterSave I want to update the count of Accounts in the Customer and add the Account to the Customer's array of Accounts.

My afterSave for Account is:

Parse.Cloud.afterSave("Account", function(request) {

    //Parse.Cloud.useMasterKey();

    console.log("request.object id " + request.object.id);
    if (request.object.existed()) {
        console.log("account existed, returning");
        return;
    }

    var sessionToken = request.user.getSessionToken()
    console.log("request.user.getSessionToken " + sessionToken);

    var customer = request.object.get("customer");
    console.log("pre-fetch got customer id " + customer.id);

    return customer.fetch({useMasterKey: true},{sessionToken: sessionToken}).then(function(customer) {

      console.log("got customer id " + customer.id);
        console.log("got customer " + customer.name);
        console.log("customer number of accounts - " + customer.numberOfAccounts);
        customer.increment('numberOfAccounts',1);
        customer.addUnique("accountsArray",request.object);
        return customer.save({useMasterKey: true},{sessionToken: sessionToken});

    }).then(function() {
        console.log("afterSave account SUCCESS");

    },function(error) {
        console.log("afterSave Account: FAIL" + JSON.stringify(error));
        logger.log("afterSave Account: FAIL" + JSON.stringify(error));
    });
});

The logs for these show at even after fetching, the Customer name and numberOfAccounts are undefined.

2016-06-09T07:24:55.670083+00:00 app[web.1]: request.user.getSessionToken r:61f25908638952b2662929c29781626f
2016-06-09T07:24:55.669723+00:00 app[web.1]: request.object id zcysCk91lo
2016-06-09T07:24:55.670155+00:00 app[web.1]: pre-fetch got customer id uJfLlc1cnK
2016-06-09T07:24:55.697868+00:00 app[web.1]: customer number of accounts - undefined
2016-06-09T07:24:55.697207+00:00 app[web.1]: got customer id uJfLlc1cnK
2016-06-09T07:24:55.697833+00:00 app[web.1]: got customer undefined
2016-06-09T07:24:55.767929+00:00 app[web.1]: afterSave Account:    FAIL{"code":119,"message":"Permission denied for this action."}

Both Customer and Account are only accessible to a role called Admin. The calling user (me) is a member of that Role.

In my code above, rather than fetching the Customer, I've tried doing a query like this: query.equalTo("objectId", customer.id);

The Customer that is returned is in the same state as above - members are undefined.

After doing some debugging in the Parse Server code that's returning my error, I think I'm getting that permissions fail because that class doesn't have "addField" permission. However, this code is not adding a field - I suspect Parse Server thinks that because the object is improperly fetched and its fields are undefined.

We're closing this issue due to inactivity.

If this is a bug you care about that is not getting attention, consider opening a pull request with a fix.

But the inactivity's from your side! In that case surely it should stay open?

@zingano did you solve the ParseError 119? thrown in your afterSave function?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

LtrDan picture LtrDan  路  4Comments

ugo-geronimo picture ugo-geronimo  路  3Comments

carjo422 picture carjo422  路  3Comments

shardul08 picture shardul08  路  3Comments

dpaid picture dpaid  路  3Comments