Docs Menu
Docs Home
/ /
Atlas Device SDKs
/ /

Open a Synced Realm - Flutter SDK

On this page

  • Before You Begin
  • Open a Synced Realm
  • Open a Realm After Downloading Changes
  • Configure a Realm
  • Close a Realm
  • Further Reading

This page describes how to open a synced realm using Device Sync. To learn how to open and configure non-synced realms, see Open and Close a Realm.

Before you open a realm with Flexible Sync in a Flutter application:

  1. Configure 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.

To open a synced realm, pass a logged in user, a list of Realm object schemas, and additional optional named arguments to the Configuration.flexibleSync() constructor. This constructor returns a FlexibleSyncConfiguration. Then, pass the FlexibleSyncConfiguration to Realm() to open an instance of the realm. Data syncs with App Services in the background after you open the realm.

final currentUser = await app.logIn(credentials);
final config = Configuration.flexibleSync(currentUser, [Tricycle.schema],
path: 'flex.realm');
final realm = Realm(config);

Once you open a synced realm, configure and manage the sync subscriptions.

To sync all data with App Services when you open a realm, use the asynchronous method Realm.open(). The operation syncs all available data before returning the realm.

On first open, Realm.open() downloads all data that matches your sync subscriptions. Subsequent opens only download the latest changes. Depending on initial realm size and updates to the data set while the device is not syncing, performance may be slower on first open and faster on subsequent opens.

If the client application is offline, Realm.open() does not resolve. You should check if the device is connected to the internet before using Realm.open(). If the device is not connected to the internet, you can still use Realm() to open a realm immediately and sync data in the background when an internet connection is available.

// Helper function to check if device is connected to the internet.
Future<bool> isDeviceOnline() async {
// ...logic to check if device is online
}
final config = Configuration.flexibleSync(currentUser, [Tricycle.schema]);
// Only use asynchronous open if app is online.
late Realm realm;
if (await isDeviceOnline()) {
// If the device is online, download changes and then open the realm.
realm = await Realm.open(config);
} else {
// If the device is offline, open the realm immediately
// and automatically sync changes in the background when the device is online.
realm = Realm(config);
}

To track the state of the synchronization, pass a ProgressCallback to the optional named argument onProgressCallback.

double progressEstimate = -1;
final realm = await Realm.open(config, onProgressCallback: (syncProgress) {
progressEstimate = syncProgress.progressEstimate;
print('Sync progress: ${progressEstimate * 100}% complete.');
if (progressEstimate == 1.0) {
// Transfer is complete
}
});

Tip

If you want to configure progress notifications after opening a realm, use SyncSession.getProgressStream.

To be able to cancel a synchronization in progress, pass a CancellationToken instance to the optional named argument cancellationToken. Call CancellationToken.cancel() to cancel the synchronization.

final token = CancellationToken();
// Cancel the open operation after 30 seconds.
// Alternatively, you could display a loading dialog and bind the cancellation
// to a button the user can click to stop the wait.
Future<void>.delayed(
const Duration(seconds: 30),
() => token.cancel(CancelledException(
cancellationReason: "Realm took too long to open")));
// If realm does not open after 30 seconds with asynchronous Realm.open(),
// open realm immediately with Realm() and try to sync data in the background.
late Realm realm;
try {
realm = await Realm.open(config, cancellationToken: token);
} on CancelledException catch (err) {
print(err.cancellationReason); // prints "Realm took too long to open"
realm = Realm(config);
}

Example

Realm() vs. Realm.open()

This section compares examples of scenarios when you might want to use Realm() versus Realm.open() to open a realm in an application.

Consider an app that allows users to record and save their favorite recipes. You might want to give the user the option to create a new recipe without waiting to download updates, or even if they're offline. In this case, Realm() is preferable. The user can operate offline, but the app syncs their recipes when they next have a network connection.

Consider an game app with a tablet and phone version. A user plays the game on both a table and a phone. The user progresses three levels on the tablet. Later, the user opens the game on a phone. In this case, Realm.open() is a better way to open the realm. Since Realm.open() synchronizes data before returning the realm, it makes sure that the user's progress is synced on the phone before they start using the app, even if the initial load time may be slower.

For more information on general realm configuration options, refer to Configure a Realm.

To handle errors in your synced realm using additional configuration properties, refer to Handle Sync Errors.

Once you've finished working with a synced realm, close it to prevent memory leaks.

realm.close();
  • Manage Sync Subscriptions: Learn how to add, modify, and remove sync subscriptions once you've opened a synced realm.

  • Manage Sync Session: Learn how to manage the state of the sync session, including pausing and resuming syncing, monitoring upload and download progress, and checking the network connection.

  • Sync Data from Multiple Processes: Learn how to sync data from multiple processes with a single realm.

Back

Add Sync to an App

Next

Manage Subscriptions