Realm-cocoa: Cannot open Read Only Synced Realms without internet connection

Created on 31 Jul 2017  路  14Comments  路  Source: realm/realm-cocoa

Goals

Trying to use a read-only synced realm to propagate data to clients. This will require reliable opening of the realm, with (after sync) or without internet connection (using cached local copy) at the time of application startup.

Expected Results

An API to reliably open a read only synced realm during application launch.

Actual Results

When online, Realm syncs and then opens with Async API (correct). Note: Read only synced realms can only be opened with AsyncOpen because conventional open will write data to the realm, according to other threads.

When offline, AsyncOpen will not return (to completion block) as it cannot connect to the server. Which is right, but leaves us with no way to open the realm.

RLMSyncManager error handler reports error with RLMSyncSession.

Steps to Reproduce

Async open a read only synced realm. Try again when disabling Internet connection.

Code Sample

NSURL *syncServerURL = [NSURL URLWithString: @"XXXXXXX"];

RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];

config.syncConfiguration = [[RLMSyncConfiguration alloc] initWithUser:loggedInUser realmURL:syncServerURL];


// Open the remote Realm
[RLMRealm asyncOpenWithConfiguration:config
                       callbackQueue:dispatch_get_main_queue()
                            callback:^(RLMRealm *realm, NSError *error)
 {
     if  (error)
     {
         NSLog(@"Error opening racing realm: %@", error);

     }
     else
     {
         if (realm)
         {
             NSLog(@"Opened Racing Realm");

         }
         else
         {
             NSLog(@"Error opening racing realm: Unspecified error");

         }
     }
 }];

Version of Realm and Tooling

Realm framework version: 2.8.3

Realm Object Server version:

Xcode version: 8.3

iOS/OSX version: 10

Dependency manager + version: CocoaPod

O-Community T-Doc T-Enhancement

Most helpful comment

This is huge problem. It makes it impossible to update data on client devices without giving them write access.

All 14 comments

Thanks for bringing this rather unfortunate limitation to our attention. This appears to be an oversight in our API design, and I believe it is something we can quickly fix and build out for our next release.

@gogoalsoft Out of curiosity. Why do you require the Realm to open? Any UI that depends on asyncOpen would need to deal with default values anyway since you don't know when the Realm is opened. So the distinction between async open never returning and returning an empty Realm shouldn't matter?

@cmelchior I have this read-only data on the server (that is updated by some admin user, for example). Data is on devices as pre-supplied copy of the database, and then updated from server if available.

The problem we have here, is that as it's a read-only database, as per the docs, it has to be opened with the async API. And the async API will not return unless it has connected to the server. So this basically means without a connection, I do not get any data, even when it's already available on the device.

Imagine it's a dictionary DB, and if you start the app in a place without connection, you cannot access any words because you cannot open it.

@austinzheng I see the other comments at #5225 and realm-object-store/#511.

So is this functionality available in a newer version now? Thanks

It's been two months, and ROS 2.0 is out. Is there any definitive word that this is addressed? @austinzheng @cmelchior

This is huge problem. It makes it impossible to update data on client devices without giving them write access.

@cmelchior @austinzheng I just ran into this problem (my app would hang if it was offline) as Realm.asyncOpen never calls its completion handler and SyncManager.shared.errorHandler reportsError Domain=io.realm.sync Code=8 "(null)" UserInfo={underlying_error=Error Domain=io.realm.sync.auth Code=1 "(null)"}

This seems to render read-only realms broken for most use cases, with the documentation misleading and incomplete. Is there any advice on how to open a sync read only realm when offline?

@nsnick @gogoalsoft how have handled this?

The purpose of asyncOpen() is to download the latest version of the Realm from the server before opening the Realm. Due to a limitation of how read-only permissions are implemented on the server side this is required the first time you open the Realm, but not after that. If you have a local copy of the Realm which you want without waiting for it to download the latest state, you can simply open it normally.

@tgoyne so the recommended solution is to write a local copy of the synced Realm?

@bmunkholm is this worked on right now? Would be really great to get done guidelines on how to make this work. Especially now when query based sync is deprecated.

No, you don't have to make your own copy of the Realm. If Realm.fileExists(for: config) returns true you can simply open the Realm synchronously rather than calling Realm.asyncOpen().

@tgoyne awesome! Thanks, that helps a lot

@tgoyne I tried your recommendation and it does work and I am able to use the realm in offline mode as long as it has been downloaded once.

However, I am a bit uneasy about it since the documentation explicitly says this:

"If a Realm has read-only Realm level permissions, then you must asynchronously open the Realm as described in Asynchronously Opening A Realm. Opening a file-level read-only Realm without the asynchronous API will cause an error."
https://docs.realm.io/sync/using-synced-realms/setting-up-your-realms

If it is fine to open the realm synchronously if it exists, then I think the documentation needs to be changed to reflect this? Is it safe to use in production?

In addition, the Realm.fileExists(for:) doesn't seem to exist on java/android. In either way, the documentation is really lacking here. Now when full sync is the recommendation, I really think this topic should be improved in the docs.

Thanks for the feedback @sipersso. We are doing an overhaul of the docs and will improve this.
@cbush Is this sufficient, or do you need more details from @tgoyne ?

That's good, I will see what I can do. Thanks!

Was this page helpful?
0 / 5 - 0 ratings