Pausing a synced Realm

In migrating to MongoDB Realm from Realm Cloud, I’m attempting to limit syncing for non-paying users if their subscription expires, but they should be able to continue to use their data locally with the same Realm.

I saw in the docs at https://docs.mongodb.com/realm/sdk/react-native/examples/sync-changes-between-devices/#pause-or-resume-a-sync-session that there is the ability to pause syncing, but when I do this, it appears to no longer utilize the Realm that is on the device either. Everything goes dead. It’s as if the database no longer exists.

Is there a way to continue CRUD locally without it syncing changes to the server?

–Kurt

Hi @Kurt_Libby1 – I can’t comment on the React-Native. SDK but I did this test on iOS (realm-cocoa):

  • I had some synced data in the app.
  • Paused sync through the Realm UI
  • Added new Objects in the iOS app
  • Restarted the iOS app and confirmed that all of the data was still there
  • Resumed sync from the Realm UI and confirmed that all of the changes made during the sync-pause were synced (and written to Atlas after a short delay for the translator to become active again)

Thanks Andrew.

When you say that you

• Paused the sync through the Realm UI

did you pause sync right after opening the Realm?

For instance, I am attempting to follow the documentation linked in the original post by doing:

let realm;
const config = {
  schema: getSchema(),
  sync: {
    user: app.currentUser,
    partitionValue: `user=${app.currentUser.id}`,
  },
};
try{
  realm = await Realm.open(config);
  const syncSession = realm.syncSession;
  syncSession.pause(); // this is what would be toggled based on subscription status
} catch (error) {
  console.log(error)
}
return realm;

Are you pausing it similarly, right when you open the Realm?

–Kurt

I paused it after the Realm had been opened. I then restarted the app (opening the realm again).

I just retried where I installed the app after sync was paused, and the data still survives an app restart

UPDATE: nevermind. I didn’t realize that when you said the Realm UI that you were talking about the server and not something on the client. I am attempting to pause sync from the client side for an individual device.

–Kurt

Old post:

Ok, well then at least I know it should work.

Now to figure out what’s happening with my code.

Thanks for your help.

Hey @Kurt_Libby1 - I think we might be talking about a couple of different but related concepts here. I believe @Andrew_Morgan has fully paused sync for all users via the Realm App UI, while you’re talking about pausing sync for individual users based on your business logic - in your case, whether or not they have a subscription.

If that’s accurate, I think there’s a different approach you could take. You could use some small function-based checks or something in custom user data to determine whether a user is a subscriber. If the user is not a subscriber, you could open a local realm, rather than opening a synced realm and pausing it immediately. This would enable you to continue doing CRUD locally and not have to worry about pausing and resuming sync (or pausing it indefinitely every time you open a realm).

If you go with this approach, you’d need to write some custom code to handle a case where a user subscribes; where you want to preserve their data from the local realm, and then switch to using a synced realm. Basically, you’d need to copy the data from the local realm and put it into a synced realm when that conversion happens. I don’t have any recommendations for the best way to do that, unfortunately, but I can talk to the team and see if they have any tips.

Hope this gets you moving in the right direction!

2 Likes

Thanks Dachary,

I think you’re right. These are definitely different.

I have the copying from local to synced and back again as a mechanism in my old Realm Cloud code, but I was hoping to not have to do that with MongoDB Realm.

Personal rant: This whole migration thing is hundreds of hours and it doesn’t seem any better than before. It’s a giant headache for nothing. rant over

So then what is the .pause() for? Is there no way for a synced realm to continue to work locally without a connection where I can just turn off the connection? I thought that was one of the main value props of Realm is that it works offline first. Then if they renew their subscription, the syncing is .resume() and everything becomes eventually consistent.

If that’s not the case, I am seriously confused as to why offline/eventually-consistent is even talked about with Realm.

Thanks for any light you can shine on this.

–Kurt

Oof, my sympathies re: the rant! That’s a lot of hours. If there’s something we can do from a documentation or example standpoint to help with that, let me know! I mostly keep an eye on the forums to see where there are places we can improve our documentation, but I’m also happy to take feedback back to the product team. I’m sorry it feels like you haven’t gotten any benefit from migrating. We do have new stuff in the pipeline and are always adding things, so hopefully something in the future will make it all feel worthwhile to you.

Regarding synced realms working locally without a connection - yes, absolutely, sync is designed to handle network connectivity losses gracefully. We offer the .pause() (or .suspend() in some of the other SDKs) method as a convenience method to manage communication between the client and server for a specific realm. It’s intended for temporarily pausing sync within a sync session. But this is for realm files that you want to have syncing to the server regularly; these are realms that need access to the most recent data from the server.

What you’re describing for your app is business logic that dictates whether a user should have a local or a synced realm. In your case, the non-subscribing user’s realm shouldn’t try to communicate with the server at all; they should be using a local-only realm. It never tries to call out to the server; it only does the CRUD locally.

I’m looking at the documentation right now to see where we describe these differences, and it looks like we could definitely improve that. Sorry for any confusion about these concepts! I’ll put in a ticket to work on that.

Regarding copying from the local realm to a synced realm, I spoke with the product team, and there’s not currently an out-of-the-box feature/API for that. But that would definitely make this flow easier to understand and implement. We’ve got a feedback engine, and I’d encourage you to suggest this feature (or anything else you’d like to see!) so our product team knows to prioritize it based on developer requests: https://feedback.mongodb.com/forums/923521-realm/

Oof is right. This extremely disappointing.

I do have about 1500 lines of code that I’ve written that copies a realm to another realm and then reconstructs the relationships, and from what I’ve experienced, it is less than ideal. I was really hopeful that this was not going to be the case going forward.

As @Ian_Ward says, a line of code you don’t have to write is a great line of code.

Instead, I’m going to be adding about 6000 lines of code into four apps to help Realm exist in my app in a usable way.

I don’t drink anymore, but if I did, today would be a good day to pair sadness with scotch.

Please update that .pause() documentation to indicate it’s actual use case and warnings against using it outside of those bounds.

–Kurt

Sorry to be the bearer of bad news, @Kurt_Libby1 ! I’ve made tickets for our documentation team to update language around .pause(), and also more clearly articulate use cases for local vs. synced realms, so hopefully the documentation will better reflect this soon.

I also spoke with @Ian_Ward about this earlier today, and as you mention, he’s a big advocate for making Realm awesome and easy for developers to use. I’m sure he’s seen this thread and will keep your experiences in mind as the product team looks at ways to improve opening realms and copying data between realms.

Meanwhile, if there are other things you spot where the documentation could be better or you’d like to see code examples of how to do something with Realm, feel free to file feedback directly, or keep on posting here. I know a bunch of us keep an eye on the forums for cases like this.

Thanks Dachary.

This just seems like a major oversight.

If the Realm works offline when it is already on the device and the user is cached, the need to copy that entire realm (including all of the possibilities of data loss that comes along with that) seems redundant and ridiculous.

There should be a way to continue using the realm. I understand the need for local realms that are never synced to transition to becoming synced realms. But forcing a synced realm to back into a local realm is a giant lift and feels like I’m still using Realm in its infancy. May as well have just stayed on self hosted.

I migrated to cloud and now to mongodb, and I’m stuck with the same issues (and some new shiny ones as well).

I understand that it is in MongoDB’s interest to never fix this because utilizing synced realms is how you make your money, so I’m not holding my breath on any innovation or effort in this area. In the meantime, I’ll resurrect 4year old code and make it work with this new mess.

Have a great Tuesday! I know I won’t! :man_facepalming:t2:

–Kurt