Docs Menu
Docs Home
/ /
Atlas Device SDKs
/
/

Configure & Open a Synced Realm - Kotlin SDK

On this page

  • Prerequisites
  • Open a Synced Realm
  • Configure a Synced Realm
  • Download Changes Before Open
  • Conditionally Download Changes Before Opening
  • Open a Synced Realm Offline

This page describes how to open a synced database and the various configuration options available.

Before you can access a synced realm from the client, you must:

  1. Enable sync in the App Services UI.

  2. Install the sync distribution of the Kotlin SDK for Android or Kotlin Multiplatform.

  3. Authenticate a user in your client project.

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.

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.

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()

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()

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()
← 
 →