Skip to content

ParseObject attributes of the ParseObject in afterSave/beforeSave triggers aren't valid for using in queries. #2000

Closed

Description

@spenceps

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.' }

Activity

  1. zingano commented on Jun 9, 2016

    @zingano

    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.

  2. zingano commented on Jun 9, 2016

    @zingano

    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.

  3. zingano commented on Jun 9, 2016

    @zingano

    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.

  4. hramos commented on Jul 27, 2016

    @hramos
    Contributor

    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.

  5. zingano commented on Jul 28, 2016

    @zingano

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

  6. shankslouis commented on Dec 8, 2016

    @shankslouis

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions