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 integrated into your Flutter app.
Before you begin, ensure you have:
Define Your Object Model
Your application's data model defines the structure of data stored within Realm. 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 RealmObjectBase class that's used within your application.
For more information, refer to Define a Realm Object Schema.
Create Data Model
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 filecar.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 asCar
.Make sure to include the generated file name, such as
part car.realm.dart
, before the code defining your model. This is required to generate the RealmObject class.
import 'package:realm/realm.dart'; part 'car.realm.dart'; ()class _Car { () late ObjectId id; late String make; late String? model; late int? miles; }
import 'package:realm_dart/realm.dart'; part 'car.realm.dart'; ()class _Car { () late ObjectId id; late String make; late String? model; late int? miles; }
Generate RealmObject Class
Now generate a RealmObject class Car
from the data model class Car
:
dart run realm generate
dart run realm_dart generate
Running this creates a Car
class in a car.realm.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:
dart run realm generate --watch
dart run realm_dart generate --watch
Open a Realm
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:
final config = Configuration.local([Car.schema]); final realm = Realm(config);
You can now use that realm instance to work with objects in the database.
For more information, refer to Configure and Open a Realm.
Work with Realm Objects
Once you've opened a realm, you can create objects within it using a write transaction block.
For more information, refer to Write Transactions.
Create Objects
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(ObjectId(), 'Tesla', model: 'Model S', miles: 42); realm.write(() { realm.add(car); });
Update Objects
To modify a car, update its properties in a write transaction block:
realm.write(() { car.miles = 99; });
Query for Objects
Retrieve a collection of all objects of a data model in the realm with the Realm.all() method:
final cars = realm.all<Car>(); final 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.
final cars = realm.query<Car>('make == "Tesla"');
Delete Objects
Delete a car by calling the Realm.delete() method in a write transaction block:
realm.write(() { realm.delete(car); });
React to Changes
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 accounting for deletions & insertions. changes.moved; // Indexes of moved objects. changes.results; // The full List of objects. changes.isCleared; // `true` after call to characters.clear(); otherwise, `false`. }); // Listen for changes on RealmResults. final hobbits = fellowshipOfTheRing.members.query('species == "Hobbit"'); final hobbitsSubscription = hobbits.changes.listen((changes) { // ... all the same data as above });
You can pause and resume subscriptions as well.
subscription.pause(); // The changes.listen() method won't fire until subscription is resumed. subscription.resume();
Once you've finished listening to changes, close the change listener to prevent memory leaks.
await subscription.cancel();
For more information, refer to React to Changes.
Close a Realm
Once you've finished working with a realm, close it to prevent memory leaks.
realm.close();
Sync Realm with MongoDB Atlas
You can integrate Realm 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 locally.
Prerequisites
Before you can use Device Sync with Realm in your client app, you must configure Device Sync using Atlas App Services:
Enable Flexible Sync. Set
owner_id
as a queryable field.Define the rules that determine which permissions users have when using Device Sync. For this example, we assign a default role, which applies to any collection that does not have a collection-specific role. In this example, a user can read and write data where the
user.id
of the logged-in user matches theowner_id
of the object:{ "roles": [ { "name": "owner-read-write", "apply_when": {}, "document_filters": { "write": { "owner_id": "%%user.id" }, "read": { "owner_id": "%%user.id" } }, "read": true, "write": true, "insert": true, "delete": true, "search": true } ] }
Now, deploy your application updates.
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
.
Initialize App Services
To use App Services features such as authentication and sync, access your App Services App using your App ID. You can find your App ID in the App Services UI.
final app = App(AppConfiguration(appId));
For more information, refer to Connect to App Services.
Authenticate a User
After you have enabled anonymous authentication in the App Services UI, users can immediately log into your app without providing any identifying information:
final loggedInUser = await app.logIn(Credentials.anonymous());
For more information, refer to Authenticate a User.
Open a Synced Realm
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 have a different Configuration.path from other opened local-only realms.
final config = Configuration.flexibleSync(loggedInUser, [Todo.schema]); final realm = Realm( config, );
For more information, refer to Open a Synced Realm.
Add a Sync Subscription
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 Subscriptions.
Further Examples and Next Steps
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.