parse-server: Exception while saving a ParseObject with CurrentInstallation set as a property

Experiencing exception while saving a ParseObject with CurrentInstallation set as a property.

Parse.ParseException: at least one ID field (deviceToken, installationId) must be specified in this operation

I have verified that installation ID is set on the CurrentInstallation object before calling SaveAsync.

The code below will save to parse-server on first run when the app is installed. Then, each time the code is run it throws an exception and does not save to parse-server.

Below is the gist of the code. For full code see this repo link: https://github.com/thewizster/hello-parse-installation/blob/master/HelloParse/HelloViewModel.cs

ParseInstallation installation = ParseInstallation.CurrentInstallation;
var instId = installation.InstallationId.ToString();
var world = new ParseObject("World");
world["message"] = "Hello world!";
world["installation"] = installation; // if removed saves every time without exception
world.SaveAsync();

Steps to reproduce

This can be reproduced using this sample code at: https://github.com/thewizster/hello-parse-installation

  1. Build and run the app (fresh install on device). ParseObject will save just fine.
  2. Close the app and re-launch. Exception will be thrown and ParseObject will not be saved.
  3. Repeat step 2 as many times as you want.
  4. Uninstall the app and you can start over at step 1.

Expected Results

A new ParseObject (Class: World) should be saved to parse-server and have a pointer to the installation of the device that saved it. Here is an example from the MongoDb of a successful object saved.

{ 
    "_id" : "EImkTziqdr", 
    "message" : "Hello world!", 
    "_p_installation" : "_Installation$iiBDWyIHfc", 
    "_updated_at" : ISODate("2016-06-17T14:15:09.248+0000"), 
    "_created_at" : ISODate("2016-06-17T14:15:09.248+0000")
}

Actual Outcome

When calling SaveAsync on the new ParseObject the save will fail and result in the following exception:

Parse.ParseException: at least one ID field (deviceToken, installationId) must be specified in this operation

Environment Setup

Parse .NET SDK v1.7.0 parse-server v2.2.13 Xamarin.iOS 9.8.0.323 iOS v9.3.2 Visual Studio 2015

  • Server
    • parse-server version: 2.2.13
    • Operating System: Azure/Windows
    • Hardware: Azure cloud
    • Localhost or remote server? (AWS, Heroku, Azure, Digital Ocean, etc): Azure
  • Database
    • MongoDB version: mongod version: 3.0.9
    • Storage engine: ???
    • Hardware: mLab Cloud
    • Localhost or remote server? (AWS, mLab, ObjectRocket, Digital Ocean, etc): mLab

Logs/Trace

App is updating and saving CurrentInstallation upon launch. Works.

�[36mverbose�[39m: POST /parse/classes/_Installation { 'cache-control': 'no-cache',
  connection: 'keep-alive',
  'content-length': '319',
  'content-type': 'application/json',
  host: 'myparseserverhost.azurewebsites.net',
  'max-forwards': '10',
  'x-parse-application-id': 'myAppId',
  'x-parse-client-version': 'net-xamarin-ios1.7.0.0',
  'x-parse-installation-id': '47562ac6-cd5c-4fbc-aaac-afdfa0614beb',
  'x-parse-app-build-version': '1.0',
  'x-parse-app-display-version': '1.0',
  'x-parse-os-version': '9.3.2',
  'x-parse-windows-key': '',
  'x-liveupgrade': '1',
  'x-arr-log-id': '76e42330-2de1-4b30-b81d-b4fca14d4890',
  'disguised-host': 'myparseserverhost.azurewebsites.net',
  'x-site-deployment-id': 'mydeployid',
  'x-original-url': '/parse/classes/_Installation',
  'x-forwarded-for': '1.1.1.1:52456' } {
  "installationId": "47562ac6-cd5c-4fbc-aaac-afdfa0614beb",
  "lastStartedAt": {
    "iso": "2016-06-17T19:18:53.110Z",
    "__type": "Date"
  },
  "deviceType": "ios",
  "timeZone": "America/Chicago",
  "localeIdentifier": "en-US",
  "parseVersion": "1.7.0.0",
  "appVersion": "1.0",
  "appIdentifier": "com.example.hello-parse",
  "appName": "Hello Parse",
  "badge": 0
}

�[36mverbose�[39m: {
  "response": {
    "updatedAt": "2016-06-17T19:18:53.797Z"
  }
}

App attempts SaveAsync on the new ParseObject. Fails

�[36mverbose�[39m: POST /parse/batch { 'cache-control': 'no-cache',
  connection: 'keep-alive',
  'content-length': '80',
  'content-type': 'application/json',
  host: 'myparseserverhost.azurewebsites.net',
  'max-forwards': '10',
  'x-parse-application-id': 'myAppId',
  'x-parse-client-version': 'net-xamarin-ios1.7.0.0',
  'x-parse-installation-id': '47562ac6-cd5c-4fbc-aaac-afdfa0614beb',
  'x-parse-app-build-version': '1.0',
  'x-parse-app-display-version': '1.0',
  'x-parse-os-version': '9.3.2',
  'x-parse-windows-key': '',
  'x-liveupgrade': '1',
  'x-arr-log-id': '5b6fba36-d6bf-4228-9e9f-21787527a605',
  'disguised-host': 'myparseserverhost.azurewebsites.net',
  'x-site-deployment-id': 'mydeploymentid',
  'x-original-url': '/parse/batch',
  'x-forwarded-for': '1.1.1.1:52456' } {
  "requests": [
    {
      "method": "POST",
      "path": "/parse/classes/_Installation",
      "body": {}
    }
  ]
}

�[36mverbose�[39m: {
  "response": [
    {
      "error": {
        "code": 135,
        "error": "at least one ID field (deviceToken, installationId) must be specified in this operation"
      }
    }
  ]
}

Client stacktrace

[0:] Parse.ParseException: at least one ID field (deviceToken, installationId) must be specified in this operation
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/3339/39ebb778/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143 
  at Parse.Internal.InternalExtensions+<>c__DisplayClass13_0`1[TResult].<OnSuccess>b__0 (System.Threading.Tasks.Task t) [0x0003c] in <filename unknown>:0 
  at System.Threading.Tasks.ContinuationResultTaskFromTask`1[TResult].InnerInvoke () <0x1005de120 + 0x00077> in <filename unknown>:0 
  at System.Threading.Tasks.Task.Execute () [0x00016] in /Users/builder/data/lanes/3339/39ebb778/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/threading/Tasks/Task.cs:2502 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/3339/39ebb778/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143 
  at Parse.Internal.InternalExtensions+<>c__DisplayClass13_0`1[TResult].<OnSuccess>b__0 (System.Threading.Tasks.Task t) [0x0003c] in <filename unknown>:0 
  at System.Threading.Tasks.ContinuationResultTaskFromTask`1[TResult].InnerInvoke () <0x1005de120 + 0x00077> in <filename unknown>:0 
  at System.Threading.Tasks.Task.Execute () [0x00016] in /Users/builder/data/lanes/3339/39ebb778/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/threading/Tasks/Task.cs:2502 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/3339/39ebb778/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143 
  at Parse.Internal.InternalExtensions+<>c__DisplayClass13_0`1[TResult].<OnSuccess>b__0 (System.Threading.Tasks.Task t) [0x0003c] in <filename unknown>:0 
  at System.Threading.Tasks.ContinuationResultTaskFromTask`1[TResult].InnerInvoke () <0x1005de120 + 0x00077> in <filename unknown>:0 
  at System.Threading.Tasks.Task.Execute () [0x00016] in /Users/builder/data/lanes/3339/39ebb778/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/threading/Tasks/Task.cs:2502 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/3339/39ebb778/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143 
  at Parse.Internal.InternalExtensions+<>c__DisplayClass13_0`1[TResult].<OnSuccess>b__0 (System.Threading.Tasks.Task t) [0x0003c] in <filename unknown>:0 
  at System.Threading.Tasks.ContinuationResultTaskFromTask`1[TResult].InnerInvoke () <0x1005de120 + 0x00077> in <filename unknown>:0 
  at System.Threading.Tasks.Task.Execute () [0x00016] in /Users/builder/data/lanes/3339/39ebb778/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/threading/Tasks/Task.cs:2502 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/3339/39ebb778/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143 
  at Parse.Internal.InternalExtensions+<>c__DisplayClass13_0`1[TResult].<OnSuccess>b__0 (System.Threading.Tasks.Task t) [0x0003c] in <filename unknown>:0 
  at System.Threading.Tasks.ContinuationResultTaskFromTask`1[TResult].InnerInvoke () <0x1005de120 + 0x00077> in <filename unknown>:0 
  at System.Threading.Tasks.Task.Execute () [0x00016] in /Users/builder/data/lanes/3339/39ebb778/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/threading/Tasks/Task.cs:2502 

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 1
  • Comments: 16 (8 by maintainers)

Commits related to this issue

Most upvoted comments

There is an obvious fix for that issue, before opening the PR, I’d like to get a 2nd opinion with @drew-gross or @nlutsenko

The fix would involve:

  1. plumb the installation-Id from the auth (trivial) raise an error when there is a mismatch between data and headers
  2. ignore the deviceType as it’s not being set given the logs provided, and enforced.

fixing the x-parse-installation-id only set on auth (https://github.com/ParsePlatform/parse-server/blob/master/src/RestWrite.js#L574) is mentioned.

I tested against parse.com and the X-Parse-Installation-Id header is not used in that matter. and the body defined installationId will take precedence on the headers

@thewizster Did you ever end up figuring this one out?

I find it strange that it says that an installationId must be specified, yet in the logs you can see “x-parse-installation-id” is actually set, which I assume is the installationId in question.

I have attached my logs below if it will help to debug / replicate.

verbose: POST /parse/classes/_Installation { host: 'torque-dev.herokuapp.com', 
  connection: 'close', 
  'content-type': 'application/json', 
  'x-unity-version': '5.3.5p4', 
  accept: '*/*', 
  'x-parse-session-token': 'r:639326dbbb1fbee8bcf94d16a7e59067', 
  'x-parse-application-id': 'torque-burnout', 
  'x-parse-windows-key': '90b8148d-627c-4c25-8f2e-e3c02acd1f85', 
  'x-parse-installation-id': '13186714-5036-401f-b4a5-18c26a6ea0e7', 
  'x-parse-os-version': 'iPad4,1', 
  'accept-language': 'en-au', 
  'accept-encoding': 'gzip, deflate', 
  'x-parse-client-version': 'net-unity1.7.0.0', 
  'user-agent': 'torqueburnout/98 CFNetwork/758.4.3 Darwin/15.5.0', 
  'x-parse-app-build-version': '98', 
  'x-parse-app-display-version': 'leagueofmonkeys.torqueburnout', 
  'x-request-id': 'd6f5df96-b6b7-4009-be6a-131631b500ec', 
  'x-forwarded-for': '27.32.138.126', 
  'x-forwarded-proto': 'http', 
  'x-forwarded-port': '80', 
  via: '1.1 vegur', 
  'connect-time': '0', 
  'x-request-start': '1469065797649', 
  'total-route-time': '0', 
  'content-length': '94' } { 
  "user": { 
    "__type": "Pointer", 
    "className": "_User", 
    "objectId": "ifX5iXUx4D" 
  }, 
  "language": "English" 
} 
verbose: error: code=135, message=at least one ID field (deviceToken, installationId) must be specified in this operation