Docs Menu

Docs HomeRealm

Sync Changes Between Devices - Java SDK

On this page

  • Prerequisites
  • Open a Synced Realm
  • Sync Data
  • Pause or Resume a Sync Session
  • Check the Current Network Connection
  • Check Upload & Download Progress for a Sync Session
  • Handle Sync Errors
  • Reset a Client Realm File

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.

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:

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.


See also:

The syntax to read, write, and watch for changes on a synced realm is identical to the syntax for non-synced realms. While you work with local data, a background thread efficiently integrates, uploads, and downloads changesets.


When Using Sync, Avoid Writes on the Main Thread

The fact that Realm performs sync integrations on a background thread means that if you write to your realm on the main thread, there's a small chance your UI could appear to hang as it waits for the background sync thread to finish a write transaction. Therefore, it's a best practice never to write on the main thread when using Sync.

The following code reads a collection of Task objects, then writes a new Task to the realm:


See also:

To pause a currently active sync session, call stop() on your SyncSession:


Use the .stop() method to control when a device syncs. You should only use it for temporary and short-term pauses of syncing.

Examples of when to use .stop() include:

  • Syncing data only at specified time of day

  • Conserving device battery use

Don't use the .stop() method to stop syncing for indefinite time periods or time ranges in months and years. The functionality is not designed or tested for these use cases, and you could encounter a range of issues when using it this way.

To resume a currently paused sync session, call start() on your SyncSession:

To check the current network connection, call getConnectionState() on your SyncSession:


Connection States vs. Session States

The SDK manages communication with App Services at two levels: connection state and session state. Connection state tracks the state of the network connection between a client device and your backend App. Session state refers to a single user's synchronization state, which can be paused and resumed in the SDK at will. As a result, you must check both states to determine whether a user's local changes will sync to the backend. Synchronization only occurs when the connection state is "connected" and the session state is "active".

You can also subscribe to connection changes on your SyncSession with addConnectionChangeListener(), which works similarly to upload and download listeners.


Flexible Sync progress notifications are not yet fully supported. When using Flexible Sync, downloads only report notifications after changes are integrated. Partition-Based Sync provides ongoing notifications as changes progress downloading. Uploads report ongoing progress notifications for both Sync Modes.

To subscribe to progress updates for uploads, call addUploadProgressListener() on your SyncSession with a ProgressMode and a ProgressListener(). The ProgressMode passed determines which upload events your listener receives:

To subscribe to progress updates for downloads, call addDownloadProgressListener() on your SyncSession with a ProgressMode and a ProgressListener(). The ProgressMode passed determines which download events your listener receives:

You can configure an error handler to detect and respond to any errors that occur in the Sync process. To define an error handler, pass an ErrorHandler to the SyncConfiguration.Builder.errorHandler() builder method:


For a list of common Device Sync errors and how to handle them, refer to Sync Errors in the App Services Device Sync documentation.

You can customize behavior in the event of a client reset with a custom client reset handler:


See also:

To see how to recover unsynced local changes in a client reset, check out this example on GitHub.

←  Authenticate Users - Java SDKFlexible Sync - Java SDK →
Share Feedback
© 2023 MongoDB, Inc.


  • Careers
  • Investor Relations
  • Legal Notices
  • Privacy Notices
  • Security Information
  • Trust Center
© 2023 MongoDB, Inc.