'Random Realm 'already opened with a different schema mode' errors

In a Swift app I am setting the default Realm config in didFinishLaunchingWithOptions like this:

Realm.Configuration.defaultConfiguration = {
    var config = Realm.Configuration.defaultConfiguration
    config.deleteRealmIfMigrationNeeded = true
    return config
}()

and then I am creating new Realm instances where needed, in 3 different ways - when reading:

let realm = try! Realm()
let users = realm.objects(User.self)

and when writing:

let realm = try! Realm()
if let user = realm.object(ofType: User.self, forPrimaryKey: userId) {
    try! realm.write {
        user.name = name
    }
}

and in models:

import Foundation
import RealmSwift
import ObjectMapper

final class User: Object, StaticMappable {

    @objc dynamic var id = 0
    @objc dynamic var name = ""

    override static func primaryKey() -> String? {
        return "id"
    }

    func mapping(map: Map) {
        id <- map["id"]
        name <- map["name"]
    }

    static func objectForMapping(map: Map) -> BaseMappable? {
        let objectOptional = try? Realm().object(ofType: self, forMapping: map)
        if let object = objectOptional {
            return object
        }
        return nil
    }
}

The problem is that sometimes I am getting this error when creating new Realm instances in completion closures, which are heavily used:

Fatal error: 'try!' expression unexpectedly raised an error: Error Domain=io.realm Code=1 "Realm at path '/var/mobile/Containers/Data/Application/...../Documents/default.realm' already opened with a different schema mode." UserInfo={NSLocalizedDescription=Realm at path '/var/mobile/Containers/Data/Application/...../Documents/default.realm' already opened with a different schema mode., Error Code=1

How can I debug and resolve this?



Solution 1:[1]

I had to make sure that I'm setting Realm.Configuration.defaultConfiguration before I do anything else with Realm. In my case I was first doing: let realm = try! Realm(), and performing some data import tasks, in the appDelegate, before ever setting the default configuration. Then it was failing when being opened from the background thread using the same mechanism. Making sure the default configuration is set before ever calling let realm = try! Realm() does the trick: Now can open on any thread.

Solution 2:[2]

The issue was resolved by adding a

    Realm.Configuration.defaultConfiguration = {
            var config = Realm.Configuration.defaultConfiguration
            ...
            // Set the new schema version. This must be greater than the previously used
            // version (if you've never set a schema version before, the version is 0).
            config.schemaVersion = 0
    }

to the Realm config on app init.

Solution 3:[3]

I was having the same error, in my case, it's because i was using:

<RealmProvider>
   <App />
</RealmProvider>

And exporting a RealmContext in another file like this:

import { createRealmContext } from "@realm/react";

export default createRealmContext({
    schema: [User.schema, Foo.schema, LoremIpsum.schema],
    deleteRealmIfMigrationNeeded: true,
})

I solved removing all above and use only this:

import Realm from "realm";

const refreshUserTable = (values) => {
    try {    
        Realm.open({ schema: [User.schema], deleteRealmIfMigrationNeeded: true })
            .then(realm => {
                realm.write(() => {
                    realm.delete(realm.objects('User'));
                    realm.create('User', values);
                })

                realm.close(); // remember to close
            })

    } catch (error) {
        console.log(error);
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 FranticRock
Solution 2 Blackbeard
Solution 3 Guilherme Zanetti