Docs Menu
Docs Home
/ /
Atlas Device SDKs
/ /

Configure & Open a Synced Realm - Node.js SDK

On this page

  • Synced Realms
  • Prerequisites
  • Open a Synced Realm
  • Open Synced Realm at Specific Path
  • Open a Synced Realm While Offline
  • Open Immediately with Background Sync
  • Open After Timeout with Background Sync
  • Sync Changes in the Background
  • Cancel Asynchronous Operations after a Timeout

You can configure a realm to automatically synchronize data between many devices that each have their own local copy of the data. Synced realms use a different configuration than local-only realms and require an Atlas App Services backend to handle the synchronization process.

Applications can always create, modify, and delete synced realm objects locally, even when offline. Whenever a network connection is available, the Realm SDK opens a connection to an application server and syncs changes to and from other clients. The Atlas Device Sync protocol and server-side operational transforms guarantee that all fully synced instances of a realm see exactly the same data, even if some changes occurred offline and/or were received out of order.

Tip

Learn How to Configure and Use Sync

For more information on synced realms, including directions on how to set up sync in a Realm app, see Atlas Device Sync Overview.

Before you configure a realm with Flexible Sync in a Node.js application:

  1. Enable Flexible Sync on the backend. You must configure Flexible Sync in the backend before you can use it with your client application.

  2. Initialize the App client.

  3. Authenticate a user in your client project.

The first step in implementing Device Sync is to open the synced Realm. The following information pertains to an app using Flexible Sync. If your existing app uses the older Partition-Based Sync, refer to Open a Partition-Based Synced Realm. If you have not yet decided or are unsure which to use, read the Choose Your Sync Mode page.

To open a realm using Flexible Sync, call Realm.open(). Pass in a ConfigurationWithSync object, which must include the sync property defining a SyncConfiguration object. In the SyncConfiguration, you must include include a user and flexible:true.

const realm = await Realm.open({
schema: [TaskSchema, TeamSchema],
sync: {
user: app.currentUser,
flexible: true,
},
});

By default, Realm syncs all data from the server before returning. If you want to sync data in the background, read the Open a Synced Realm While Offline section.

Important

Flexible Sync Requires a Subscription

You can't use a Flexible Sync realm until you add at least one subscription. To learn how to add subscriptions, see: Add a Subscription.

New in version realm@11.6.0.

Using AppConfiguration.baseFilePath, and Realm.Configuration.path, you can control where Realm and metadata files are stored on client devices.

To do so, set <AppProvider>.baseFilePath. If baseFilePath is not set, the current work directory is used. You can also set <RealmProvider>.sync.path for more control.

const app = new Realm.App({ id: APP_ID, baseFilePath: customPath });
const user = await app.logIn(Realm.Credentials.anonymous());
const realm = await Realm.open({
schema: [Car],
sync: {
flexible: true,
user,
},
});

If baseFilePath is set, metadata is always stored in <baseFilePath>/mongodb-realm/. If baseFilePath isn't set, then metadata is stored in <Realm.defaultPath>/mongodb-realm.

Where exactly your Realm file is stored can vary depending on how you set Realm.Configuration.path:

  • Realm.Configuration.path is not set and baseFilePath is set. Your Realm file is stored at baseFilePath.

  • Realm.Configuation.path is set to a relative path. Your Realm file is stored relative to baseFilePath.

  • Realm.Configuration.path is an absolute path. Your Realm file is stored at Realm.Configuration.path.

When your Realm application authenticates a user, it caches the user's credentials. You can check for existing user credentials to bypass the login flow and access the cached user. Use this to open a realm offline.

Note

Initial login requires a network connection

When a user signs up for your app, or logs in for the first time with an existing account on a client, the client must have a network connection. Checking for cached user credentials lets you open a realm offline, but only if the user has previously logged in while online.

// Log user into your App Services App.
// On first login, the user must have a network connection.
const getUser = async () => {
// If the device has no cached user credentials, log in.
if (!app.currentUser) {
const credentials = Realm.Credentials.anonymous();
await app.logIn(credentials);
}
// If the app is offline, but credentials are
// cached, return existing user.
return app.currentUser!;
};

The following subsections show how to use background synchronization to access a realm while offline. To do this, use the cached user and an OpenRealmBehaviorConfiguration object.

Within your Sync Configuration, set the optional newRealmFileBehavior and existingRealmFileBehavior fields to your OpenRealmBehaviorConfiguration object to enable background synchronization.

Important

Offline Login is Supported for Both Flexible and Partition-Based Sync Configurations

You can open a realm immediately with background sync or after a timeout elapses using Flexible Sync or the older Partition-Based Sync.

Partition-Based Sync is an outdated sync mode. See the Partition-Based Sync - Node.js SDK page for details on using Partition-Based Sync for your application.

If the user's device is not connected to the internet or you're uncertain of it's connection status, set the realm behavior's type to openImmediately. This syncs data from the server in the background.

const behaviorConfiguration = {
type: "openImmediately",
};
const config = {
schema: [Car],
sync: {
user: await getUser(),
flexible: true,
newRealmFileBehavior: behaviorConfiguration,
existingRealmFileBehavior: behaviorConfiguration,
},
};
const realm = await Realm.open(config);
const behaviorConfiguration: Realm.OpenRealmBehaviorConfiguration = {
type: "openImmediately",
};
const config: Realm.Configuration = {
schema: [Car],
sync: {
user: await getUser(),
flexible: true,
newRealmFileBehavior: behaviorConfiguration,
existingRealmFileBehavior: behaviorConfiguration,
},
};
const realm = await Realm.open(config);

If you want to sync data but you're in an environment where it's uncertain if the user has an Internet connection, specify a timeOut. This automatically opens the realm when either:

  • the timeout period elapses.

  • the realm has completely downloaded.

If the realm doesn't finish downloading before the timeout, the initial realm sync continues in the background.

const behaviorConfiguration = {
type: "openImmediately",
timeOut: 1000,
timeOutBehavior: "openLocalRealm",
};
const config = {
schema: [Car],
sync: {
flexible: true,
user: await getUser(),
existingRealmFileBehavior: behaviorConfiguration,
newRealmFileBehavior: behaviorConfiguration,
},
};
const realm = await Realm.open(config);
const behaviorConfiguration: Realm.OpenRealmBehaviorConfiguration = {
type: "openImmediately",
timeOut: 1000,
timeOutBehavior: "openLocalRealm",
};
const config: Realm.Configuration = {
schema: [Car],
sync: {
flexible: true,
user: await getUser(),
existingRealmFileBehavior: behaviorConfiguration,
newRealmFileBehavior: behaviorConfiguration,
},
};
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 behaviorConfiguration = {
type: "openImmediately",
};
const behaviorConfiguration: Realm.OpenRealmBehaviorConfiguration = {
type: Realm.OpenRealmBehaviorType.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],
sync: {
user: app.currentUser,
partitionValue: "MyPartitionValue",
// The behavior to use when this is the first time opening a realm.
newRealmFileBehavior: behaviorConfiguration,
// The behavior to use when a realm file already exists locally,
// i.e. you have previously opened the realm.
existingRealmFileBehavior: behaviorConfiguration,
},
};
const config: Realm.Configuration = {
schema: [DogSchema],
sync: {
user: app.currentUser!,
partitionValue: "MyPartitionValue",
// The behavior to use when this is the first time opening a realm.
newRealmFileBehavior: behaviorConfiguration,
// The behavior to use when a realm file already exists locally,
// i.e. you have previously opened the realm.
existingRealmFileBehavior: behaviorConfiguration,
},
};

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

New in version 12.0.0.

You can specify a cancelWaitsOnNonFatalErrors property in your BaseSyncConfiguration object.

When true, the Node.js SDK cancels asynchronous operations, such as waiting for uploads or downloads, when a timeout period elapses. You can define the timeout for this option on the AppConfiguration. For an example, refer to Configure a Timeout for the App Client.

This property defaults to false if you do not specify a value.

const config = {
schema: [Doggie],
sync: {
flexible: true,
user: app.currentUser,
// When `true`, upload and download waits are canceled on any
// error, such as a timeout, instead of just a fatal error.
// You can provide an optional timeouts property in milliseconds.
cancelWaitsOnNonFatalError: true,
},
};
const config: Realm.Configuration = {
schema: [Doggie],
sync: {
flexible: true,
user: app.currentUser!,
// When `true`, upload and download waits are canceled on any
// error, such as a timeout, instead of just a fatal error.
// You can provide an optional timeouts property in milliseconds.
cancelWaitsOnNonFatalError: true,
},
};

Back

Sync Data