Docs Menu

Manage a Sync Session - Flutter SDK

On this page

  • Before You Begin
  • Manage Your Subscriptions
  • Get Subscriptions
  • Add a Query to the Set of Subscriptions
  • Update Subscriptions with a New Query
  • Remove Subscriptions
  • Wait for Subscription Changes to Sync

Atlas Device Sync with Flexible Sync uses subscriptions and permissions to determine which data to sync between MongoDB Atlas and your app.

You can add, update, and remove query subscriptions to determine which data syncs to the client device.

Note
Flexible Sync Prerequisites

Enabling Flexible Sync in Your Realm Application requires a non-sharded MongoDB Atlas cluster running MongoDB 5.0 or greater

To use Flexible Sync in a Flutter application:

  1. Configure Flexible Sync on the Atlas App Services backend
  2. Initialize the app client
  3. Authenticate a user in the client
  4. Open the synced realm in the client

When configuring Flexible Sync on the backend, you specify which fields your client application can query. In the client application, use the Realm.subscriptions property to manage a set of subscriptions to specific queries on queryable fields.

You can:

  • Get a list of all subscriptions
  • Add subscriptions
  • Check subscription state
  • Update a subscription with a new query
  • Remove subscriptions

When the data matches the subscription, and the authenticated user has the appropriate permissions, Atlas Device Sync syncs the backend data with the client app.

You can specify a string name for your subscription. If you do not give your subscription a name, the name is set to null.

When you create a subscription, Realm looks for data matching a query on a specific object type. In your Flexible Sync subscriptions, you can have subscriptions on several different object types or several queries on the same object type.

When using Flexible Sync, you can access a SubscriptionSet, a collection of subscriptions, through the Realm.subscriptions property.

You can use this subscriptions set to add queries to this list of subscriptions and update existing subscriptions, as shown in the examples below.

SubscriptionSet subscriptions = realm.subscriptions;

You must perform all mutations on the subscriptions set within an update block. To create an update block, call SubscriptionSet.update().

The update block callback function, includes a MutableSubscriptionSet() object as an argument. You can modify your method on the SubscriptionSet to add a query to the subscription.

Important

Flexible Sync does not support all the operators available in Realm Query Language. See Flexible Sync RQL Limitations for details.

The MutableSubscriptionSet.add() method takes three arguments:

  • RealmResults query: Required. A RealmResults object that you can create using the Realm Query Language query.
  • String name: Optional. Name for the subscription that you can refer to.
  • bool update: Optional. When true, adding a subscription with an existing name replaces the existing query with the new query. Only use with named subscriptions.
Note
Duplicate Subscriptions

If you add a duplicate unnamed subscription with the same query, Realm automatically removes it; adding an identical named subscription is a no-op. Therefore, in both cases, duplicate subscriptions are ignored.

You can add a single query, or batch multiple queries within a SubscriptionSet.update block. Performing query updates is an expensive operation on the server. We strongly advise designing your application to minimize subscription updates. You can do this by creating all subscriptions in a single update block the first time the user launches the app and batching any follow-up changes to the subscription set.

In the example below, we subscribe to two queries.

final planeQuery = realm.all<Plane>();
final longTrainQuery = realm.query<Train>("numCars >= 5");
realm.subscriptions.update((MutableSubscriptionSet mutableSubscriptions) {
mutableSubscriptions.add(planeQuery, name: "planes");
mutableSubscriptions.add(longTrainQuery,
name: 'long-trains', update: true);
});
await realm.subscriptions.waitForSynchronization();

You can update a named subscription with a new query. To update a subscription's query, open an update block with SubscriptionSet.update(). In the callback function of the update block, pass the following arguments to MutableSubscriptionSet.add():

  • The new query
  • The name of the subscription that you want to update
  • update: true

You cannot update an unnamed subscription. Alternatively, you can delete the unnamed subscription, and create a new subscription with the desired query.

In the following example, long trains are re-defined to be any trains that have more than 10 cars.

final longerTrainQuery = realm.query<Train>("numCars > 10");
realm.subscriptions.update((MutableSubscriptionSet mutableSubscriptions) {
mutableSubscriptions.add(longerTrainQuery,
name: 'long-trains', update: true);
});

To remove subscriptions from the subscription set, you can:

  • Remove a single subscription with the given query
  • Remove a single subscription with the given name
  • Remove a single subscription with the subscription reference
  • Remove all subscriptions

When you remove a subscription query, the server also removes synced data from the client device.

Within an update block, you can remove a specific subscription by query. Open an update block with SubscriptionSet.update(). Pass the Subscription to MutableSubscriptionSet.removeByQuery().

In the following example, the subscription for all Plane objects is removed.

realm.subscriptions.update((MutableSubscriptionSet mutableSubscriptions) {
mutableSubscriptions.removeByQuery(realm.all<Plane>());
});

Within an update block, you can remove a specific subscription by name. Pass the name to MutableSubscriptionSet.removeByName()

realm.subscriptions.update((MutableSubscriptionSet mutableSubscriptions) {
mutableSubscriptions.removeByName('long-trains');
});

You can remove a subscription if you have a reference to its Subscription object. Within a subscription update block, pass the Subscription reference to MutableSubscriptionSet.remove().

Subscription sub = realm.subscriptions[0];
realm.subscriptions.update((MutableSubscriptionSet mutableSubscriptions) {
mutableSubscriptions.remove(sub);
});

Within a subscription update block, you can remove all unnamed subscriptions from the subscriptions set with MutableSubscriptionSet.clear().

realm.subscriptions.update((MutableSubscriptionSet mutableSubscriptions) {
mutableSubscriptions.clear();
});

Mutating the subscription set within an update block is only one part of changing a subscription. After the local subscription change, the realm synchronizes with the server to resolve any updates to the data due to the subscription change. This includes adding or removing data from the synced realm.

Use Realm.subscriptions.waitForSynchronization() to wait for the server to acknowledge this set of subscriptions. If the server rejects the change, and an exception is thrown.

An exception may occur if:

  • You subscribe to an unsupported query. Subscribing to an unsupported query will pause synchronization. To resume synchronization, remove the unsupported query.
  • You are performing an invalid action, such as adding an object that does not match a subscription. This triggers a client reset: data is erased from the realm, and a new copy of the data is created without any subscriptions in the set.
await realm.subscriptions.waitForSynchronization();
←  Open a Synced Realm - Flutter SDKRealm Java SDK →
Give Feedback
© 2022 MongoDB, Inc.

About

  • Careers
  • Investor Relations
  • Legal Notices
  • Privacy Notices
  • Security Information
  • Trust Center
© 2022 MongoDB, Inc.