Realm-cocoa: Error - Synchronized Realms cannot be opened in immutable mode

Created on 8 Jan 2018  路  13Comments  路  Source: realm/realm-cocoa

Goals

To be able to open a read-only synchronized realm.

Actual Results

An error stating:

Domain=io.realm Code=1 "Synchronized Realms cannot be opened in immutable mode" UserInfo={NSLocalizedDescription=Synchronized Realms cannot be opened in immutable mode

Steps to Reproduce

Open a read-only synchronized realm not created by you.

Code Sample

SyncUser.current!.retrievePermissions { (permissions, error) in
            if let error = error {
                print(error)
            } else if let permissions = permissions {
                    // loops through each permission object, opens the corresponding user's realm, and finds and appends appropriate object
                    for p in permissions {
                        let url = URL(string: "realm://<server>" + p.path)!
                        let id = p.path.components(separatedBy: "/")[1]
                        let config = Realm.Configuration(
                            syncConfiguration: SyncConfiguration(user: SyncUser.current!, realmURL: url),
                            readOnly: true)

                        Realm.asyncOpen(configuration: config, callbackQueue: DispatchQueue.main, callback: { (realm, error) in
                            // finds object and appends it to the array
                            if let otherUser = realm?.object(ofType: User.self, forPrimaryKey: id) {
                                otherUsers.append(otherUser)
                            }
                        })

                    }
                }
            }

Version of Realm and Tooling

Realm framework version: 3.0.2

Realm Object Server version: 2.4.2

Xcode version: 9.2.0

iOS/OSX version: Running the app on iOS 11.2.1. Xcode running on MacOS High Sierra 10.13.2

Dependency manager + version: Carthage 0.27.0

All 13 comments

Are you sure the error is coming from that code? The error message indicates that you're setting both syncConfiguration and readOnly: true on a config object, which is not done there.

@tgoyne My fault, it was there when the error occurred. I pasted the code from in the midst of debugging and didn't check through it well enough before posting =P. Just updated

@michael-mckenna
I have the same issue.
So i have got 1 realm, which was created by realm administrator, it is read-only for all users except admin. I'm trying to connect it via Realm.asyncOpen but I'm getting the same error.
BUT. If I connect to this realm in sync mode Realm(configuration:), all is fine, except I can't get updates for this realm and I need to reconnect to it to see new objects which were added by admin.

I'm having the same issue. Also, if you register for didChange/requireRefresh notifications, they're not fired if you load the realm synchronously.

You'll also see a connection failure if you try to register for upload notifications when loading a realm synchronously.

I think this problem stems from a misunderstanding of what Realm.Configuration's readOnly property means. To quote the documentation (emphasis mine):

Whether to open the Realm in read-only mode.

This is required to be able to open Realm files which are not writeable or are in a directory which is not writeable. This should only be used on files which will not be modified by anyone while they are open, and not just to get a read-only view of a file which may be written to by another thread or process. Opening in read-only mode requires disabling Realm鈥檚 reader/writer coordination, so committing a write transaction from another process will result in crashes.

It doesn't make sense to open a synced Realm using this read-only mode as such a Realm could never see any data from the server.

If what you're after is opening a synced Realm that the sync user doesn't have permission to write to, then you should simply open the Realm using Realm.asyncOpen and then don't ever write to the Realm.

@bdash
Ok, so how can I get notifications from a realm which I don't have write permissions?

Realm.asyncOpen = crash
Realm(configuration:) = no notifications to objects\collections observers.

@morteg how does it crash? Can you post the code you use to build the configuration and open the realm with asyncOpen?

@nirinchev

 var verificationRealmConfiguration = Realm.Configuration(
            syncConfiguration: SyncConfiguration(user: user, realmURL: URL(string: "\(baseRealmPath)/protected/userVerification")!), encryptionKey: getKey()
        )

        verificationRealmConfiguration.objectTypes = [VerificationResult.self]

            Realm.asyncOpen(configuration: verificationRealmConfiguration, callbackQueue: DispatchQueue.main) {
                [weak self] realm, error in
                if let error = error {
                    completion(false, error)
                    return
                }
                self?.verificationRealm = realm
                completion(true, nil)
            }
            completion(true, nil)

Sorry, I haven't got a crash, but I have got an error.
1) With

 var verificationRealmConfiguration = Realm.Configuration(
            syncConfiguration: SyncConfiguration(user: user, realmURL: URL(string: "\(baseRealmPath)/protected/userVerification")!), encryptionKey: getKey(), readOnly: true
        )

I get "Operation canceled" error.

2) Without readOnly flag I've got :
"Synchronized Realms cannot be opened in immutable mode"

I think I don't need exactly asyncOpen, I need to receive updates from my "user-verification" realm, but in sync mode, i don't receive any updates from that realm until I make reconnect.

The _only_ way you can see an error that says "Synchronized Realms cannot be opened in immutable mode" is when specifying readOnly: true on the Realm.Configuration. As I described above, the error message indicates that readOnly is not compatible with sync. If it happens to not throw an error when using Realm(configuration:), that's a bug that we'd like to fix. From looking at the code I don't immediately see how it could be possible as both Realm(configuration:) and Realm.asyncOpen use the configuration in the same way.

Operation canceled means that the sync session was torn down before the callback was invoked. It's not clear how that could happen from the code snippet you've shared. I'd suggest enabling debug logging (add SyncManager.shared.logLevel = .debug before you use _any_ sync related functionality in Realm).

Ok, so how can I get notifications from a realm which I don't have write permissions?

I'm not clear on what code you're using when notifications are not working. If you're trying to use readOnly: true and are seeing notifications not work, then that's expected per the documentation I quoted above. If you're _not_ using readOnly: true and you're having issues with notifications, I'm not clear why you're sharing that fact on this issue. I'd suggest filing a new issue specifically about the problem you're experiencing.

Sorry I'm late to the party. I can confirm this was fixed by removing readOnly: true on the Realm.Configuration.

Thanks for confirming, @michael-mckenna.

The original problem reported in this issue has been addressed so I'll close this issue, and I'll ask that anyone else that is experiencing any problems please file a new issue about it.

I can also confirm that for a user who only has read access to a synced realm, when opening the realm asynchronously without readonly set, the user is able to see changes made to the realm by a user who does have write privileges.

Was this page helpful?
0 / 5 - 0 ratings