Docs Menu

Docs HomeRealm

Quick Start - Flutter SDK

On this page

  • Define Your Object Model
  • Create Data Model
  • Generate RealmObject Class
  • Open a Realm
  • Work with Realm Objects
  • Create Objects
  • Update Objects
  • Query for Objects
  • Delete Objects
  • React to Changes
  • Close a Realm
  • Sync Realm with MongoDB Atlas
  • Prerequisites
  • Initialize App Services
  • Authenticate a User
  • Open a Synced Realm
  • Add a Sync Subscription
  • Further Examples and Next Steps

This page contains information to quickly get Realm Database integrated into your Flutter app.

Before you begin, ensure you have:

Your application's data model defines the structure of data stored within Realm Database. You can define your application's data model via Dart classes in your application code with a Realm object schema. You then have to generate the RealmObject class that's used within your application.

Tip

See also: Further Reading

To define your application's data model, add a Realm model class definition to your application code.

Some considerations when defining your Realm model class:

  • Import package at the top of your class definition file.

  • In your file, give your class a private name (starting with _), such as a file car.dart with a class _Car. You generate the public RealmObject class using the command in the following Generate RealmObject Class section. This command outputs a public class, such as Car.

  • Make sure to include the generated file name, such as part car.g.dart, before the code defining your model. This is required to generate the RealmObject class.

Now generate a RealmObject class Car from the data model class Car:

Running this creates a Car class in a car.g.dart file located in the directory where you defined the model class per the preceding Create Data Model section. This Car class is public and part of the same library as the _Car data model class. The generated Car class is what's used throughout your application.

If you'd like to watch your data model class to generate a new Car class whenever there's a change to _Car, run:

Use the Configuration class to control the specifics of the realm you would like to open, including schema and whether the realm is local-only or synced.

Pass your configuration to the Realm constructor to generate an instance of that realm:

var config = Configuration.local([Car.schema]);
var realm = Realm(config);

You can now use that realm instance to work with objects in the database.

Tip

See also: Further Reading

Once you've opened a realm, you can create objects within it using a write transaction block.

Tip

See also: Further Reading

To create a new Car, instantiate an instance of the Car class and add it to the realm in a write transaction block:

final car = Car('Tesla', model: 'Model S', miles: 42);
realm.write(() {
realm.add(car);
});

To modify a car, update its properties in a write transaction block:

realm.write(() {
car.miles = 99;
});

Retrieve a collection of all objects of a data model in the realm with the Realm.all() method:

var cars = realm.all<Car>();
var myCar = cars[0];
print('My car is ${myCar.make} ${myCar.model}');

Filter a collection to retrieve a specific segment of objects with the Realm.query() method. In the query() method's argument, use Realm Query Language operators to perform filtering.

var cars = realm.all<Car>().query('make == "Tesla"');

Sort the results using the Realm Query Language SORT() operator in the query() method's argument.

realm.write(() {
realm.add(Car('BMW', model: 'Z4', miles: 42));
realm.add(Car('Audi', model: 'A8', miles: 99));
realm.add(Car('Mercedes', model: 'G-Wagon', miles: 2));
});
final sortedCars = realm.query<Car>('TRUEPREDICATE SORT(model ASC)');
for (var car in sortedCars) {
print(car.model);
}
// prints 'A8', 'G-Wagon', 'Z4'

Delete a car by calling the Realm.delete() method in a write transaction block:

realm.write(() {
realm.delete(car);
});

Delete multiple cars with the Realm.deleteMany() method in a write transaction block.

realm.write(() {
realm.deleteMany(cars);
});

Listen and respond to changes to a query, a single object, or a list within an object. The change listener is a Stream that invokes a callback function with an containing changes since last invocation as its argument.

To listen to a query, use RealmResults.changes.listen().

// Listen for changes on whole collection
final characters = realm.all<Character>();
final subscription = characters.changes.listen((changes) {
changes.inserted; // indexes of inserted objects
changes.modified; // indexes of modified objects
changes.deleted; // indexes of deleted objects
changes.newModified; // indexes of modified objects
// after deletions and insertions are accounted for
changes.moved; // indexes of moved objects
changes.results; // the full List of objects
});
// Listen for changes on RealmResults
final hobbits = fellowshipOfTheRing.members.query('species == "Hobbit"');
final hobbitsSubscription = hobbits.changes.listen((changes) {
// ... all the same data as above
});

To listen to a single Realm object, use RealmObject.changes.listen().

final frodoSubscription = frodo.changes.listen((changes) {
changes.isDeleted; // if the object has been deleted
changes.object; // the RealmObject being listened to, `frodo`
changes.properties; // the changed properties
});

To listen to a list of Realm objects within another Realm object, use RealmList.changes.listen().

final fellowshipSubscription =
fellowshipOfTheRing.members.changes.listen((changes) {
changes.inserted; // indexes of inserted Realm objects
changes.modified; // indexes of modified Realm objects
changes.deleted; // indexes of deleted Realm objects
changes.newModified; // indexes of modified Realm objects
// after deletions and insertions are accounted for
changes.moved; // indexes of moved Realm objects
changes.list; // the full RealmList of Realm objects
});

You can pause and resume subscriptions as well.

subscription.pause();
// the changes.listen() method won't fire until the subscription is resumed
subscription.resume();

Once you've finished listening to changes, close the change listener to prevent memory leaks.

await subscription.cancel();

Tip

See also: Further Reading

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

realm.close();

You can integrate Realm Database and Atlas Device Sync into your Flutter app. Atlas Device Sync is an MongoDB Atlas App Service that synchronizes data between a client application and a MongoDB database cluster on Atlas.

To synchronize data with Atlas using Device Sync, the Flutter SDK uses Flexible Sync. Flexible Sync lets you define a query for the data that you synchronize from the client app.

Note

You do not need to add Device Sync to use Realm Database locally.

Before you can use Device Sync with Realm in your client app, you must configure Device Sync using Atlas App Services:

  1. Create an App Services App

  2. Enable Anonymous Authentication

  3. Enable Flexible Sync. Include the following Flexible Sync configuration:

    • Set owner_id as a queryable field.

    • Add the following backend permissions to have the user only be able to read and write their own data:

    {
    "rules": {},
    "defaultRoles": [
    {
    "name": "owner-read-write",
    "applyWhen": {},
    "read": {
    "owner_id": "%%user.id"
    },
    "write": {
    "owner_id": "%%user.id"
    }
    }
    ]
    }

Tip

Use Realm Flutter Template App

If you want a working Flutter app with Device Sync already set up in the client and on that App Service backend, use the Flutter Template App flutter.todo.flex.

To use App Services features such as authentication and sync, you must access your App Services App using your App ID. You can find your App ID in the App Services UI.

App app = App(AppConfiguration(APP_ID));

For more information, refer to Connect to App Services.

After you have enabled anonymous authentication in the App Services UI, users can immediately log into your app without providing any identifying information:

User loggedInUser = await app.logIn(Credentials.anonymous());

For more information, refer to Authenticate a User.

Once you have enabled Device Sync and authenticated a user, open a synced realm with Configuration.flexibleSync(). Then, pass the configuration to Realm() to open an instance of the realm. The synced realm must hav a different Configuration.path from other opened local-only realms.

Configuration config =
Configuration.flexibleSync(loggedInUser, [Todo.schema]);
Realm realm = Realm(
config,
);

For more information, refer to Open a Synced Realm.

Now create a subscription to synchronize data with Atlas using Device Sync. Add the subscription within the SubscriptionSet.update() callback function.

The update block callback function, includes a MutableSubscriptionSet() object as an argument. Use MutableSubscriptionSet.add() to add a new subscription.

// Check if the subscription already exists before adding
final userTodoSub = realm.subscriptions.findByName('getUserTodos');
if (userTodoSub == null) {
realm.subscriptions.update((mutableSubscriptions) {
// server-side rules ensure user only downloads their own Todos
mutableSubscriptions.add(realm.all<Todo>(), name: 'getUserTodos');
});
}

For more information, refer to Manage Sync Session.

  • To get started with a pre-made Flutter application using the Realm SDK and an Atlas App Services backend set up, use the Flutter template app, flutter.todo.flex.

  • For a guided experience of adding the Realm SDK with Device Sync to a Flutter app, read the Realm Flutter SDK Tutorial.

  • For further examples of the Flutter SDK methods described above and more, refer to the Realm Dart Samples Github repo.

←  Install Realm - Flutter SDKRealm Database Overview - Flutter SDK →
Give Feedback
© 2022 MongoDB, Inc.

About

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