Build offline-first mobile application using MongoDB Realm Sync in React Native

Lakshman Kambam
8 min readMay 20, 2021

What are offline-first Applications?

“If you’re not familiar with the term “Offline First”, it refers to applications designed to work without an internet connection. While these applications might make network requests when available, they can still operate when the internet is disconnected or flaky.”

All you need to know about Realm:

Realm’s mobile database is an open source, developer-friendly alternative to CoreData and SQLite. Start in minutes, port your app in hours, and save yourself weeks of work.

MongoDB acquired Realm, an open-source database geared for mobile applications, for $39 million. The startup had raised just over $40 million before being acquired on June 2020.

Realm has more than 100,000 developers using its product, with 350 companies using its data synchronisation tools to move data between mobile devices and the cloud, using the Realm Platform, according to the company.

MongoDB Realm:

MongoDB and Realm are fully committed to investing in the Realm Database and the future of data synchronisation, and taking both to the next phase of their evolution

MongoDB Realm enables sync between Realm Database and MongoDB Atlas, seamlessly stitching together the two components into an application layer for your mobile app.

MongoDB Atlas provides cloud-hosted managed instances of MongoDB are always available.

1. Realm Users & Authentication

  • it has built-in user mgt with easy integration into third-party authentication providers.
  • like Facebook, Google, and Apple.

2. Realm Functions

  • You can call pre defined Realm Functions from a module of the Realm SDK in your client application.
  • Like endpoints in a REST API

3. Realm Triggers

  • Automatically execute a function at a scheduled time or when an event occurs.

4. Realm Rules

  • Access data based on roles managed by you.

5. Supports GraphQL API to access data.

MongoDB Realm calculates usage based on the data you sync and the requests your application makes.

You’ll only pay for what you need. (Sync hours with requests).

MongoDB Limits and Thresholds

Service Limitations

Note: focusing more on functionality. Keeping it very simple about creating MongoDB Realm UI Steps which are easy. i’ve mentioned official docs links below for all get started steps.

  1. Create a Realm App (Realm UI)
  2. MongoDB Realm React Native SDK

In this tutorial, you’re going to learn how to build MongoDB Realm Sync Online or Offline in React Native.

This tutorial will cover every step in detail and include code snippets for each. you’ll work through this tutorial by creating a new react-native demo project.

It support Realm Sync with offline means stores data in local and will sync once online. Sync configuration need to be switched based on network connectivity status.

Note: demo app supports offline sync, Open & Close a Local Realm — React Native SDK. To open a local (non-synced) realm, pass a Realm.Configuration object to Realm.open().

I’ve created working example of Books CRUD demo app (MongoDB Realm Sync with online). please follow below steps to make your demo app.

Let’s get started with MongoDB Realm, React Native SDK for TypeScript and JavaScript.

Step 1: Create a React Native Project and Package.json Setup

react-native init MyRealmApp

Next, Install required packages for this project

npm install --save packageName
  • bson — to generate mongodb like ObjectId().
  • prop-types — you can use prop-types to document the intended types of properties passed to components.
  • react-native-get-random-values — to avoid Error: crypto.getRandomValues() not supported in react native.
  • react-native-vector-icons — customizable icons for UI.
  • realm — realm react native SDK. (Installation Guide in Step 3)

Step 2: Folder Structure and Clean up

Next, you need to create a folder structure as shown in the screenshot below:

You need to clean up App.js file as shown below:

Step 3: Realm Configuration & Define Object Model Schema

Install Realm with npm

npm install --save realm

Resolve CocoaPods Dependencies

For the iOS app, fetch the CocoaPods dependencies with the following commands from your React Native project directory:

cd ios && pod install && cd ..

Inside databasedirectory, create files as shown in screenshot below:

I’ve created custom method to generate MongoDB like ObjectId but i never used it. so nvm ObjectId.js

RealmConfig.js will look like this:

As i mentioned earlier, please refer to MongoDB Realm documentation to Create a Realm App (Realm UI)

Note: Replace RealmAppId and partitionValue with yours.

Now that you have created the realm app instance and configuration, the next step is to define your object model for the data that you’re planning to sync.

Define Your Object Model

If have not enabled Realm Sync or you enabled Sync with development mode in the Realm UI, you can define your object model directly in code.

Inside schemasdirectory, create BookSchema as shown in screenshot below:

BookSchema.jswill look like as shown in the snippet below:

you can define BookSchema.js in RealmConfig.js configuration like this

const configuration = {
schema: [BookSchema], // add multiple schemas, comma seperated.
sync: {
user: app.currentUser, // loggedIn User
partitionValue: "2F6092d4c594587f582ef165a0" //singleUserId
}
};

Partitioning helps you turn the large amount of data stored by your application into the small amount of data needed by individual clients, called realms.

Client applications only need the data relevant to the current user. Most users only have permission to access a limited subset of the data in a linked cluster. Some data, like user settings and personal information, are only relevant to a single user.

Know more about PartitionValue Partition Atlas Data into Realms.

Step 4: Authenticate a User & Open a Realm once Enabled Realm Sync

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

Note: Potential use cases for anonymous authentication include, Allowing end users to try the features of an application before registering for an account.

Authentication Providers

Realm provides many additional ways to authenticate, register, and link users. Example: Email/Password, Apple, Google, Facebook etc.,

Checkout the list of the Authentication Providers available in Realm.

Now, we login as anonymous for demo purpose. we’ve already created an anonymous credential in RealmConfig.js

Once we’ve have enabled Realm Sync and authenticated a user, you can open a synced realm:

Now that we’ve understood realm instance and configuration. we’ll get right into Realm Open.

Open a Synced Realm

To open a synced realm, call Realm.open(). Pass in a Configuration object, which must include the sync property defining a SyncConfiguration object.

Realm.open(configuration);

In the following example, a synced realm is opened with a schema value of a predefined BookSchema SyncConfiguration object that uses the currently logged in user and a partition value of 2f6092d4c594587f582ef1

if you add partitionKey as realm_id from BookSchema it will sync all books data that match realm_id=6092d4c594587f582ef1

JSON Schema

Unlike regular Realm objects, which map to their own MongoDB collection, embedded objects map to embedded documents in the parent type’s document schema:

Document Schema Configuration

Documents in MongoDB are objects stored in a format called BSON, a binary-encoded superset of JSON that supports additional data types. The root of every document schema in Realm is a BSON Object schema that applies to each document in a collection.

{  
"bsonType": "object",
"title": "<Type Name>",
"required": ["<Required Field Name>", ...],
"properties": {
"<Field Name>": <Schema Document>
}
}

Book Document Schema Screenshot

Now that you have opened a realm,

In the next step, you will learn to modify it and its objects in a write transaction block.

Step 5: Create, Read, Update, and Delete Book Document Objects

To create a new Book run the method “realm.create()” inside the “realm.write()” callback. Pass the string “Book” as the first parameter to “realm.create()”. Pass a book data object as the second parameter.

I’ve created few UI Screens for CRUD operations to make it understandable, a bit better.

I made a basic demo BookStore app UI Screen Flow.

Bookshelves in the shape of human brain. Source: istockphoto

BookStore UI Screen Components in demo project folder structure as shown in screenshot below:

Create or Update a Book

Now, Just import getRealm realm config method from RealmConfig.js

import getRealm from './database';

Create Book transaction code block example:

Update/modify a book, update its properties in a write transaction. similar to create but the only difference is that you need to pass 3rd argument as string “modified” like below:

realm.create('Book', editingBookObj, 'modified');

here, it checks if data object already exists with given _id of book that you’re trying to edit.

Read/Get Books, you can retrieve a live collection of all books in the realm:

"Book" is a collection name.

realm.objects("Book");

You can also filter that collection using a filter:

const books = realm.objects("Book");let filteredBooks = books.filtered("category = 'Science');

Delete a Book, from the realm with realm.delete

“objectForPrimaryKey” — Searches for a Realm object by its primary key.

you’ve reached end of this tutorial on building offline-first mobile application using MongoDB Realm Sync in React Native.

We have our final output:

The complete demo source code for this tutorial is available in the Github Repository. Check it!

also, you can raise an issue if you’re stuck.

Happy Coding!

--

--