Docs Menu

Sync Changes Between Devices - React Native SDK

On this page

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 SyncConfiguration, you must include include user and partitionValue.

When opening a synced realm, the configuration you use depends on the initial sync behavior you want. You can connect to a synced realm in the following ways:

Example

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);

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);
Warning
Read-only Realms Must Not Be Synced in the Background

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.

Opening a synced realm starts a sync session. You can pause and resume the sync session on the realm. Pausing a sync session only pauses that realm's sync session. If you have more than one open realm, pause does not affect the sync sessions for other realms.

To pause synchronization, use the syncSession.pause() method. To resume synchronization, use the syncSession.resume() method.

const OpenRealmBehaviorConfiguration = {
type: "openImmediately",
};
var config = {
schema: [DogSchema], // predefined schema
sync: {
user: app.currentUser,
partitionValue: "MyPartitionValue",
newRealmFileBehavior: OpenRealmBehaviorConfiguration,
existingRealmFileBehavior: OpenRealmBehaviorConfiguration,
},
};
let realm = await Realm.open(config);
const syncSession = realm.syncSession;
// Pause synchronization
syncSession.pause();
// Later, resume synchronization
syncSession.resume();
Note

Use the .pause() 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 .pause() include:

  • Syncing data only at specified time of day
  • Conserving device battery use

Don't use the .pause() 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 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 and transferable, 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.
Example

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.

const OpenRealmBehaviorConfiguration = {
type: "openImmediately",
};
var config = {
schema: [DogSchema], // predefined schema
sync: {
user: app.currentUser,
partitionValue: "MyPartitionValue",
newRealmFileBehavior: OpenRealmBehaviorConfiguration,
existingRealmFileBehavior: OpenRealmBehaviorConfiguration,
},
};
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`);
});

To check the current state of the connection to the server, call the syncSession.connectionState() method.

Tip

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();

You can set the realm Sync client log level by calling Realm.App.Sync.setLogLevel() with your Realm.App.

Example

In the following example, an application developer sets the sync client log level to "debug".

Realm.App.Sync.setLogLevel(app, "debug");
Tip

To diagnose and troubleshoot errors while developing your application, set the log level to debug or trace. For production deployments, decrease the log level for improved performance.

To enable session multiplexing, call Realm.App.Sync.enableSessionMultiplexing() with your Realm.App.

Warning

Only use session multiplexing if you see errors about reaching the file descriptor limit, and you know you are using many sync sessions.

Example
Realm.App.Sync.enableSessionMultiplexing(app);

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);

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,
},
};
Tip

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

Give Feedback
© 2021 MongoDB, Inc.

About

  • Careers
  • Legal Notices
  • Privacy Notices
  • Security Information
  • Trust Center
© 2021 MongoDB, Inc.