Sync Changes Between Devices - React Native SDK¶
Open a Synced Realm¶
To open a synced realm, call Realm.open().
Pass in a Configuration
object, which must include the sync
property defining a
SyncConfiguration object.
In the following example, a synced realm is opened with a schema value of a predefined
TaskSchema
SyncConfiguration
object that uses the currently logged in
user and a partition value of "MyPartition".
const config = { schema: [TaskSchema], sync: { user: app.currentUser, partitionValue: "myPartition", } }; const realm = await Realm.open(config);
Sync Changes in the Background¶
You may want to sync changes in the background to display partial data to the user while the synced realm downloads data from the server, preventing the user experience from being blocked. We recommend syncing changes in the background for applications in which the user's device may go offline. To sync changes in the background, open a synced realm synchronously.
Create a OpenRealmBehaviorConfiguration object and set its
type
to "openImmediately"
.
const OpenRealmBehaviorConfiguration = { type: "openImmediately", };
Create a Configuration object, which must
include the sync
property defining a SyncConfiguration object. Set this
OpenRealmBehaviorConfiguration
object as the value for
the newRealmFileBehavior
and existingRealmFileBehavior
fields of the
SyncConfiguration
.
const config = { schema: [DogSchema], // predefined schema sync: { user: app.currentUser, partitionValue: "MyPartitionValue", // The behavior to use when this is the first time opening a realm. newRealmFileBehavior: OpenRealmBehaviorConfiguration, // The behavior to use when a realm file already exists locally, // i.e. you have previously opened the realm. existingRealmFileBehavior: OpenRealmBehaviorConfiguration, }, };
Finally, call Realm.open() to open a synced realm. This will create a sync session and begin downloading any existing data from the server in the background.
const realm = await Realm.open(config);
If a realm has read-only realm level permissions, then you must asynchronously open the realm. Opening a file-level read-only realm without the asynchronous API will cause an error if your session is online. Synced realms are opened asynchronously by default. Learn how to open a synced realm.
Pause or Resume a Sync Session¶
You can pause synchronization using the syncSession.pause() method. To resume synchronization, use the syncSession.resume() method
var config = { schema: [DogSchema], // predefined schema sync: { user: app.currentUser, partitionValue: "MyPartitionValue", }, }; let realm = await Realm.open(config); const syncSession = realm.syncSession; // Pause synchronization syncSession.pause(); // Later, resume synchronization syncSession.resume();
Check Upload & Download Progress for a Sync Session¶
To check the upload and download progress for a sync session, add a progress notification using the syncSession.addProgressNotification() method.
The syncSession.addProgressNotification()
method takes in the following three parameters:
- A
direction
parameter that can be set to"upload"
or"download"
to register notifications for either event. - A
mode
parameter that can be set to"reportIndefinitely"
(for the notifications to continue until the callback is unregistered using the syncSession.removeProgressNotification() method), or"forCurrentlyOutstandingWork"
(for the notifications to continue until only the currently transferable bytes are synced). - A callback parameter with the arguments
transferred
andtransferable
, representing the current number of bytes already transferred and the number of transferable bytes (the number of bytes already transferred plus the number of bytes pending transfer), respectively.
In the following example, an application developer registers a callback on the syncSession
to
listen for upload events indefinitely. The developer writes to the realm and
then unregisters the syncSession
notification callback.
var config = { schema: [DogSchema], // predefined schema sync: { user: app.currentUser, partitionValue: "MyPartitionValue", }, }; let realm = await Realm.open(config); const syncSession = realm.syncSession; syncSession.addProgressNotification( "upload", "reportIndefinitely", (transferred, transferable) => { console.log(`${transferred} bytes has been transferred`); console.log( `There are ${transferable} total transferable bytes, including the ones that have already been transferred` ); } ); // Upload something let dog; realm.write(() => { dog = realm.create("Dog", { name: "Fido", age: 2, }); }); // use dog // remember to unregister the progress notifications syncSession.removeProgressNotification((transferred, transferable) => { console.log(`There was ${transferable} total transferable bytes`); console.log(`${transferred} bytes were transferred`); });
Check the Network Connection¶
To check the current state of the connection to the server, call the syncSession.connectionState() method.
MongoDB Realm's offline-first design means that you generally don't need to
check the current network connection state. That said, the
syncSession.connectionState()
method is available if your app needs to
gets the current state of the connection to the server.
var config = { schema: [DogSchema], // predefined schema sync: { user: app.currentUser, partitionValue: "MyPartitionValue", }, }; let realm = await Realm.open(config); const syncSession = realm.syncSession; const connectionState = syncSession.connectionState();
Set the Client Log Level¶
You can set the realm Sync client log level by calling Realm.App.Sync.setLogLevel() with your Realm.App.
In the following example, an application developer sets the sync client
log level to "debug"
.
Realm.App.Sync.setLogLevel(app, "debug");
Multiplex Sync Sessions¶
To enable session multiplexing, call Realm.App.Sync.enableSessionMultiplexing() with your Realm.App.
Only use session multiplexing if you see errors about reaching the file descriptor limit, and you know you are using many sync sessions.
Realm.App.Sync.enableSessionMultiplexing(app);
Handle Sync Errors¶
While developing an application that uses Realm Sync, you should set an error handler. This error handler will detect and respond to any failed sync-related API calls.
Set an error handler by registering an error callback as part of the SyncConfiguration.
var config = { schema: [DogSchema], // predefined schema sync: { user: app.currentUser, partitionValue: "MyPartitionValue", error: (_session, error) => { (error) => { console.log(error.name, error.message); }; }, }, }; const realm = await Realm.open(config);
Perform a Client Reset¶
You can customize behavior in the event of a client reset error with a custom error handler function:
let realm = await Realm.open(config); function errorSync(_session, error) { if (realm) { if (error.name === "ClientReset") { const realmPath = "<Your Realm Path>"; realm.close(); console.log(`Error ${error.message}, need to reset ${realmPath}…`); Realm.App.Sync.initiateClientReset(app, realmPath); // pass your realm app instance, and realm path to initiateClientReset() console.log(`Creating backup from ${error.config.path}…`); // Move backup file to a known location for a restore fs.renameSync(error.config.path, realmPath + "~"); // Discard the reference to the realm instance realm = null; } else { console.log(`Received error ${error.message}`); } } } var config = { schema: [DogSchema], // predefined schema sync: { user: app.currentUser, partitionValue: "MyPartitionValue", error: errorSync, }, };
To see how to recover unsynced local changes in a client reset, check out this example on GitHub.