How to Use Realm in Flutter: A Complete Guide

Haris Bin Nasir Avatar

·

·

Realm is a mobile-first, high-performance database designed for real-time data applications. It is particularly useful in mobile apps because of its speed, offline-first capability, and ease of use. In this guide, we’ll show you how to use Realm in Flutter for local data persistence, including setup, CRUD operations (Create, Read, Update, Delete), and handling complex data relationships. We’ll also provide code examples to help you get started.

What is Realm, and Why Use It in Flutter?

Realm is a NoSQL database optimized for mobile devices that allows seamless data storage and real-time updates. Its key advantages include:

  • Speed: Realm is designed to be faster than traditional mobile databases like SQLite.
  • Offline-First: It stores data locally, allowing your app to work even when there’s no internet connection.
  • Real-Time Sync: Realm offers real-time synchronization (in the paid version) that can sync data between devices.
  • Zero Boilerplate: Realm manages schema and handles data relationships natively, so you don’t need to write complex SQL queries or schema migrations.

By integrating Realm into your Flutter app, you get a powerful tool to handle your local data efficiently, especially for apps that need fast, reliable offline-first support.

Setting Up Realm in Flutter

Before diving into Realm features, let’s go through the setup process.

Step 1: Add Realm Dependencies

To get the dependency click here and add Realm to your Flutter project by updating your pubspec.yaml file:

dependencies:
  realm: ^20.0.0

Run flutter pub get to install the package.

Step 2: Import Realm

After adding the dependencies, import the Realm package into your Dart file:

import 'package:realm/realm.dart';

Now, let’s define a Realm schema to structure our data.

Defining a Realm Schema

In Realm, you work with Dart classes that represent your data models. You annotate these classes to define how they should be stored in the database.

Example: Defining a Model Class

Let’s define a Task model, where each task has an id, title, and a completed status:

import 'package:realm/realm.dart';

// Define a Task model class
class Task extends RealmObject {
  @PrimaryKey()
  late String id;  // Realm automatically handles unique IDs

  late String title;
  late bool completed;

  Task(this.id, this.title, this.completed);
}

Explanation:

  • @PrimaryKey(): This annotation marks id as the primary key, ensuring each task has a unique identifier.
  • RealmObject: This is the base class for all Realm model classes. It tells Realm to manage this class as a database object.

Step 3: Open a Realm Instance

Before you can interact with the database, you need to open a Realm instance. Here’s how you can do that:

void main() {
  final config = Configuration([Task.schema]);  // Pass schema to configuration
  final realm = Realm(config);  // Open a Realm instance

  runApp(MyApp(realm: realm));
}

In this example, Task.schema is the schema that defines the structure of the data you’ll store. Once the Realm instance is open, you can start working with the data.

Performing CRUD Operations with Realm in Flutter

Now that we have Realm set up, let’s walk through how to perform CRUD (Create, Read, Update, Delete) operations on the data.

1. Creating Data (Inserting)

To add new objects to the database, use the write() method. Here’s how you can create and insert a new task:

void addTask(Realm realm, String title) {
  realm.write(() {
    realm.add(Task(ObjectId().toString(), title, false));  // Create a new task
  });
}

Explanation:

  • realm.write(): All database modifications must be wrapped in a write transaction.
  • realm.add(): Adds a new object to the database.
  • ObjectId().toString(): Generates a unique ID for the task.

2. Reading Data (Querying)

To read data from Realm, you can query the database directly by accessing the class type. Here’s how to retrieve all tasks:

List<Task> getAllTasks(Realm realm) {
  return realm.all<Task>().toList();  // Get all Task objects from the database
}

You can also filter tasks using queries:

List<Task> getCompletedTasks(Realm realm) {
  return realm.query<Task>('completed == true').toList();  // Filter completed tasks
}

Explanation:

  • realm.all<Task>(): Retrieves all objects of type Task from the database.
  • realm.query(): Allows you to filter objects using a query. In this case, we’re filtering for tasks where completed == true.

3. Updating Data

To update data, retrieve the object and modify its fields inside a write transaction:

void markTaskAsCompleted(Realm realm, Task task) {
  realm.write(() {
    task.completed = true;  // Update the task's status
  });
}

Explanation:

  • Modifying an object’s fields within a realm.write() block automatically updates the object in the database.

4. Deleting Data

To remove data from Realm, use the delete() method inside a write transaction:

void deleteTask(Realm realm, Task task) {
  realm.write(() {
    realm.delete(task);  // Delete the task from the database
  });
}

This removes the specified task from the database.

Working with Relationships

Realm also supports complex data relationships like one-to-many or many-to-many. Here’s an example of a one-to-many relationship where a Project contains multiple Task objects.

Example: Defining a One-to-Many Relationship

class Project extends RealmObject {
  @PrimaryKey()
  late String id;

  late String name;
  late List<Task> tasks = [];  // A list of related tasks

  Project(this.id, this.name);
}

To add tasks to a project:

void addTaskToProject(Realm realm, Project project, String taskTitle) {
  realm.write(() {
    final task = Task(ObjectId().toString(), taskTitle, false);
    project.tasks.add(task);  // Add task to the project's task list
    realm.add(task);  // Add task to the Realm database
  });
}

With Realm, managing relationships is simple since it treats relationships as part of the object model.

Reactive Data with Realm

One of the standout features of Realm is its ability to provide real-time data updates. You can listen for changes in the data and update the UI accordingly.

Example: Listening for Data Changes

RealmResults<Task> tasks = realm.all<Task>();

StreamBuilder(
  stream: tasks.changes,
  builder: (context, snapshot) {
    if (snapshot.connectionState == ConnectionState.waiting) {
      return CircularProgressIndicator();
    }

    final tasks = snapshot.data.results;
    return ListView.builder(
      itemCount: tasks.length,
      itemBuilder: (context, index) {
        final task = tasks[index];
        return ListTile(
          title: Text(task.title),
          trailing: Icon(
            task.completed ? Icons.check_box : Icons.check_box_outline_blank,
          ),
        );
      },
    );
  },
);

In this example, we use RealmResults<Task>() to get a list of tasks and listen for changes using a StreamBuilder. Whenever data is updated, the UI is automatically refreshed.

Saving and Syncing Data with Realm

If you’re using the paid version of Realm, you can also enable real-time syncing across devices. This allows your app to sync local data with the cloud, ensuring consistency across multiple devices.

Example: Sync Configuration

void main() async {
  final config = Configuration.flexibleSync([Task.schema], user: myRealmUser);
  final realm = await Realm.open(config);

  runApp(MyApp(realm: realm));
}

With this setup, any changes made to the Realm database will automatically sync across all devices that are connected to the same account.

Conclusion

Realm is a powerful database solution for Flutter, offering high performance, real-time data handling, and ease of use. From basic CRUD operations to handling complex data relationships, Realm simplifies data persistence in mobile applications. Its ability to work offline and sync data in real-time makes it an excellent choice for mobile-first applications that require seamless local storage and fast performance.

By following this guide, you should be able to integrate Realm into your Flutter projects with ease and start building robust, offline-first apps.

Happy Coding…!!!

Leave a Reply

Your email address will not be published. Required fields are marked *