Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
spenceps opened this issue Jun 7, 2016 · 6 comments

Comments

@spenceps
Copy link

spenceps commented Jun 7, 2016

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.' }
@zingano
Copy link

zingano commented Jun 9, 2016

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.

@zingano
Copy link

zingano commented Jun 9, 2016

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.

@zingano
Copy link

zingano commented Jun 9, 2016

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.

@hramos
Copy link
Contributor

hramos commented Jul 27, 2016

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.

@hramos hramos closed this as completed Jul 27, 2016
@zingano
Copy link

zingano commented Jul 28, 2016

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

@shankslouis
Copy link

@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
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants