Docs Menu
Docs Home
/ /
Atlas Device SDKs
/ /

Configure a Synced Realm - Java SDK

On this page

  • Prerequisites
  • Synced Realms
  • Synced Realm Configuration
  • Open a Synced Realm While Offline
  • Close a Realm

Note

New Java SDK apps cannot use RealmAny

New App Services Apps will not be able to synchronize data models with properties of type RealmAny.

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

  1. Enable sync in the App Services UI.

  2. Initialize the app

  3. Enable Sync in your application by adding the following to the top level of your application-level build.gradle file:

    realm { syncEnabled = true }
  4. Authenticate a user in your client project.

Synced realms use Atlas Device Sync to store data both on the client device and in your synced data source. Opening a synced realm works exactly like opening a local realm, except you use SyncConfiguration to customize the settings for synced realms.

To configure settings for a realm, create a SyncConfiguration with a SyncConfiguration.Builder.

To open a synced realm, call getInstanceAsync(), passing in a SyncConfiguration object.

When your application uses Flexible Sync, call the initialSubscriptions() sync configuration builder method with an instance of SyncConfiguration.InitialFlexibleSyncSubscriptions() to open a synced realm. In the configure() method, instantiate an UnmanagedSubscription with a name and query using Subscription.create(). Pass your new subscription to the add() method of the MutableSubscriptionSet parameter to add it to your subscriptions:

// instantiate a Realm App connection
String appID = YOUR_APP_ID; // replace this with your App ID
App app = new App(new AppConfiguration.Builder(appID)
.build());
// authenticate a user
Credentials credentials = Credentials.anonymous();
app.loginAsync(credentials, it -> {
if (it.isSuccess()) {
User user = it.get();
// add an initial subscription to the sync configuration
SyncConfiguration config = new SyncConfiguration.Builder(app.currentUser())
.initialSubscriptions(new SyncConfiguration.InitialFlexibleSyncSubscriptions() {
@Override
public void configure(Realm realm, MutableSubscriptionSet subscriptions) {
subscriptions.add(Subscription.create("subscriptionName",
realm.where(Frog.class)
.equalTo("species", "spring peeper")));
}
})
.build();
// instantiate a realm instance with the flexible sync configuration
Realm.getInstanceAsync(config, new Realm.Callback() {
@Override
public void onSuccess(Realm realm) {
Log.v("EXAMPLE", "Successfully opened a realm.");
}
});
} else {
Log.e("EXAMPLE", "Failed to log in: " + it.getError().getErrorMessage());
}
});
// instantiate a Realm App connection
val appID: String = YOUR_APP_ID // replace this with your App ID
val app = App(
AppConfiguration.Builder(appID)
.build()
)
// authenticate a user
val credentials = Credentials.anonymous()
app.loginAsync(
credentials
) { it: App.Result<User?> ->
if (it.isSuccess) {
val user = it.get()
// add an initial subscription to the sync configuration
val config = SyncConfiguration.Builder(app.currentUser())
.initialSubscriptions { realm, subscriptions ->
subscriptions.add(
Subscription.create(
"subscriptionName",
realm.where(Frog::class.java)
.equalTo("species", "spring peeper")
)
)
}
.build()
// instantiate a realm instance with the flexible sync configuration
Realm.getInstanceAsync(config, object : Realm.Callback() {
override fun onSuccess(realm: Realm) {
Log.v("EXAMPLE", "Successfully opened a realm.")
}
})
} else {
Log.e(
"EXAMPLE",
"Failed to log in: " + it.error.errorMessage
)
}
}

Tip

See also:

For more information about subscriptions, see Subscribe to Queryable Fields.

Important

Synchronous Reads and Writes on the UI Thread

By default, you can only read or write to a realm in your application's UI thread using asynchronous transactions. That is, you can only use Realm methods whose name ends with the word Async in the main thread of your Android application unless you explicitly allow the use of synchronous methods.

This restriction exists for the benefit of your application users: performing read and write operations on the UI thread can lead to unresponsive or slow UI interactions, so it's usually best to handle these operations either asynchronously or in a background thread. However, if your application requires the use of synchronous realm reads or writes on the UI thread, you can explicitly allow the use of synchronous methods with the following SyncConfiguration options:

SyncConfiguration config = new SyncConfiguration.Builder(app.currentUser())
.allowQueriesOnUiThread(true)
.allowWritesOnUiThread(true)
.initialSubscriptions(new SyncConfiguration.InitialFlexibleSyncSubscriptions() {
@Override
public void configure(Realm realm, MutableSubscriptionSet subscriptions) {
subscriptions.add(Subscription.create("springPeepers",
realm.where(Frog.class)
.equalTo("species", "spring peeper")));
}
})
.build();
Realm.getInstanceAsync(config, new Realm.Callback() {
@Override
public void onSuccess(Realm realm) {
Log.v(
"EXAMPLE",
"Successfully opened a realm with reads and writes allowed on the UI thread.");
}
});
val config = SyncConfiguration.Builder(app.currentUser())
.allowQueriesOnUiThread(true)
.allowWritesOnUiThread(true)
.initialSubscriptions { realm, subscriptions ->
subscriptions.add(
Subscription.create(
"subscriptionName",
realm.where(Frog::class.java)
.equalTo("species", "springPeepers")
)
)
}
.build()
Realm.getInstanceAsync(config, object : Realm.Callback() {
override fun onSuccess(realm: Realm) {
Log.v(
"EXAMPLE",
"Successfully opened a realm with reads and writes allowed on the UI thread."
)
}
})

You can open a synced realm when offline with the exact same syntax that you use to open a synced realm while online. Not all SDKs follow this pattern, so cross-platform developers should consult the documentation for each SDK to learn more.

It is important to remember to call the close() method when done with a realm instance to free resources. Neglecting to close realms can lead to an OutOfMemoryError.

realm.close();
realm.close()

Back

Sync Data