Navigation

Sync Changes Between Devices - Node.js 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.

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.

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

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.

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

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

On this page