Search code examples
swiftrealm

Realm object server: failed asserting left.optional == right.optional (sync data between Android & iOS)


I am trying to synchronise data between my iOS Application and Android application. The Android application can read from the Realm just fine, but my Swift program is struggling, and the error message is not very informative.

I am receiving this error message:

2016-11-08 08:53:43.919 iOSRealm[2629:65667] Sync: Connection[1]: Session[1]: Bad changeset received: Assertion failed: left().nullable == right().nullable

I have no idea what it means or how to fix it. This is how I authenticate myself with the Realm Object server:

private func synchronouslyLogInUser() throws {
    SyncUser.authenticateWithCredential(Credential.usernamePassword(username, password: password, actions:.UseExistingAccount), authServerURL: authURL) { (user, error) in
        print("sent login request")
        if let user = user {
            print("user was not nil")
            self.setDefaultRealmConfiguration(user)
        }
        if let error = error where error.code == SyncError.HTTPStatusCodeError.rawValue && (error.userInfo["statusCode"] as? Int) == 400 {
            print("invalid user and pass")
        } else {
            print(error)
        }
    }
}

private func setDefaultRealmConfiguration(user: SyncUser) {
    Realm.Configuration.defaultConfiguration = Realm.Configuration(syncConfiguration: (user, realmURL), objectTypes: [Weather.self, Wind.self])
    Realm.Configuration.defaultConfiguration.deleteRealmIfMigrationNeeded = true
    realm = try! Realm()
}

I see output being printed to the console so I know the login attempt was successful. I don't think it's a problem with a mismatching database, because I set the deleteRealmIfMigrationNeeded flag to true.

What does this error message mean and how do I fix it?

The appropriate Object Realm Server logs can be found here: http://pastebin.com/raw/J9mU4H0u - my apologies for the off-site link, but it's a long log file.

My Swift models are as follows:

class Weather : Object {
    dynamic var id = 0
    dynamic var date = ""
    dynamic var forecast = ""
    dynamic var humidity = ""
    dynamic var wind: Wind!

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

class Wind: Object {
    dynamic var direction = ""
    dynamic var speed = ""
}

Android Models:

public class Weather extends RealmObject {
    @PrimaryKey
    public int id;
    public String date;
    public String forecast;
    public String humidity;
    public Wind wind;
}

public class Wind extends RealmObject {
    public String direction;
    public String speed;
}

Thanks in advance!


Solution

  • Figured out what was going on. Apparantly, Java String is nullable (or Optional if you'd like) by definition. In Swift, I was telling my model to map to non-Optional strings. That is why the error message said it failed asserting that left.optional == right.optional.

    So, what I had to do to fix it was make every String in my swift model optional).

    See here:

    class Weather : Object {
        dynamic var id = 0
        dynamic var date: String?
        dynamic var forecast: String?
        dynamic var humidity: String?
        dynamic var wind: Wind?
    
        override class func primaryKey() -> String? {
            return "id"
        }
    }
    
    class Wind: Object {
        dynamic var direction: String?
        dynamic var speed: String?
    }