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

Saving a relation on a User object with beforeSave causes the response to contain a relation op instead of a relation #1606

Closed
3 tasks done
omyen opened this issue Apr 23, 2016 · 14 comments
Milestone

Comments

@omyen
Copy link

omyen commented Apr 23, 2016

Check out this issue for an ideal bug report. The closer your issue report is to that one, the more likely we are to be able to help, and the more likely we will be to fix the issue quickly!

For implementation related questions or technical support, please refer to the Stack Overflow and Server Fault communities.

Make sure these boxes are checked before submitting your issue -- thanks for reporting issues back to Parse Server!

Environment Setup

It's unlikely you'll need to match this setup exactly to reproduce this issue, but included for completeness:

  • Parse server running on Heroku with a mLab MongoDB add-in for a backend
  • JS client code (specifically Angular JS using the Ionic framework) using parse 1.6.14
  • Parse server version 2.2.7 (though any version seems to be able to reproduce this)

Steps to reproduce

  • In your cloud code, set up an empty beforeSave for Users (also works with '_User' instead of Parse.User):
Parse.Cloud.beforeSave(Parse.User, function(req, res){
    res.success();
});
  • In a JS Parse client app running in a browser, log a user in and then run the following code in the client:
var Test = Parse.Object.extend('Test');
var test = new Test();

test.save().then(function(result){
    var relation = Parse.User.current().relation('tests'); 
    relation.add(test); 
    return Parse.User.current().save();
}).then(function(result){
    var errorHere = result.relation('tests');
});

Logs/Trace

  • The browser logs the error:
parse-1.6.14.js:3333 Uncaught Error: Called relation() on non-relation field tests
  • With a breakpoint on line var errorHere = result.relation('tests'); you can see the following inside the attributes of the result object
tests:RelationOp
    _targetClassName:"Test"
    relationsToAdd:Array[1]
    relationsToRemove:Array[0]
    __proto__:Op
  • The verbose Heroku logs support the browser logs; parse-server is responding with an AddRelation op:
2016-04-23T09:57:35.103093+00:00 app[web.1]: verbose: PUT /parse/classes/_User/juAkCJSEY0 { host: 'xxxxxxxx.herokuapp.com',
2016-04-23T09:57:35.103106+00:00 app[web.1]:   connection: 'close',
2016-04-23T09:57:35.103107+00:00 app[web.1]:   origin: 'http://localhost:8100',
2016-04-23T09:57:35.103108+00:00 app[web.1]:   'user-agent': 'Mozilla/5.0 xxxxxx',
2016-04-23T09:57:35.103109+00:00 app[web.1]:   'content-type': 'text/plain',
2016-04-23T09:57:35.103109+00:00 app[web.1]:   accept: '*/*',
2016-04-23T09:57:35.103110+00:00 app[web.1]:   referer: 'http://localhost:8100/',
2016-04-23T09:57:35.103111+00:00 app[web.1]:   'accept-encoding': 'gzip, deflate',
2016-04-23T09:57:35.103112+00:00 app[web.1]:   'accept-language': 'en-GB,en-US;q=0.8,en;q=0.6',
2016-04-23T09:57:35.103112+00:00 app[web.1]:   'x-request-id': 'xxxxxx',
2016-04-23T09:57:35.103113+00:00 app[web.1]:   'x-forwarded-for': 'xxxxxxx',
2016-04-23T09:57:35.103113+00:00 app[web.1]:   'x-forwarded-proto': 'https',
2016-04-23T09:57:35.103114+00:00 app[web.1]:   'x-forwarded-port': '443',
2016-04-23T09:57:35.103114+00:00 app[web.1]:   via: '1.1 vegur',
2016-04-23T09:57:35.103115+00:00 app[web.1]:   'connect-time': '0',
2016-04-23T09:57:35.103116+00:00 app[web.1]:   'x-request-start': '1461405455100',
2016-04-23T09:57:35.103116+00:00 app[web.1]:   'total-route-time': '0',
2016-04-23T09:57:35.103117+00:00 app[web.1]:   'content-length': '385' } {
2016-04-23T09:57:35.103118+00:00 app[web.1]:   "tests": {
2016-04-23T09:57:35.103118+00:00 app[web.1]:     "__op": "AddRelation",
2016-04-23T09:57:35.103119+00:00 app[web.1]:     "objects": [
2016-04-23T09:57:35.103119+00:00 app[web.1]:       {
2016-04-23T09:57:35.103120+00:00 app[web.1]:         "__type": "Pointer",
2016-04-23T09:57:35.103121+00:00 app[web.1]:         "className": "Test",
2016-04-23T09:57:35.103121+00:00 app[web.1]:         "objectId": "i8RMGfHmNx"
2016-04-23T09:57:35.103122+00:00 app[web.1]:       }
2016-04-23T09:57:35.103123+00:00 app[web.1]:     ]
2016-04-23T09:57:35.103123+00:00 app[web.1]:   }
2016-04-23T09:57:35.103124+00:00 app[web.1]: }
2016-04-23T09:57:38.366469+00:00 heroku[router]: at=info method=POST path="/parse/classes/_User/juAkCJSEY0" host=xxxx.herokuapp.com request_id=85167cec-accc-44f8-bae1-b21c77a8cfaa fwd="xxxx" dyno=web.1 connect=0ms service=3265ms status=200 bytes=630
2016-04-23T09:57:38.360971+00:00 app[web.1]: verbose: {
2016-04-23T09:57:38.360997+00:00 app[web.1]:   "response": {
2016-04-23T09:57:38.360999+00:00 app[web.1]:     "updatedAt": "2016-04-23T09:57:35.119Z",
2016-04-23T09:57:38.361000+00:00 app[web.1]:     "tests": {
2016-04-23T09:57:38.361000+00:00 app[web.1]:       "__op": "AddRelation",
2016-04-23T09:57:38.361001+00:00 app[web.1]:       "objects": [
2016-04-23T09:57:38.361001+00:00 app[web.1]:         {
2016-04-23T09:57:38.361002+00:00 app[web.1]:           "__type": "Pointer",
2016-04-23T09:57:38.361002+00:00 app[web.1]:           "className": "Test",
2016-04-23T09:57:38.361003+00:00 app[web.1]:           "objectId": "i8RMGfHmNx"
2016-04-23T09:57:38.361003+00:00 app[web.1]:         }
2016-04-23T09:57:38.361004+00:00 app[web.1]:       ]
2016-04-23T09:57:38.361005+00:00 app[web.1]:     }
2016-04-23T09:57:38.361005+00:00 app[web.1]:   }
2016-04-23T09:57:38.361006+00:00 app[web.1]: }

This also seems to happen to other objects with relations and beforeSave functions, but I can't reliably reproduce it for anything other than a User.

@flovilmart
Copy link
Contributor

Instead of using Parse.User.current() can you try with req.object. the former is unavailable on parse-server and the latter should be the proper _User you are looking for.

@omyen
Copy link
Author

omyen commented Apr 24, 2016

Hi @flovilmart , thanks for the quick response. As far as I can tell, I'm not using Parse.User.current() at all on the parse-server side, only in the client code. In fact, the beforeSave function doesn't do anything apart from calling res.success().

I've edited the issue to be clearer about where the code is run.

@omyen
Copy link
Author

omyen commented Apr 28, 2016

Has anyone reading this been able to reproduce this issue?

@tony-pizza
Copy link

@omyen I have! Ran into a similar thing from the iOS SDK as well: parse-community/Parse-SDK-iOS-OSX#911

@omyen
Copy link
Author

omyen commented May 14, 2016

@peeinears Thanks for the reply - I've "resolved" this issue by fetch()ing the object after any save() with a relation change, but there's still a race condition where the code might want to access the relation before the fetch() is complete.

@tony-pizza
Copy link

@omyen Thanks, yep I've been doing the same thing. fetch()s everywhere.

@omyen
Copy link
Author

omyen commented May 14, 2016

@peeinears Actually, I'm curious - I could only repro this issue on objects with a BeforeSave. Do you see it on any other objects, or is it isolated to BeforeSaves for you too?

@omyen omyen closed this as completed May 14, 2016
@omyen omyen reopened this May 14, 2016
@omyen
Copy link
Author

omyen commented May 14, 2016

Misclicked close

@tony-pizza
Copy link

@omyen I've only noticed it on objects with beforeSaves as well. And I've noticed that removing the beforeSave fixes it.

@borekwa
Copy link

borekwa commented May 15, 2016

@omyen I'm experiencing the same issue, but removing the beforeSave does not resolve the issue for me. I get the error whether or not the beforeSave exists.

The issue appears to be isolated to relations on Parse.User.current(); I am not seeing it on other objects.

@tony-pizza
Copy link

Can a Parse Pro please confirm that the relation operation should not be in the save response?

@flovilmart
Copy link
Contributor

I'm working right now on something similar, I'll post a fix in #1946

@tony-pizza
Copy link

@flovilmart Awesome, thanks!

In the meantime, I just hacked together this monkeypatch to avoid having to fetch() everywhere:

var originalRelation = Parse.Object.prototype.relation;
Parse.Object.prototype.relation = function (attr) {
  if (this.get(attr) instanceof Parse.Op.Relation) {
    return new Parse.Relation(this, attr);
  }
  return originalRelation.apply(this, arguments);
};

@flovilmart
Copy link
Contributor

@peeinears nice patch! But the PR should be merged soon, as soon as we're ready for 2.2.17, you'll be able to remove it :)

flovilmart added a commit that referenced this issue Jul 15, 2016
…ons to SDKs (#1946)

* Adding a test demonstrating issue #1840.

* Fixes #1840

* Adds failing test with other use case

- That test fails on parse.com as well

* Bumps parse to 1.9.0

* exclude pg db

* Exclude pg on other test

* Adds clientSDK compatibility check for forward deletion

- Mark js1.9.0 as compatible

* Strips all operations from result

- fix for #1606
rsouzas pushed a commit to back4app/parse-server that referenced this issue Mar 15, 2017
… delete operations to SDKs (parse-community#1946)

* Adding a test demonstrating issue parse-community#1840.

* Fixes parse-community#1840

* Adds failing test with other use case

- That test fails on parse.com as well

* Bumps parse to 1.9.0

* exclude pg db

* Exclude pg on other test

* Adds clientSDK compatibility check for forward deletion

- Mark js1.9.0 as compatible

* Strips all operations from result

- fix for parse-community#1606
rsouzas pushed a commit to back4app/parse-server that referenced this issue Mar 16, 2017
… delete operations to SDKs (parse-community#1946)

* Adding a test demonstrating issue parse-community#1840.

* Fixes parse-community#1840

* Adds failing test with other use case

- That test fails on parse.com as well

* Bumps parse to 1.9.0

* exclude pg db

* Exclude pg on other test

* Adds clientSDK compatibility check for forward deletion

- Mark js1.9.0 as compatible

* Strips all operations from result

- fix for parse-community#1606
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