Valbrand
Valbrand

Reputation: 77

Realm Sync data resets on app reinstall

I have an iOS app which uses Realm locally and it works great, and my intention is to use Realm Object Server to enable:

I've been having a lot of trouble with the last one. The flow in my app is the following:

  1. First, it tries to find a User in my Realm Sync. If a User exists, go to step 4. Otherwise, go to step 2;
  2. Ask for the user's name, income and payday;
  3. Get the user's userRecordID for iCloud and logIn to Realm Object Server.
  4. Use the SyncUser's identity as the User entity identifier. Save the data I just asked (name, income and payday) to Realm;
  5. Go to main app screen and let the user enjoy the app.

ROS is using cloudkit based authentication. The problem occurs if I follow steps 1-4 above, and then reinstall the app. I expected the previously created User to be retrieved in step 1, but instead all of its fields beside the primary key are set to blank values (name becomes empty string, income and payday become 0). Is this behavior expected? Is what I want to do within the purpose of Realm?

EDIT

Made the flow clearer after @AustinZ's answer.

Upvotes: 0

Views: 295

Answers (1)

AustinZ
AustinZ

Reputation: 1787

"Data restoration on app install" is definitely a valid use case for Realm Sync. However, the flow you describe is problematic.

A synchronized Realm is identified by two pieces of information: a sync user and the Realm's path on the Realm Object Server (e.g. /~/my/realm). If you have the same sync user logged into multiple devices, and they each open a copy of a Realm at the same path, they are opening the same synced Realm and will stay in sync with each other.

However, to get the same sync user, a user needs to log in to the Realm Object Server from their device. You do this by creating a CloudKit SyncCredentials value using SyncCredentials.cloudKit(token:) and passing that credential to SyncUser.logIn(). The device will then communicate with the Realm Object Server, and if the log in succeeds, then the logIn() method's callback block will be invoked and will give you a SyncUser. That is the sync user you need to use to open Realms.

So:

  • You shouldn't be saving users or user info to Realms manually. We persist the relevant information automatically.
  • If a user deletes and re-installs their app, the app's documents and files are deleted as well, which means you shouldn't assume you can access a Realm's data after the app which created it was re-installed.
  • What you should be doing is, in step 3, using the user's CloudKit credentials and logging into the Realm Object Server as described above.

Please review our documentation for more information.

Upvotes: 2

Related Questions