Configure & Open a Synced Realm - Kotlin SDK
On this page
This page describes how to open a synced database and the various configuration options available.
Prerequisites
Before you can access a synced realm from the client, you must:
Enable sync in the App Services UI.
Install the sync distribution of the Kotlin SDK for Android or Kotlin Multiplatform.
Authenticate a user in your client project.
Open a Synced Realm
To open a Flexible Sync realm,
pass a user and a set of Realm object schemas to
SyncConfiguration.Builder(). Next, create a set of initial subscriptions with the initialSubscriptions()
builder method. Finally, pass the configuration to Realm.open() to open
an instance of the realm:
val app = App.create(YOUR_APP_ID) // use constants for query names so you can edit or remove them later val NAME_QUERY = "NAME_QUERY" runBlocking { val user = app.login(Credentials.anonymous()) val config = SyncConfiguration.Builder(user, setOf(Toad::class)) .initialSubscriptions { realm -> add( realm.query<Toad>( "name == $0", "name value" ), "subscription name" ) } .build() val realm = Realm.open(config) Log.v("Successfully opened realm: ${realm.configuration.name}") realm.close() }
For more information on bootstrapping the realm with initial subscriptions and managing your synced realm subscriptions, refer to Manage Sync Subscriptions.
Configure a Synced Realm
To adjust specific configuration settings, use the options provided by SyncConfiguration.Builder:
val app = App.create(YOUR_APP_ID) runBlocking { val user = app.login(Credentials.anonymous()) val config = SyncConfiguration.Builder(user, setOf(Toad::class)) .maxNumberOfActiveVersions(10) .name("realm name") .initialSubscriptions { realm -> add( realm.query<Toad>( "name == $0", "name value" ), "subscription name" ) } .build() val realm = Realm.open(config) Log.v("Successfully opened realm: ${realm.configuration}") realm.close() }
New in version 1.13.0: Sync timeout configuration options added
In Kotlin v1.13.0, you can override various default timeouts used for sync
operations. You can set these timeouts in the App
client
configuration, and they apply to all sync sessions in the app.
To learn how, refer to Configure Sync Timeouts.
Download Changes Before Open
When you open a synced realm with the Kotlin SDK, you can use the .waitForInitialRemoteData() function to download the changeset from your App before opening the realm. Setting this blocks the realm from opening until all the data has been downloaded. If a device is offline, this blocks opening the realm. Because initial data download could be a lengthy operation, you should open a realm using this setting on a background thread.
This function accepts a timeout Duration. When the download exceeds a timeout duration, Realm throws a DownloadingRealmTimeoutException.
val user = app.login(Credentials.emailPassword(email, password)) val config = SyncConfiguration.Builder(user, setOf(Toad::class)) .waitForInitialRemoteData(60.seconds) .initialSubscriptions { realm -> add( realm.query<Toad>( "name == $0", "Jeremiah" ), "toads_named_jeremiah" ) } .build() val realm = Realm.open(config) Log.v("Successfully opened realm: ${realm.configuration}") // Query the realm we opened after waiting for data to download, and see that it contains data val downloadedToads: RealmResults<Toad> = realm.query<Toad>().find() Log.v("After downloading initial data, downloadedToads.size is ${downloadedToads.size}") realm.close()
Conditionally Download Changes Before Opening
If there is a condition that determines whether your app should download server data before opening the realm, you can use that with SyncSession.downloadAllServerChanges() to conditionally download changes before opening the realm. Calling this method blocks until all known remote changes have been downloaded and applied to the Realm, or until a specified timeout is hit. You should call this method only from a non-UI thread.
This function accepts a timeout Duration.
val user = app.login(Credentials.emailPassword(email, password)) val config = SyncConfiguration.Builder(user, setOf(Toad::class)) .initialSubscriptions { realm -> add( realm.query<Toad>( "name == $0", "Lollihops" ), "toads_named_lollihops" ) } .build() val realm = Realm.open(config) // Conditionally download data before using the realm based on some business logic if (downloadData) { realm.syncSession.downloadAllServerChanges(30.seconds) } // Query the realm we opened after waiting for data to download, and see that it contains data val downloadedToads: RealmResults<Toad> = realm.query<Toad>().find() Log.v("After conditionally downloading data, downloadedToads.size is ${downloadedToads.size}") realm.close()
Open a Synced Realm Offline
When your Realm application authenticates a user, it caches the user's credentials. You can check for existing user credentials to bypass the login flow and access the cached user. Use this to open a realm offline.
Note
Initial login requires a network connection
When a user signs up for your app, or logs in for the first time with an existing account on a client, the client must have a network connection. Checking for cached user credentials lets you open a realm offline, but only if the user has previously logged in while online.
You can only open a synced realm offline if you do not require your client app to download changes before opening the realm.
// You can only open a synced realm offline if there is a cached user credential. If // there is no app.currentUser, you must log them in, which requires a network connection. if (app.currentUser == null) { app.login(Credentials.emailPassword(email, password)) } // If the app.currentUser isn't null, you can use the cached credential to open the synced // realm even if the user is offline. val user = app.currentUser!! val realm = Realm.open(config) // Query the realm we opened, and see that it contains data val offlineToads: RealmResults<Toad> = realm.query<Toad>().find() Log.v("After opening a realm offline, offlineToads.size is ${offlineToads.size}") realm.close()