Description
Issue Description
Our Android users with multiple devices are permanently getting code=209, message=invalid legacy session token
on all but one of their devices.
- Users had several devices with our app installed
- Our app was pointed at parse.com (not yet parse-server)
- The users had a single ParseUser record, they were logged into it on each device, our app was not using revocable sessions
- We updated our Android app, to switch to parse-server
- The Android app on startup (every time) calls
ParseUser.enableRevocableSessionInBackground()
What we see is:
a. The first device to update works fine
b. The other devices do not
So despite the other devices calling ParseUser.enableRevocableSessionInBackground()
, they are still getting code=209, message=invalid legacy session token
on all parse operations.
The only work around we've found is to get them to uninstall and reinstall the app on those devices.
Steps to reproduce
- Install 0.1.229 of our Android app on two devices, this points to
parse.com
- In the Account section, on one app, create an account
- In the Account section, on the other app, login to that account
- Optional: create an invoice one device, confirm it syncs to other device
- Update device 1 to 0.1.232, now the app points to our
parse-server
, and callsParseUser.enableRevocableSessionInBackground()
- See everything works fine
- Update device 2 to 0.1.232
- Get exception
com.parse.ParseRequest$ParseRequestException: invalid session token
when the app starts up, when it tries to callParseUser.getCurrentUser().saveInBackground()
Expected result: apps on both devices work properly, and can do basic parse operations involving the ParseUser
like saving it, saving other objects pointing to it etc
Environment Setup
- Server
- parse-server version 2.2.22
- using Express
- Operating System: Android
- Localhost or remote server? Heroku
- Database
- Hosted at mLab
- Android app
- parse sdk verison 1.13.1
Code
Before (parse.com): https://gist.github.com/alexblack/a2c8bdde59608e85f192448f8e4dde84
After (parse-server): https://gist.github.com/alexblack/8fd376d54c1535a5b8777cbbef4b82df
Logs/Trace
Exception: http://crashes.to/s/16792fdcd3d
{
"client": {
"name": "raygun-node",
"version": "0.8.5"
},
"groupingKey": "code209messageinvalidsessiontoken",
"error": {
"message": "code=209, message=invalid session token"
},
"request": {
"hostName": "invoice-simple.herokuapp.com",
"url": "/parse/batch",
"httpMethod": "POST",
"ipAddress": "::ffff:10.186.80.249",
"queryString": {},
"headers": {
"host": "invoice-simple.herokuapp.com",
"connection": "close",
"x-parse-os-version": "5.1",
"x-parse-app-build-version": "2000359",
"x-parse-client-version": "a1.13.1",
"x-parse-app-display-version": "0.1.232",
"x-parse-installation-id": "d3ca7c2a-60a9-4f44-9d46-d9391940d1cc",
"user-agent": "Parse Android SDK 1.13.1 (com.aadhk.woinvoice/2000359) API Level 22",
"x-parse-session-token": "voARgYrfgzc1SYKF7gm19Bmc8",
"x-parse-application-id": "F8pgJyHm8jxQhXxYnpdEzBTxLP2Nhu68JLtmek3y",
"content-type": "application/json",
"accept-encoding": "gzip",
"x-request-id": "1318fd32-036f-48b0-9ae0-a7fd2a7260b3",
"x-forwarded-for": "114.125.12.147",
"x-forwarded-proto": "http",
"x-forwarded-port": "80",
"via": "1.1 vegur",
"connect-time": "0",
"x-request-start": "1475892231454",
"total-route-time": "0",
"content-length": "499"
},
"form": {
"requests": [
{
"method": "PUT",
"path": "/parse/classes/_Installation/UslVQbptng",
"body": {
"pushType": "gcm",
"deviceToken": "APA91bGFWQgXPnZoI6a4M369qGpKVfCrfLx0ajdSV0aihPCxwSWuXO-XtyB_TvnvyhiKO6eGNT5_VmEytJDP4CUhF_W-hNI6bXtKpJyihHm1XupvtUXz430fYwJYCBbaXOFYDOk4xoIa",
"appVersion": "0.1.232",
"parseVersion": "1.13.1",
"objectId": "UslVQbptng"
}
},
{
"method": "PUT",
"path": "/parse/classes/_User/3Ms85kJUin",
"body": {
"accountId": "9caae171f3654c95a7bfcba87c8b8639",
"countryCode": "id",
"objectId": "3Ms85kJUin"
}
}
]
}
},
"machineName": "33f76be6-2c44-4a29-94db-eb8740cd37ba",
"environment": {
"osVersion": "Linux linux 3.13.0-95-generic",
"architecture": "x64",
"totalPhysicalMemory": 64426360832,
"availablePhysicalMemory": 3063279616,
"utcOffset": 0,
"processorCount": 8,
"cpu": "Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz"
},
"userCustomData": {},
"user": {},
"tags": [],
"OccurredOn": "2016-10-08T02:03:51.48Z"
}
Caused by: org.json.JSONException: Value {"code":209,"error":"invalid session token"} of type org.json.JSONObject cannot be converted to JSONArray
at org.json.JSON.typeMismatch(JSON.java:111)
at org.json.JSONArray.<init>(JSONArray.java:96)
at org.json.JSONArray.<init>(JSONArray.java:108)
at com.parse.ParseRESTObjectBatchCommand.onResponseAsync(ParseRESTObjectBatchCommand.java:163)
... 13 more
Inner throwable #1: com.parse.ParseRequest$ParseRequestException: bad json response
at com.parse.ParseRequest.newTemporaryException(ParseRequest.java:290)
at com.parse.ParseRESTObjectBatchCommand.onResponseAsync(ParseRESTObjectBatchCommand.java:167)
at com.parse.ParseRequest$3.then(ParseRequest.java:137)
at com.parse.ParseRequest$3.then(ParseRequest.java:133)
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 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
Caused by: org.json.JSONException: Value {"code":209,"error":"invalid session token"} of type org.json.JSONObject cannot be converted to JSONArray
at org.json.JSON.typeMismatch(JSON.java:111)
at org.json.JSONArray.<init>(JSONArray.java:96)
at org.json.JSONArray.<init>(JSONArray.java:108)
at com.parse.ParseRESTObjectBatchCommand.onResponseAsync(ParseRESTObjectBatchCommand.java:163)
at com.parse.ParseRequest$3.then(ParseRequest.java:137)
at com.parse.ParseRequest$3.then(ParseRequest.java:133)
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 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)