Realm-js: Offline Access Using Sync.

Created on 10 Feb 2017  Â·  11Comments  Â·  Source: realm/realm-js

Hey Guys,

I'm getting deep into integrating Realm Sync with my React Native app, ntwrk, which is currently running perfectly with a local-only Realm database.

I have the Realm Object Server running on a small Digital Ocean box with Ubuntu. I'm connecting to that Realm Object Server with both the simple Realm Browser and an XCode simulator running ntwrk. Everything works perfectly, with synching happening between the server, the simulator and the Realm Browser.

However, what I'm not understanding is how the offline-first is supposed to work. If I turn off the network connection to the simulator and refresh my app, it cannot connect to the Realm server and instead of using some locally cached Realm file until network access is restored, it gives an error TypeError: Network request failed.

Reading through the docs it doesn't seem clear how to handle this appropriately.

Before I start rolling my own solution can you explain how to do this in the best way or point me to the docs that spell it out.

Many Thanks!

Joshua

T-Feature faq

Most helpful comment

Just for others that might stumble upon this, here is the working code to use your offline local Realm User once they've authenticated for the first time online:

let user = Realm.Sync.User.current
if (user) {
  let synchedRealm = new Realm({
    sync: {
      user: user,
      url: 'realm://1.2.3.4:9080/~/my-realm',
    },
    schema: [Model1Schema, Model2Schema]
  });
  return synchedRealm;
}

// otherwise continue with login flow:

Realm.Sync.User.login('http://1.2.3.4:9080', '[email protected]', 'password', (error, user) => {
//...

Bit of a discussion over at https://github.com/realm/realm-mobile-platform/issues/14#issuecomment-288487722 as well.

All 11 comments

Hey @joshuapinter. Thanks for reaching out. Someone will follow-up soon with some more information on your question. Cheers!

I'll add a second question here that isn't related but also of value. :)

I'm finding that when I'm instantiating Realm, it does a lookup to the server each time before returning the Promise. So everything I call Realm, it does this lookup.

Is it advisable to store your "Synched Realm" in a global variable scope or something, like global.realm = realm?

Doing some testing I find it's much quicker because it avoids these network lookups while still maintaining the connection with the Realm Object Server.

Thanks.

Hi Joshua, you have indeed run across something that we are still working on. Once you have a Realm and an established connection, going offline works just fine. But initially, you do need the network. Obviously this is something that we are fixing, stay tuned.
Storing a realm globally is not an antipattern. In other languages it would be more so, because threading issues can occur but obviously that's not a problem in JS.

Awesome, thanks for the reply @kristiandupont. I figured you guys were still working on creating a local cache or something for offline usage.

Do you have a _(rough)_ timeline for this?

That being said, I think it's manageable for beta testing sync at this point.

Sorry, no timeline for it at this point. It's somewhat high priority though, but also something that interferes quite significantly with the whole connect/sign-in/sign-up process, so it needs to be thought out.

@kristiandupont Understood. Meanwhile, is there a way to get the location of the local Realm file that is being used when Sync is setup. I know without sync I could do something like Realm.defaultPath to get the default path of the Realm file.

This might be an easy way of using the local version until a network connection is available.

Let me know. Thanks!

Hey @kristiandupont, can I get an update on this. It's currently a blocker with going to production as a user that starts the app while on a train and in a tunnel can't see any of the data.

Am I missing something that would allow me to access to the local database whilst offline and Realm is periodically checking for an internet connection?

This seems like a big gap in the capabilities, so I'm likely not "getting" something. :)

Thanks.

Once you've logged a user in it's actually persisted internally by Realm across application runs until you manually log it out. You can find a map with all the logged-in users in Realm.Sync.User.all and you can use that to open a synced realm even when offline.

Oh,I didn't know that. Can you show me a little code on what that would like so I can give it a shot this evening.

Thanks.

On Mar 17, 2017, 11:13 AM -0600, Yavor Georgiev notifications@github.com, wrote:
>

Once you've logged a user in it's actually persisted internally by Realm across application runs until you manually log it out. You can find a map with all the logged-in users in Realm.Sync.User.all and you can use that to open a synced realm even when offline.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub (https://github.com/realm/realm-js/issues/857#issuecomment-287415657), or mute the thread (https://github.com/notifications/unsubscribe-auth/AALCU5Hjd5gtFqqC72ZfZC1E40qG32Prks5rmr9EgaJpZM4L9hYW).

Just for others that might stumble upon this, here is the working code to use your offline local Realm User once they've authenticated for the first time online:

let user = Realm.Sync.User.current
if (user) {
  let synchedRealm = new Realm({
    sync: {
      user: user,
      url: 'realm://1.2.3.4:9080/~/my-realm',
    },
    schema: [Model1Schema, Model2Schema]
  });
  return synchedRealm;
}

// otherwise continue with login flow:

Realm.Sync.User.login('http://1.2.3.4:9080', '[email protected]', 'password', (error, user) => {
//...

Bit of a discussion over at https://github.com/realm/realm-mobile-platform/issues/14#issuecomment-288487722 as well.

I don't think this is working as expected, when running via the react native debugger, this all seems ok, however when not using the debugger, it seems to have problems. This all boils back down to that Realm.Sync.User.current being == {} which seems to be an issue only true when the debugger isn't attached. The thing that is even more strange, is if you pass that empty {} object to the Realm.open function, as suggested above, Realm.open({ sync: { user: user, url: 'realm://10.8.209.111:9080/~/my-realm', }, schema: [SyncTest] }).then(realm => { ... then it just hangs when the server isnt running, never calls the catch.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ugendrang picture ugendrang  Â·  3Comments

MihaelIsaev picture MihaelIsaev  Â·  3Comments

texas697 picture texas697  Â·  3Comments

camslaz picture camslaz  Â·  4Comments

matt2legit picture matt2legit  Â·  3Comments