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

Still have issues logging in with anonymous user #1198

Closed
3 tasks done
yuzeh opened this issue Mar 25, 2016 · 6 comments
Closed
3 tasks done

Still have issues logging in with anonymous user #1198

yuzeh opened this issue Mar 25, 2016 · 6 comments

Comments

@yuzeh
Copy link
Contributor

yuzeh commented Mar 25, 2016

I'm opening a new issue to document my ongoing issues with upgrading from anonymous users.

This is related to #1136 and #639.

On the latest release, authData is still not properly cleaned on PUT requests for the _User class. See below for VERBOSE=1 logs from a parse-server I've set up. This causes an error on the Android SDK.

There are probably two good ways of fixing this:

  • do the clean up on the client side (in this case, the Android SDK) before issuing the PUT request.
  • do the clean up on the server side before sending the response.

1ed868b goes part of the way to fixing it server-side, but does not do it everywhere it should.

I'm in the process of putting a pull request that will fix this in RestWrite.js handleUpdate as well as handleLogIn in UsersRouter.


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

AWS/ElasticBeanstalk, parse-server 2.2.2

Steps to reproduce

It will be hard to give clean repro steps on a general app that has anonymous users enabled, but if requested I'll try.

Logs/Trace

The Android SDK issues a PUT request for signup instead of calling the signUp endpoint because this user already has data saved to the parse-server. The key thing to notice is that in the response, the value associated with authData is {"anonymous": null} instead of null.

PUT /parse/classes/_User/bCsdHm4wrT {
  'content-length': '260',
  'accept-encoding': 'gzip',
  'content-type': 'application/json',
  'user-agent': 'Parse Android SDK 1.13.0 (com.mtailor.android.debug/34) API Level 23',
  'x-forwarded-port': '443',
  'x-forwarded-proto': 'https' } {
  "firstName": "D",
  "password": REDACTED,
  "username": "dan+20160325+4@mtailor.com",
  "authData": {
    "anonymous": null
  },
  "lastName": "H",
  "email": "dan+20160325+4@mtailor.com",
  "objectId": "bCsdHm4wrT"
}
response: {
  "response": {
    "updatedAt": "2016-03-25T20:27:21.104Z",
    "authData": {
      "anonymous": null
    },
    "firstName": "D",
    "username": "dan+20160325+4@mtailor.com",
    "lastName": "H",
    "email": "dan+20160325+4@mtailor.com",
    "_hashed_password": "REDACTED"
  }
}
@flovilmart
Copy link
Contributor

What is the error that you experience on the Android SDK?

@yuzeh
Copy link
Contributor Author

yuzeh commented Mar 28, 2016

Android SDK v1.13

Non-fatal Exception: com.parse.ParseException: java.lang.ClassCastException: org.json.JSONObject$1 cannot be cast to java.util.Map
       at com.parse.ParseTaskUtils$2$1.run(ParseTaskUtils.java:114)
       at android.os.Handler.handleCallback(Handler.java:746)
       at android.os.Handler.dispatchMessage(Handler.java:95)
       at android.os.Looper.loop(Looper.java:148)
       at android.app.ActivityThread.main(ActivityThread.java:5443)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
Caused by java.lang.ClassCastException: org.json.JSONObject$1 cannot be cast to java.util.Map
       at com.parse.ParseUser.getAuthData(ParseUser.java:340)
       at com.parse.ParseUser.synchronizeAuthDataAsync(ParseUser.java:1245)
       at com.parse.ParseUser.synchronizeAllAuthDataAsync(ParseUser.java:1234)
       at com.parse.CachedCurrentUserController$1$2.then(CachedCurrentUserController.java:71)
       at com.parse.CachedCurrentUserController$1$2.then(CachedCurrentUserController.java:67)
       at bolts.Task$15.run(Task.java:917)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:105)
       at bolts.Task.completeAfterTask(Task.java:908)
       at bolts.Task.continueWithTask(Task.java:715)
       at bolts.Task.continueWithTask(Task.java:726)
       at bolts.Task$13.then(Task.java:818)
       at bolts.Task$13.then(Task.java:806)
       at bolts.Task$15.run(Task.java:917)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:105)
       at bolts.Task.completeAfterTask(Task.java:908)
       at bolts.Task.continueWithTask(Task.java:715)
       at bolts.Task.continueWithTask(Task.java:690)
       at bolts.Task.onSuccessTask(Task.java:806)
       at bolts.Task.onSuccessTask(Task.java:796)
       at bolts.Task.onSuccessTask(Task.java:830)
       at com.parse.CachedCurrentUserController$1.then(CachedCurrentUserController.java:47)
       at com.parse.CachedCurrentUserController$1.then(CachedCurrentUserController.java:44)
       at com.parse.TaskQueue.enqueue(TaskQueue.java:69)
       at com.parse.CachedCurrentUserController.setAsync(CachedCurrentUserController.java:44)
       at com.parse.CachedCurrentUserController.setAsync(CachedCurrentUserController.java:17)
       at com.parse.ParseUser.saveCurrentUserAsync(ParseUser.java:926)
       at com.parse.ParseUser.access$200(ParseUser.java:30)
       at com.parse.ParseUser$1.then(ParseUser.java:496)
       at com.parse.ParseUser$1.then(ParseUser.java:493)
       at bolts.Task$15.run(Task.java:917)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:105)
       at bolts.Task.completeAfterTask(Task.java:908)
       at bolts.Task.continueWithTask(Task.java:715)
       at bolts.Task.continueWithTask(Task.java:726)
       at bolts.Task$13.then(Task.java:818)
       at bolts.Task$13.then(Task.java:806)
       at bolts.Task$15.run(Task.java:917)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:105)
       at bolts.Task.completeAfterTask(Task.java:908)
       at bolts.Task.access$100(Task.java:32)
       at bolts.Task$11.then(Task.java:708)
       at bolts.Task$11.then(Task.java:705)
       at bolts.Task.runContinuations(Task.java:956)
       at bolts.Task.trySetResult(Task.java:994)
       at bolts.TaskCompletionSource.trySetResult(TaskCompletionSource.java:39)
       at bolts.TaskCompletionSource.setResult(TaskCompletionSource.java:62)
       at bolts.Task$15$1.then(Task.java:934)
       at bolts.Task$15$1.then(Task.java:921)
       at bolts.Task$14.run(Task.java:872)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:105)
       at bolts.Task.completeImmediately(Task.java:863)
       at bolts.Task.continueWith(Task.java:661)
       at bolts.Task.continueWith(Task.java:672)
       at bolts.Task$15.run(Task.java:921)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:105)
       at bolts.Task.completeAfterTask(Task.java:908)
       at bolts.Task.access$100(Task.java:32)
       at bolts.Task$11.then(Task.java:708)
       at bolts.Task$11.then(Task.java:705)
       at bolts.Task.runContinuations(Task.java:956)
       at bolts.Task.trySetResult(Task.java:994)
       at bolts.TaskCompletionSource.trySetResult(TaskCompletionSource.java:39)
       at bolts.TaskCompletionSource.setResult(TaskCompletionSource.java:62)
       at bolts.Task$15$1.then(Task.java:934)
       at bolts.Task$15$1.then(Task.java:921)
       at bolts.Task$14.run(Task.java:872)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:105)
       at bolts.Task.completeImmediately(Task.java:863)
       at bolts.Task.continueWith(Task.java:661)
       at bolts.Task.continueWith(Task.java:672)
       at bolts.Task$15.run(Task.java:921)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:105)
       at bolts.Task.completeAfterTask(Task.java:908)
       at bolts.Task.access$100(Task.java:32)
       at bolts.Task$11.then(Task.java:708)
       at bolts.Task$11.then(Task.java:705)
       at bolts.Task.runContinuations(Task.java:956)
       at bolts.Task.trySetResult(Task.java:994)
       at bolts.TaskCompletionSource.trySetResult(TaskCompletionSource.java:39)
       at bolts.TaskCompletionSource.setResult(TaskCompletionSource.java:62)
       at bolts.Task$15$1.then(Task.java:934)
       at bolts.Task$15$1.then(Task.java:921)
       at bolts.Task$14.run(Task.java:872)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:105)
       at bolts.Task.completeImmediately(Task.java:863)
       at bolts.Task.access$000(Task.java:32)
       at bolts.Task$10.then(Task.java:654)
       at bolts.Task$10.then(Task.java:651)
       at bolts.Task.runContinuations(Task.java:956)
       at bolts.Task.trySetResult(Task.java:994)
       at bolts.TaskCompletionSource.trySetResult(TaskCompletionSource.java:39)
       at bolts.TaskCompletionSource.setResult(TaskCompletionSource.java:62)
       at bolts.Task$15$1.then(Task.java:934)
       at bolts.Task$15$1.then(Task.java:921)
       at bolts.Task$14.run(Task.java:872)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:105)
       at bolts.Task.completeImmediately(Task.java:863)
       at bolts.Task.access$000(Task.java:32)
       at bolts.Task$10.then(Task.java:654)
       at bolts.Task$10.then(Task.java:651)
       at bolts.Task.runContinuations(Task.java:956)
       at bolts.Task.trySetResult(Task.java:994)
       at bolts.TaskCompletionSource.trySetResult(TaskCompletionSource.java:39)
       at bolts.TaskCompletionSource.setResult(TaskCompletionSource.java:62)
       at bolts.Task$15$1.then(Task.java:934)
       at bolts.Task$15$1.then(Task.java:921)
       at bolts.Task$14.run(Task.java:872)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:105)
       at bolts.Task.completeImmediately(Task.java:863)
       at bolts.Task.continueWith(Task.java:661)
       at bolts.Task.continueWith(Task.java:672)
       at bolts.Task$15.run(Task.java:921)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:105)
       at bolts.Task.completeAfterTask(Task.java:908)
       at bolts.Task.access$100(Task.java:32)
       at bolts.Task$11.then(Task.java:708)
       at bolts.Task$11.then(Task.java:705)
       at bolts.Task.runContinuations(Task.java:956)
       at bolts.Task.trySetResult(Task.java:994)
       at bolts.TaskCompletionSource.trySetResult(TaskCompletionSource.java:39)
       at bolts.TaskCompletionSource.setResult(TaskCompletionSource.java:62)
       at bolts.Task$15$1.then(Task.java:934)
       at bolts.Task$15$1.then(Task.java:921)
       at bolts.Task$14.run(Task.java:872)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:105)
       at bolts.Task.completeImmediately(Task.java:863)
       at bolts.Task.continueWith(Task.java:661)
       at bolts.Task.continueWith(Task.java:672)
       at bolts.Task$15.run(Task.java:921)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:105)
       at bolts.Task.completeAfterTask(Task.java:908)
       at bolts.Task.access$100(Task.java:32)
       at bolts.Task$11.then(Task.java:708)
       at bolts.Task$11.then(Task.java:705)
       at bolts.Task.runContinuations(Task.java:956)
       at bolts.Task.trySetResult(Task.java:994)
       at bolts.TaskCompletionSource.trySetResult(TaskCompletionSource.java:39)
       at bolts.TaskCompletionSource.setResult(TaskCompletionSource.java:62)
       at bolts.Task$15$1.then(Task.java:934)
       at bolts.Task$15$1.then(Task.java:921)
       at bolts.Task$14.run(Task.java:872)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:105)
       at bolts.Task.completeImmediately(Task.java:863)
       at bolts.Task.continueWith(Task.java:661)
       at bolts.Task.continueWith(Task.java:672)
       at bolts.Task$15.run(Task.java:921)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
       at java.lang.Thread.run(Thread.java:818)

@yuzeh
Copy link
Contributor Author

yuzeh commented Mar 28, 2016

I guess the bigger question is why all these fields are being sent back on the PUT request:

response: {
  "response": {
    "updatedAt": "2016-03-25T20:27:21.104Z",
    "authData": {
      "anonymous": null
    },
    "firstName": "D",
    "username": "dan+20160325+4@mtailor.com",
    "lastName": "H",
    "email": "dan+20160325+4@mtailor.com",
    "_hashed_password": "REDACTED"
  }
}

@flovilmart
Copy link
Contributor

Do you have a beforeSave or an afterSave? Depending on the case, parse-server may return some fields.

Given your logs:

com.parse.ParseUser.getAuthData(ParseUser.java:340) 
This is an Android implementation detail that fails to load a null value, we'll try to remove the authData field from the response.

There is a PR opened (#1199) but I'm waiting for unit tests from @yuzeh in order to merge to prevent any further regression.

@yuzeh
Copy link
Contributor Author

yuzeh commented Mar 29, 2016

Yes, I have both a beforeSave and afterSave. The behavior in hosted parse seems to be to not return these fields, so I guess there is an inconsistency here.

Probably the Android client should not be treating a Map as a JSONObject either...

@yuzeh
Copy link
Contributor Author

yuzeh commented Mar 29, 2016

@flovilmart I spent yesterday trying to figure out a test case that would make sense. Now that I understand that beforeSave/afterSave handlers affect what fields get returned, I think I can make that test case.

I'll look into it later today.

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

2 participants