Trying to migrate from Local Realm to MongoDB Realm Sync

I have been using Realm for many years in an app. I just upgraded to the latest version of Realm (10.8.1) and am struggling to convert my local realm to a synced realm.

I use/create realms throughout the app using let realm = try! Realm() after setting Realm.Configuration.defaultConfiguration = config in App Delegate. The config object contains migration blocks that I have added.

From what I understand my objects now need a _id field, but I also need to create an App object, log in and then use the app users configuration to create a new realm. If I do that, I lose all the old data. First, how can I copy the old local realm data to the new synced realm? Second, can I set the defaultConfiguration to the new synced realm configuration, so I can continue using the same old try! Realm() everywhere, or is there a better practice?

Hi, @realm_guy – welcome to the community forum!

From your description, I’m assuming that you’re not using the legacy Realm sync solution (if you are, then this guide can help Realm Legacy Migration Guide - Realm Legacy Migration Guide).

You are correct that to use MongoDB Realm Sync, you need to include an _id attribute in your Objects.

I’m not aware of an automated way of moving Objects from one realm to another and so I think you’ll have to write your own deep copy/transform function in your app.

You should be able to set your default realm to your synced realm.

Hi @Andrew_Morgan. I am not using the Legacy Sync. I’ve been using Realm for a while and have been holding out for MongoDB Realm Sync, but have a few implementation questions.

I have a Log Object that has a uuid field that is a String and is the primary key. Should I rename the uuid field to _id or should I create another field for _id? Or do I create a new object type?

Next, how exactly do I go about copying all the old records to the new realm in a seamless end-user experience? Do I just open both realms at the same time and copy each object individually?

Then how do I go about making the default realm the synced realm, so I can just use let realm = Realm() throughout my iOS app

For your Log Object, renaming your uuid field to _id should work. _id can be a string or ObjectId.

I think your description of how to copy the objects makes sense.

TBH, I don’t tend to set the default Realm config. Instead, I open a synced realm and then the app uses a reference to that realm for transactions. This tutorial includes an example with asyncOpen:

Thanks @Andrew_Morgan. I’m going to give the copying a shot at some point and may have some more questions!

I built this app a while ago and I’m instantiating Realms all over the place. In fact, many of my view controllers have their own Realm instances. Is it a better practice to have a data store manager/singleton and use one instance throughout the app?

@Andrew_Morgan any advice would be helpful!

This is really a preferences question but in general I would say yes, it makes it a bit easier if you have your opening and closing of Realms in a single place like a singleton for when you want to do ancillary administrative tasks like compaction or ClientReset.

@Ian_Ward @Andrew_Morgan I am planning to migrate my users to realm sync and am going to use email auth (or custom JWT). However, not all users will have an account, so they will not be authorized. Is there a way to open a synced realm, but not authenticate? In other words, I want to be able to use the same code, etc. for authed and un-authed users, but only have data sync for authed users and unauthed users would still be able to use everything locally.

I think using a singleton and initializing with a local realm if there is no auth user and then if there is an auth user initialize with a synced realm.

Then if a local realm user logs in, copy the objects to the synced realm.

The only caveat is if a user logs out, then they will have no objects.

No a user must be authenticated in order to open a synced realm. You can use either anonymous authentication or use a dummy username/password where you login the user in the background in code if you want to open a sync realm without requiring the user to create an account or anything.

You could have two different methods exposed from your Realm Provider. If the user is not logged in then you can return a non-sync Realm, if there is a CurrentUser() != null then you can return a synced realm.