Docs Menu
Docs Home
/ /
Atlas Device SDKs
/ /

Partition-Based Sync - Java SDK

On this page

  • Partition Value
  • Open a Synced Realm
  • Open a Synced Realm While Online
  • Open a Synced Realm While Offline
  • Migrate from Partition-Based Sync to Flexible Sync
  • Updating Client Code After Migration

Partition-Based Sync is an older mode for using Atlas Device Sync with the Realm Java SDK. We recommend using Flexible Sync for new apps. The information on this page is for users who are still using Partition-Based Sync.

Tip

Realm Java SDK v10.16.0 and newer supports the ability to migrate from Partition-Based Sync to Flexible Sync. For more information, refer to: Migrate from Partition-Based Sync to Flexible Sync.

For more information about Partition-Based Sync and how to configure it in Atlas App Services, refer to Partition-Based Sync in the App Services documentation.

When you select Partition-Based Sync for your backend App configuration, your client implementation must include a partition value. This is the value of the partition key field you select when you configure Partition-Based Sync.

The partition value determines which data the client application can access.

You pass in the partition value when you open a synced realm.

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

The following example configures a synced realm with:

  • partition-based Sync

  • synchronous reads explicitly allowed on the UI thread

  • synchronous writes explicitly allowed on the UI thread

  • explicit waiting for all backend changes to synchronize to the device before returning an open realm

  • automatic compaction when launching the realm to save file space

Warning

Production Applications Should Handle Client Resets

Applications used in production environments should handle client reset errors. To learn more, see Reset a Client Realm.

SyncConfiguration config = new SyncConfiguration.Builder(app.currentUser(), PARTITION)
.allowQueriesOnUiThread(true)
.allowWritesOnUiThread(true)
.waitForInitialRemoteData(500, TimeUnit.MILLISECONDS)
.compactOnLaunch()
.build();
Realm.getInstanceAsync(config, new Realm.Callback() {
@Override
public void onSuccess(Realm realm) {
Log.v("EXAMPLE", "Successfully opened a realm.");
}
});
val config =
SyncConfiguration.Builder(app.currentUser(), PARTITION)
.allowQueriesOnUiThread(true)
.allowWritesOnUiThread(true)
.waitForInitialRemoteData(500, TimeUnit.MILLISECONDS)
.compactOnLaunch()
.build()
Realm.getInstanceAsync(config, object : Realm.Callback() {
override fun onSuccess(realm: Realm) {
Log.v("EXAMPLE", "Successfully opened a realm.")
}
})

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(), PARTITION)
.allowQueriesOnUiThread(true)
.allowWritesOnUiThread(true)
.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(), PARTITION)
.allowQueriesOnUiThread(true)
.allowWritesOnUiThread(true)
.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.")
}
})

To open a synced realm, call getInstanceAsync(), passing in a SyncConfiguration object. The following code demonstrates how to create a realm with specific sync settings created using a SyncConfiguration object:

SyncConfiguration config = new SyncConfiguration.Builder(app.currentUser(), PARTITION)
.allowQueriesOnUiThread(true)
.allowWritesOnUiThread(true)
.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(), PARTITION)
.allowQueriesOnUiThread(true)
.allowWritesOnUiThread(true)
.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.")
}
})

The code above shows how to open the realm asynchronously by using getInstanceAsync(). You can also open a realm synchronously by using getInstance(), which returns an open realm before synchronizing all data from the backend. However, this may lead to temporary data inconsistencies while the remote data is downloaded, and is generally not recommended. You can use the waitForInitialRemoteData() configuration option to force the SDK to fetch remote data before opening the realm to avoid these inconsistencies.

The partition value specifies which subset of your data to sync. This is typically a user ID, project ID, store ID, or some other category identifier in your app that has particular relevance to the current user.

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.

You can migrate your App Services Device Sync Mode from Partition-Based Sync to Flexible Sync. Migrating is an automatic process that does not require any changes to your application code. Automatic migration requires Realm Java SDK version 10.16.0 or newer.

Migrating enables you to keep your existing App Services users and authentication configuration. Flexible Sync provides more versatile permissions configuration options and more granular data synchronization.

For more information about how to migrate your App Services App from Partition-Based Sync to Flexible Sync, refer to Migrate Device Sync Modes.

The automatic migration from Partition-Based Sync to Flexible Sync does not require any changes to your client code. However, to support this functionality, Realm automatically handles the differences between the two Sync Modes by:

  • Automatically creating Flexible Sync subscriptions for each object type where partitionKey == partitionValue.

  • Injecting a partitionKey field into every object if one does not already exist. This is required for the automatic Flexible Sync subscription.

If you need to make updates to your client code after migration, consider updating your client codebase to remove hidden migration functionality. You might want update your client codebase when:

  • You add a new model or change a model in your client codebase

  • You add or change functionality that involves reading or writing Realm objects

  • You want to implement more fine-grained control over what data you sync

Make these changes to convert your Partition-Based Sync client code to use Flexible Sync:

  • Update your SyncConfiguration.Builder to use Flexible Sync. This involves removing the partitionValue and adding a set of initial subscriptions, if needed.

  • Add relevant properties to your object models to use in your Flexible Sync subscriptions. For example, you might add an ownerId property to enable a user to sync only their own data.

  • Remove automatic Flexible Sync subscriptions. If you did not add initial subscriptions in the SyncConfiguration.Builder, manually create the relevant subscriptions.

For examples of Flexible Sync permissions strategies, including examples of how to model data for these strategies, refer to Device Sync Permissions Guide.

When you migrate from Partition-Based Sync to Flexible Sync, Realm automatically creates hidden Flexible Sync subscriptions for your app. The next time you add or change subscriptions, we recommend that you:

  1. Remove the automatically-generated subscriptions.

  2. Manually add the relevant subscriptions in your client codebase.

This enables you to see all of your subscription logic together in your codebase for future iteration and debugging.

For more information about the automatically-generated Flexible Sync subscriptions, refer to Migrate Client App to Flexible Sync.

Back

Background Sync

Next

Test and Debug