Sync Changes Between Devices - Java SDK
On this page
Prerequisites
Before you can access a synced realm from the client, you must:
Enable sync in the App Services UI.
Enable Sync in your application by adding the following to the top level of your application-level
build.gradle
file:realm { syncEnabled = true } Authenticate a user in your client project.
Open a Synced Realm
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.
Tip
See also:
Sync Data
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.
Important
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:
Tip
See also:
Pause or Resume a Sync Session
To pause a currently active sync session, call stop() on your SyncSession:
Note
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:
Check the Current Network Connection
To check the current network connection, call getConnectionState() on your SyncSession:
Important
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.
Check Upload & Download Progress for a Sync Session
Note
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:
Handle Sync Errors
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:
Tip
For a list of common Device Sync errors and how to handle them, refer to Sync Errors in the App Services Device Sync documentation.
Reset a Client Realm File
You can customize behavior in the event of a client reset with a custom client reset handler:
Tip
See also:
To see how to recover unsynced local changes in a client reset, check out this example on GitHub.