Realm-cocoa: Default Sync Realm API

Created on 6 Mar 2018  ·  8Comments  ·  Source: realm/realm-cocoa

As part of the upcoming release of partial sync, Realm Platform Self-Hosted and Cloud will offer the concept of a default synced Realm. This is designed to simplify how developers start working with synced data. Specifically it will fix or improve the following:

  1. Simplify how developers think about their data model. Previously developers needed to split their data into multiple Realms to control data access. Now with partial sync and the new permission system this is not necessary.
  2. Mirror the ease of use of Realm Database which offers a similar default Realm convenience API
  3. Limit the code needed to open a synced Realm - now the user simply needs to login with just the auth URL instead of needing to worry about Realm URLs and paths
  4. The default synced Realm will include the master User list of the application allowing developers to incorporate relationships to users simplifying how to think about user metadata.

API Proposal:

/*
  Open the default synced Realm
  - Has a dedicated API so that we can have a default configuration using:
    - SyncUser.current
    - Default Realm URL based off SyncUser auth URL (supplied within the refresh token)
    - Hardcoded path
    - Setup the Realm with a sync history type

  - If opened before there is a SyncUser.current one of two things can happen depending on the implementation:
    - The simple implementation is to throw if there is no SyncUser.current
    - The advanced implementation is to open the Realm without a sync session allowing offline access
*/

// Java
Realm realm = Realm.getDefaultSyncInstance();

// Swift
let realm = try! Realm.defaultSync()

// Objective-C
RLMRealm *realm = [RLMRealm defaultSyncRealm];

// JS
// Currently lacks a default Realm, so we should add
var realm = new Realm.defaultSync()

// .Net
var realm = Realm.GetDefeaultSyncInstance();

/*
  Login Example
*/

let credentials = SyncCredentials.nickname(nickname: "Adam", isAdmin: false)
let serverURL = NSURL(“http://testapp.us1.cloud.realm.io”)
SyncUser.logIn(with: credentials,
               server: serverURL) { user, error in
    if let user = user {
        // can now open the default synchronized Realm with this user
        let realm = try! Realm.defaultSync()
    } else if let error = error {
        // handle error
    }
}

P-1-Required T-Feature

Most helpful comment

I think our ideal API would look something like:

// 1. Open the Realm in offline mode, and begin syncing with the first user to log in
Realm.Configuration.defaultConfiguration = SyncConfiguration.automatic()
let realm = try! Realm()
SyncUser.logIn(with: credentials, server: serverURL) { ... }

// 2. Log in, then async open the Realm with the current user
SyncUser.logIn(with: credentials, server: serverURL) { user, error in
    if let user = user {
        Realm.Configuration.defaultConfiguration = SyncConfiguration.automatic()
        Realm.asyncOpen() { realm in
            // ...
        }
    }
}

// 3. Log in, then async open the Realm with that specific user
SyncUser.logIn(with: credentials, server: serverURL) { user, error in
    if let user = user {
        Realm.Configuration.defaultConfiguration = SyncConfiguration.automatic(user: user)
        Realm.asyncOpen() { realm in
            // ...
        }
    }
}

Anything more complicated (a Realm URL that isn't just the default one derived from the auth URL, or customizing the configuration in other ways) would be done by modifying the configuration struct as usual.

2 and 3 should be completely trivial to support since it's basically just a convenience function. 1 would be more involved, but also has the most potential for simplifying things.

All 8 comments

I think our ideal API would look something like:

// 1. Open the Realm in offline mode, and begin syncing with the first user to log in
Realm.Configuration.defaultConfiguration = SyncConfiguration.automatic()
let realm = try! Realm()
SyncUser.logIn(with: credentials, server: serverURL) { ... }

// 2. Log in, then async open the Realm with the current user
SyncUser.logIn(with: credentials, server: serverURL) { user, error in
    if let user = user {
        Realm.Configuration.defaultConfiguration = SyncConfiguration.automatic()
        Realm.asyncOpen() { realm in
            // ...
        }
    }
}

// 3. Log in, then async open the Realm with that specific user
SyncUser.logIn(with: credentials, server: serverURL) { user, error in
    if let user = user {
        Realm.Configuration.defaultConfiguration = SyncConfiguration.automatic(user: user)
        Realm.asyncOpen() { realm in
            // ...
        }
    }
}

Anything more complicated (a Realm URL that isn't just the default one derived from the auth URL, or customizing the configuration in other ways) would be done by modifying the configuration struct as usual.

2 and 3 should be completely trivial to support since it's basically just a convenience function. 1 would be more involved, but also has the most potential for simplifying things.

// 1. Open the Realm in offline mode, and begin syncing with the first user to log in
Realm.Configuration.defaultConfiguration = SyncConfiguration.automatic()
let realm = try! Realm()
SyncUser.logIn(with: credentials, server: serverURL) { ... }

Regarding this use case, how are you going to resolve the full path of the Realm since you're starting offline (no user identity to use when resolving the full path)

The local disk path would simply not be derived from the URL. You inherently can only ever have one "automatic" Realm, so it can just be a single hardcoded name.

What happens when you logout then login with a different user, will you reuse the same Realm? (i.e you still point to the same "automatic" Realm?)

User switching would get weird. My inclination is that we start with not trying to support multiple users at all. As a future enhancement we could add a way to do the "create offline and attach a user later" flow with explicitly specified users rather than the first to log in, but I think we specifically want to avoid trying to support anything more than we have to with the "automatic" mode.

I don't think we're even intending to support the "create offline" case in the initial version?

The local disk path would simply not be derived from the URL. You inherently can only ever have one "automatic" Realm, so it can just be a single hardcoded name.

I don't think that is true, because my understanding was that the default Realm should be a partial Realm, which means it must be different for each user. So I don't think the offline login use case can be supported either at this point in time.

Done.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

javierjulio picture javierjulio  ·  3Comments

matteodanelli picture matteodanelli  ·  3Comments

menhui222 picture menhui222  ·  3Comments

jpsim picture jpsim  ·  3Comments

carvalho-oak picture carvalho-oak  ·  3Comments