Bundle a Realm - Flutter SDK
On this page
You might want to seed your mobile app with some initial data that will be available to users on the initial launch of the app. To do this, you can bundle an existing realm file in your Flutter app.
If your app uses a synced realm, you may not want to bundle it. For more information, refer to the Bundle a Synced Realm section.
Tip
Consider Initial Data Callback
You can also add data to your realm the first time an application opens it using the initial data callback function.
Bundle a Local Realm
Create a Realm File for Bundling
Create a new project with the same Realm object schema as your production app. Open an existing realm with the data you wish to bundle, or create a new one.
Get the path to the realm file with the Realm.config.path property.
print("Bundling realm"); final config = Configuration.local([Car.schema], path: 'bundle.realm'); final realm = Realm(config); realm.write(() { realm.add(Car(ObjectId(), "Audi", model: 'A8')); realm.add(Car(ObjectId(), "Mercedes", model: 'G Wagon')); }); print("Bundled realm location: " + realm.config.path); realm.close();
Tip
Create Bundled Realm with Dart Standalone SDK
You might want to use the Dart Standalone SDK to create the bundled realm for your Flutter application for the following reasons:
Creating a bundled realm does not require any Flutter UI elements.
Dart standalone projects require less boilerplate code than Flutter projects
Bundle a Realm File in Your Production Application
Now that you have a copy of the realm with the "seed" data in it, you need to bundle it with your production application.
Add the realm file to your application's Flutter assets.
For example you could add the bundled realm in your project at the location
assets/bundled.realm
.
Add a reference to the bundled realm to your pubspec.yaml
file
to include it in your production application:
flutter: assets: - realm/bundle.realm
Open a Realm from a Bundled Realm File
Now that you have a copy of the realm included with your app, you need to add code to use it.
Before you deploy your app with the bundled realm, you need to extract the realm from the embedded resources, save it to the app's data location, and then open this new realm in the app. The following code shows how you can do this during start-up of the app.
Create a helper function initBundledRealm
to check if the bundled realm
already exists within the app, and load it into the app if it does not exist yet.
Call initBundledRealm
before calling loading the app's widgets with
runApp().
// Also import Realm schema and Flutter widgets import 'package:flutter/services.dart'; import 'package:realm/realm.dart'; import 'dart:io'; Future<Realm> initBundledRealm(String assetKey) async { final config = Configuration.local([Car.schema]); final file = File(config.path); if (!await file.exists()) { final realmBytes = await rootBundle.load(assetKey); await file.writeAsBytes( realmBytes.buffer .asUint8List(realmBytes.offsetInBytes, realmBytes.lengthInBytes), mode: FileMode.write); } return Realm(config); } void main() async { WidgetsFlutterBinding.ensureInitialized(); final realm = await initBundledRealm("assets/bundle.realm"); runApp(const MyApp()); }
Bundle a Synced Realm
In most cases, you should not bundle a synced realm. If the bundled realm was last updated further in the past than client maximum offline time, the user experiences a client reset the first time they open the bundled realm file. The client reset causes the application to download the full state of the realm from the application backend. This negates the advantages of bundling a realm file.
Rather than bundling a synced realm, you can populate your application with data using sync subscriptions. If you add data using sync subscriptions, you do not need to be concerned with data being older than the client maximum online time while taking advantage of Flexible Sync's trimming feature. To learn more about using sync subscriptions, refer to Manage Sync Subscriptions.
You should only bundle a synced realm if your use case meets the following criteria:
You can ensure that the users have a version of the app with the bundled synced realm that was created more recently than the client maximum offline time.
The initial bundled data is very large and the app is being used in a situation with limited internet bandwidth, so an initial data download using sync subscriptions would take too long.
All app users have backend permission to view the data included in the bundle. If a user doesn't have permission to view this data, it will be removed from their device when the realm sync with Atlas via a compensating write error.
To bundle a synced realm, perform the following:
Connect to your App Services App and authenticate a user.
Add a subscription to the realm. You need a subscription to write to a synced realm.
Add data to the synced realm.
Wait for all local changes to synchronize with the Device Sync server.
Use Realm.writeCopy() to create a new version of the synced realm. You must use
Realm.writeCopy()
to bundle the synced realm because the method removes metadata that associates the realm with the user, which allows other users to open the realm file as well.
print("Bundling synced realm"); // You must connect to the Device Sync server with an authenticated // user to work with the synced realm. final app = App(AppConfiguration(APP_ID)); // Check if current user exists and log anonymous user if not. final user = app.currentUser ?? await app.logIn(Credentials.anonymous()); final config = Configuration.flexibleSync(user, [Car.schema]); final realm = Realm(config); // Add subscription that match the data being added // and your app's backend permissions. realm.subscriptions.update((mutableSubscriptions) { mutableSubscriptions.add(realm.all<Car>()); }); await realm.subscriptions.waitForSynchronization(); // Add data to realm realm.write(() { realm.add(Car(ObjectId(), "Audi", model: 'A8')); realm.add(Car(ObjectId(), "Mercedes", model: 'G Wagon')); }); // Sync changes with the server await realm.syncSession.waitForUpload(); await realm.syncSession.waitForDownload(); // Create new configuration for the bundled realm. // You must specify a path separate from the realm you // are copying for Realm.writeCopy() to succeed. final bundledConfig = Configuration.flexibleSync(user, [Car.schema], path: 'sync_bundle.realm'); realm.writeCopy(bundledConfig); print("Bundled realm location: " + bundledConfig.path); realm.close();
After you create the bundled realm, follow the instructions from the above sections Bundle a Realm File in Your Production Application and Open a Realm from a Bundled Realm File.