Javascript required
Skip to content Skip to sidebar Skip to footer

Realm React Native Causing Ui to Act Funny

Introduction

Realm JavaScript enables you to efficiently write your app's model layer in a safe, persisted and fast way. It's designed to work with React Native and Node.js.

Here's a quick example:

                          const              Realm              =              require              (              '              realm              '              );              // Define your models and their properties              const              CarSchema              =              {              name              :              '              Car              '              ,              properties              :              {              make              :              '              string              '              ,              model              :              '              string              '              ,              miles              :              {              type              :              '              int              '              ,              default              :              0              },              }              };              const              PersonSchema              =              {              name              :              '              Person              '              ,              properties              :              {              name              :              '              string              '              ,              birthday              :              '              date              '              ,              cars              :              '              Car[]              '              ,              picture              :              '              data?              '              // optional property              }              };              Realm              .              open              ({              schema              :              [              CarSchema              ,              PersonSchema              ]})              .              then              (              realm              =>              {              // Create Realm objects and write to local storage              realm              .              write              (()              =>              {              const              myCar              =              realm              .              create              (              '              Car              '              ,              {              make              :              '              Honda              '              ,              model              :              '              Civic              '              ,              miles              :              1000              ,              });              myCar              .              miles              +=              20              ;              // Update a property value              });              // Query Realm for all cars with a high mileage              const              cars              =              realm              .              objects              (              '              Car              '              ).              filtered              (              '              miles > 1000              '              );              // Will return a Results object with our 1 car              cars              .              length              // => 1              // Add another car              realm              .              write              (()              =>              {              const              myCar              =              realm              .              create              (              '              Car              '              ,              {              make              :              '              Ford              '              ,              model              :              '              Focus              '              ,              miles              :              2000              ,              });              });              // Query results are updated in realtime              cars              .              length              // => 2              });                      

Note that if you are going to use Realm for server-side/node, there is additional information to be found in the Realm Object Server documentation.

Getting Started

Installation

Follow the installation instructions below to install Realm JavaScript via npm, or see the source on GitHub.

Prerequisites

  • Make sure your environment is set up to run React Native applications. Follow the React Native instructions for getting started.
  • Apps using Realm can target both iOS and Android.
  • React Native 0.31.0 and later is supported.

Installation

  • Create a new React Native project:

                        react-native init <project-name>                  
  • Change directories into the new project (cd <project-name>) and add the realm dependency:

  • Next, link your project to the realm native module.

Warning for Android: Depending on the version, react-native link may generate an invalid configuration, updating Gradle correctly (android/settings.gradle and android/app/build.gradle) but failing to add the Realm module. Confirm that react-native link has added the Realm module; if it has not, link manually to the library with the following steps:

  1. Add the following lines to android/settings.gradle:

                                              include                      ':realm'                      project                      (                      ':realm'                      ).                      projectDir                      =                      new                      File                      (                      rootProject                      .                      projectDir                      ,                      '../node_modules/realm/android'                      )                                      
  2. Add the compile line to the dependencies in android/app/build.gradle:

                                              dependencies                      {                      compile                      project                      (                      ':realm'                      )                      }                                      
  3. Add the import and link the package in MainApplication.java:

                                              import                      io.realm.react.RealmReactPackage                      ;                      // add this import                      public                      class                      MainApplication                      extends                      Application                      implements                      ReactApplication                      {                      @Override                      protected                      List                      <                      ReactPackage                      >                      getPackages                      ()                      {                      return                      Arrays                      .<                      ReactPackage                      >                      asList                      (                      new                      MainReactPackage                      (),                      new                      RealmReactPackage                      ()                      // add this line                      );                      }                      }                                      

You're now ready to go. To see Realm in action, replace the definition of class <project-name> with the following in index.ios.js or index.android.js:

                                  const                  Realm                  =                  require                  (                  '                  realm                  '                  );                  class                  <                  project                  -                  name                  >                  extends Component                  {                  constructor                  (                  props                  )                  {                  super                  (                  props                  );                  this                  .                  state                  =                  {                  realm                  :                  null                  };                  }                  componentWillMount                  ()                  {                  Realm                  .                  open                  ({                  schema                  :                  [{                  name                  :                  '                  Dog                  '                  ,                  properties                  :                  {                  name                  :                  '                  string                  '                  }}]                  }).                  then                  (                  realm                  =>                  {                  realm                  .                  write                  (()                  =>                  {                  realm                  .                  create                  (                  '                  Dog                  '                  ,                  {                  name                  :                  '                  Rex                  '                  });                  });                  this                  .                  setState                  ({                  realm                  });                  });                  }                  render                  ()                  {                  const                  info                  =                  this                  .                  state                  .                  realm                  ?                  '                  Number of dogs in this Realm:                                    '                  +                  this                  .                  state                  .                  realm                  .                  objects                  (                  '                  Dog                  '                  ).                  length                  :                  '                  Loading...                  '                  ;                  return                  (                  <                  View                  style=                  {                  styles                  .                  container                  }                  >                  <                  Text                  style=                  {                  styles                  .                  welcome                  }                  >                  {                  info                  }                  </                  Text                  >                  </                  View                  >                  );                  }                  }                              

You can then run your app on a device and in a simulator.

These instructions install the Developer Edition of the Realm Node.js SDK. If you have downloaded the Professional Edition or Enterprise Edition, follow the installation instructions you received in email.

To install Realm Node.js, simply use the Node Package Manager:

To use the SDK, require('realm') in your application.

                                  var                  Realm                  =                  require                  (                  '                  realm                  '                  );                              

Examples

Examples can be found on GitHub in the realm-js repository.

Note that on Android, you need the NDK installed and must have set the ANDROID_NDK environment variable.

            export ANDROID_NDK=/usr/local/Cellar/android-ndk/r10e          

Realm Studio

Realm Studio is our premiere developer tool, built so you can easily manage the Realm Database and Realm Platform. With Realm Studio, you can open and edit local and synced Realms, and administer any Realm Object Server instance. It supports Mac, Windows and Linux.

Realm Studio

Getting Help

  • Need help with your code? Ask on StackOverflow. We actively monitor & answer questions on SO!
  • Have a bug to report? Open an issue on our repo. If possible, include the version of Realm, a full log, the Realm file, and a project that shows the issue.
  • Have a feature request? Open an issue on our repo. Tell us what the feature should do, and why you want the feature.

If you're using a crash reporter (like Crashlytics or HockeyApp), make sure to enable log collection. Realm logs metadata information (but no user data) when throwing exceptions and in irrecoverable situations, and these messages can help debug when things go wrong.

Models

Realm data models are defined by the schema information passed into a Realm during initialization. The schema for an object consists of the object's name and a set of properties. Each property has a name and is described by either a string containing the property's type, or an object with name, type, objectType, optional, default, and indexed fields.

                          const              Realm              =              require              (              '              realm              '              );              const              CarSchema              =              {              name              :              '              Car              '              ,              properties              :              {              make              :              '              string              '              ,              model              :              '              string              '              ,              miles              :              {              type              :              '              int              '              ,              default              :              0              },              }              };              const              PersonSchema              =              {              name              :              '              Person              '              ,              properties              :              {              name              :              '              string              '              ,              birthday              :              '              date              '              ,              cars              :              '              Car[]              '              picture              :              '              data?              '              ,              // optional property              }              };              // Initialize a Realm with Car and Person models              Realm              .              open              ({              schema              :              [              CarSchema              ,              PersonSchema              ]})              .              then              (              realm              =>              {              // ... use the realm instance to read and modify data              })                      

Classes

At this point, support for defining models via classes is limited. It works in React Native but not in Node.

If you want to use ES2015 classes (and maybe want to inherit existing features), you just need to define the schema on the constructor:

                          class              Person              {              get              fullName              ()              {              return              this              .              firstName              +              '                                          '              +              this              .              lastName              ;              }              }              Person              .              schema              =              {              name              :              '              Person              '              ,              properties              :              {              firstName              :              '              string              '              ,              lastName              :              '              string              '              }              };                      

You can now pass the class itself to the schema property of the open configuration:

                          Realm              .              open              ({              schema              :              [              Person              ]})              .              then              (              /* ... */              );                      

You access properties as always:

                          realm              .              write              (()              =>              {              const              john              =              realm              .              create              (              '              Person              '              ,              {              firstName              :              '              John              '              ,              lastName              :              '              Smith              '              });              john              .              lastName              =              '              Peterson              '              ;              console              .              log              (              john              .              fullName              );              // -> 'John Peterson'              });                      

Supported types

Realm supports the following basic types: bool, int, float, double, string, data, and date.

  • bool properties map to JavaScript boolean values
  • int, float, and double properties map to JavaScript number values. Internally 'int' and 'double' are stored as 64 bits while float is stored with 32 bits.
  • string properties map to string
  • data properties map to ArrayBuffer
  • date properties map to Date

When specifying basic properties as a shorthand you may specify only the type rather than having to specify a dictionary with a single entry:

                          const              CarSchema              =              {              name              :              '              Car              '              ,              properties              :              {              // The following property types are equivalent              make              :              {              type              :              '              string              '              },              model              :              '              string              '              ,              }              }                      

Optional Properties

By default, basic types are non-optional and do not support storing null or undefined. Properties can be made optional by specifying the optional designator in your property definition, or with the shorthand syntax, by appending a ? to the type name:

                          const              PersonSchema              =              {              name              :              '              Person              '              ,              properties              :              {              realName              :              '              string              '              ,              // required property              displayName              :              '              string?              '              ,              // optional property              birthday              :              {              type              :              '              date              '              ,              optional              :              true              },              // optional property              }              };              let              realm              =              new              Realm              ({              schema              :              [              PersonSchema              ,              CarSchema              ]});              realm              .              write              (()              =>              {              // optional properties can be set to null or undefined at creation              let              charlie              =              realm              .              create              (              '              Person              '              ,              {              realName              :              '              Charlie              '              ,              displayName              :              null              ,              // could also be omitted entirely              birthday              :              new              Date              (              1995              ,              11              ,              25              ),              });              // optional properties can be set to `null`, `undefined`,              // or to a new non-null value              charlie              .              birthday              =              undefined              ;              charlie              .              displayName              =              '              Charles              '              ;              // Setting a non-optional property to null will throw `TypeError`              // charlie.realName = null;              });                      

List Properties

In addition to storing individual values, properties can also be declared as a list of any of the supported basic types. This is done by appending [] to the type name:

                          const              PersonSchema              =              {              name              :              '              Person              '              ,              properties              :              {              name              :              '              string              '              ,              testScores              :              '              double?[]              '              }              };              let              realm              =              new              Realm              ({              schema              :              [              PersonSchema              ,              CarSchema              ]});              realm              .              write              (()              =>              {              let              charlie              =              realm              .              create              (              '              Person              '              ,              {              name              :              '              Charlie              '              ,              testScores              :              [              100.0              ]              });              // Charlie had an excused absense for the second test and was allowed to skip it              charlie              .              testScores              .              push              (              null              );              // And then he didn't do so well on the third test              charlie              .              testScores              .              push              (              70.0              );              });                      

When accessing list properties a List object is returned. List has methods very similar to a regular JavaScript array. The big difference is that any changes made to a List are automatically persisted to the underlying Realm, and as such they can only be modified in write transactions. Additionally, Lists belong to the underlying object they were acquired from - you can only get List instances by accessing a property from an owning object and they cannot be manually created.

While the values in a list property can be made optional, the list property itself cannot be. Specifying a list property as optional using the longhand syntax (values: {type: 'int[]', optional: true}) will make the values within the list optional.

Relationships

To-One Relationships

For to-one relationships you specify the name property of the object schema you are referencing as the property's type:

                          const              PersonSchema              =              {              name              :              '              Person              '              ,              properties              :              {              // The following property definitions are equivalent              car              :              {              type              :              '              Car              '              },              van              :              '              Car              '              ,              }              };                      

When using object properties you need to make sure all referenced types are present in the schema used to open the Realm:

                          // CarSchema is needed since PersonSchema contains properties of type 'Car'              Realm              .              open              ({              schema              :              [              CarSchema              ,              PersonSchema              ]})              .              then              (              /* ... */              );                      

When accessing object properties, you can access nested properties using normal property syntax:

                          realm              .              write              (()              =>              {              const              nameString              =              person              .              car              .              name              ;              person              .              car              .              miles              =              1100              ;              // create a new Car by setting the property to an object              // with all of the required fields              person              .              van              =              {              make              :              '              Ford              '              ,              model              :              '              Transit              '              };              // set both properties to the same car instance              person              .              car              =              person              .              van              ;              });                      

Object properties in Realm are always optional, do not have to be explicitly specified as such, and cannot be made required.

To-Many Relationships

Just as with basic properties, you can also have a list of objects to form a to-many relationship. This is done by either appending [] to the name of the target object schema, or by setting the property type to list and specifying the objectType:

                          const              PersonSchema              =              {              name              :              '              Person              '              ,              properties              :              {              // The following property definitions are equivalent              cars              :              {              type              :              '              list              '              ,              objectType              :              '              Car              '              },              vans              :              '              Car[]              '              }              }              let              carList              =              person              .              cars              ;              // Add new cars to the list              realm              .              write              (()              =>              {              carList              .              push              ({              make              :              '              Honda              '              ,              model              :              '              Accord              '              ,              miles              :              100              });              carList              .              push              ({              make              :              '              Toyota              '              ,              model              :              '              Prius              '              ,              miles              :              200              });              });              let              secondCar              =              carList              [              1              ].              model              ;              // access using an array index                      

Unlike other lists and to-one relationships, to-many relationships cannot be made optional.

Inverse Relationships

Links are unidirectional. So if a to-many property Person.dogs links to Dog instances and a to-one property Dog.owner links to Person, these links are independent from one another. Appending a Dog to a Person instance's dogs property doesn't automatically set the dog's owner property to this Person. Because manually synchronizing pairs of relationships is error prone, complex and duplicates information, Realm provides linking objects properties to represent these inverse relationships.

With linking objects properties, you can obtain all objects that link to a given object from a specific property. For example, a Dog object can have a property named owners that contains all of the Person objects that have this exact Dog object in their dogs property. This is done by making the owners property of type linkingObjects and then specifying the relationship that it has with the Person object.

                          const              PersonSchema              =              {              name              :              '              Person              '              ,              properties              :              {              dogs              :              '              Dog[]              '              }              }              const              DogSchema              =              {              name              :              '              Dog              '              ,              properties              :              {              // No shorthand syntax for linkingObjects properties              owners              :              {              type              :              '              linkingObjects              '              ,              objectType              :              '              Person              '              ,              property              :              '              dogs              '              }              }              }                      

A linkingObjects property can point either to a List property (to-many relationship) or an Object property (to-one relationship):

                          const              ShipSchema              =              {              name              :              '              Ship              '              ,              properties              :              {              captain              :              '              Captain              '              }              }              const              CaptainSchema              =              {              name              :              '              Captain              '              ,              properties              :              {              ships              :              {              type              :              '              linkingObjects              '              ,              objectType              :              '              Ship              '              ,              property              :              '              captain              '              }              }              }                      

When accessing linkingObjects properties, a Results object is returned, so further querying and sorting are fully supported. linkingObject properties belong to the object they were acquired from and can not be set or manipulated directly. They are updated automatically when a transaction is committed.

Accessing linkingObjects without a schema: if you have opened a Realm file without specifying a schema, e.g. in a Realm Functions callback, you can get a linkingObjects property by calling linkingObjects(objectType, property) on an Object instance:

                          let              captain              =              realm              .              objectForPrimaryKey              (              '              Captain              '              ,              1              );              let              ships              =              captain              .              linkingObjects              (              '              Ship              '              ,              '              captain              '              );                      

Linking objects properties cannot be made optional.

Default Property Values

Default property values can be specified by setting the default designator in the property definition. To use a default value, leave the property unspecified during object creation.

                          const              CarSchema              =              {              name              :              '              Car              '              ,              properties              :              {              make              :              {              type              :              '              string              '              },              model              :              {              type              :              '              string              '              },              drive              :              {              type              :              '              string              '              ,              default              :              '              fwd              '              },              miles              :              {              type              :              '              int              '              ,              default              :              0              }              }              };              realm              .              write              (()              =>              {              // Since `miles` is left out it defaults to `0`, and since              // `drive` is specified, it overrides the default value              realm              .              create              (              '              Car              '              ,              {              make              :              '              Honda              '              ,              model              :              '              Accord              '              ,              drive              :              '              awd              '              });              });                      

Indexed Properties

You can add an indexed designator to a property definition to cause that property to be indexed. This is supported for int, string, bool, and date property types:

                          var              BookSchema              =              {              name              :              '              Book              '              ,              properties              :              {              name              :              {              type              :              '              string              '              ,              indexed              :              true              },              price              :              '              float              '              }              };                      

Indexing a property will greatly speed up queries where the property is compared for equality at the cost of slower insertions.

Primary Keys

You can specify the primaryKey property in an object model for string and int properties. Declaring a primary key allows objects to be looked up and updated efficiently and enforces uniqueness for each value. Once an object with a primary key has been added to a Realm the primary key cannot be changed.

                          const              BookSchema              =              {              name              :              '              Book              '              ,              primaryKey              :              '              id              '              ,              properties              :              {              id              :              '              int              '              ,              // primary key              title              :              '              string              '              ,              price              :              '              float              '              }              };                      

Primary key properties are automatically indexed.

Writes

Changes to objects in a Realm—creating, updating and deleting—must take place within a write() transaction block. Note that write transactions have a non-negligible overhead; you should try to minimize the number of write blocks within your code.

Creating Objects

Objects are created using the create method:

                          try              {              realm              .              write              (()              =>              {              realm              .              create              (              '              Car              '              ,              {              make              :              '              Honda              '              ,              model              :              '              Accord              '              ,              drive              :              '              awd              '              });              });              }              catch              (              e              )              {              console              .              log              (              "              Error on creation              "              );              }                      

Note that any exceptions thrown in write() will cancel the transaction. The try/catch block won't be shown in all examples, but it's good practice.

Nested Objects

If an object has object properties, values for those properties can be created recursively by specifying JSON values for each child property:

                          realm              .              write              (()              =>              {              realm              .              create              (              '              Person              '              ,              {              name              :              '              Joe              '              ,              // nested objects are created recursively              car              :              {              make              :              '              Honda              '              ,              model              :              '              Accord              '              ,              drive              :              '              awd              '              },              });              });                      

Updating Objects

Typed Updates

You can update any object by setting its properties within a write transaction.

                          realm              .              write              (()              =>              {              car              .              miles              =              1100              ;              });                      

Creating and Updating Objects With Primary Keys

If your model class includes a primary key, you can have Realm intelligently update or add objects based off of their primary key values. This is done by passing true as the third argument to the create method:

                          realm              .              write              (()              =>              {              // Create a book object              realm              .              create              (              '              Book              '              ,              {              id              :              1              ,              title              :              '              Recipes              '              ,              price              :              35              });              // Update book with new price keyed off the id              realm              .              create              (              '              Book              '              ,              {              id              :              1              ,              price              :              55              },              true              );              });                      

In the example above, since an object already exists with the id value of 1 and we have passed in true for the third argument, the price property is updated rather than trying to create a new object. Since the title property is omitted the object retains the original value for this property. Note that when creating or updating objects with primary key properties the primary key must be specified.

Deleting Objects

Objects can be deleted by calling the delete method within a write transaction.

                          realm              .              write              (()              =>              {              // Create a book object              let              book              =              realm              .              create              (              '              Book              '              ,              {              id              :              1              ,              title              :              '              Recipes              '              ,              price              :              35              });              // Delete the book              realm              .              delete              (              book              );              // Delete multiple books by passing in a `Results`, `List`,              // or JavaScript `Array`              let              allBooks              =              realm              .              objects              (              '              Book              '              );              realm              .              delete              (              allBooks              );              // Deletes all books              });                      

Queries

Queries allow you to get objects of a single type from a Realm, with the option of filtering and sorting those results. All queries (including queries and property access) are lazy in Realm. Data is only read when objects and properties are accessed. This allows you to represent large sets of data in a performant way.

When performing queries you are returned a Results object. Results are simply a view of your data and are not mutable.

The most basic method for retrieving objects from a Realm is using the objects method on a Realm to get all objects of a given type:

                          let              dogs              =              realm              .              objects              (              '              Dog              '              );              // retrieves all Dogs from the Realm                      

Filtering

You can get a filtered Results by calling the filtered method on a List or a Results with a query string.

For example, the following would change our earlier example to retrieve all dogs with the color tan and names beginning with 'B':

                          let              dogs              =              realm              .              objects              (              '              Dog              '              );              let              tanDogs              =              dogs              .              filtered              (              '              color = "tan" AND name BEGINSWITH "B"              '              );                      

At the moment only a subset of the NSPredicate syntax is supported in the query language. Basic comparison operators ==, !=, >, >=, <, and <= are supported for numeric properties. ==, BEGINSWITH, ENDSWITH, and CONTAINS are supported for string properties. String comparisons can be made case insensitive by appending [c] to the operator: ==[c], BEGINSWITH[c] etc. Filtering by properties on linked or child objects can by done by specifying a keypath in the query eg car.color == 'blue'.

Currently only Lists of Realm Objects can be filtered. Filtering Lists of basic types will come in a future version.

Sorting

Results allows you to specify a sort criteria and order based on a single or multiple properties. For example, the following call sorts the returned cars from the example above numerically by miles:

                          let              hondas              =              realm              .              objects              (              '              Car              '              ).              filtered              (              '              make = "Honda"              '              );              // Sort Hondas by mileage              let              sortedHondas              =              hondas              .              sorted              (              '              miles              '              );              // Sort in descending order instead              sortedHondas              =              hondas              .              sorted              (              '              miles              '              ,              true              );              // Sort by price in descending order and then miles in ascending              sortedHondas              =              hondas              .              sorted              ([              '              price              '              ,              true              ],              [              '              miles              '              ]);                      

Results can also be sorted on the values of objects linked to by the objects you're sorting:

                          let              people              =              realm              .              objects              (              '              Person              '              );              // Sort people by the milage of their cars              let              sortedPeople              =              people              .              sorted              (              '              car.miles              '              );                      

Lists of basic types can be sorted by their values by calling sorted() without specifying a property:

                          let              person              =              realm              .              objects              (              '              Person              '              )[              0              ];              let              sortedTestScores              =              person              .              testScores              .              sorted              ();                      

Note that the order of Results is only guaranteed to stay consistent when the query is sorted. For performance reasons, insertion order is not guaranteed to be preserved.

Auto-Updating Results

Results instances are live, auto-updating views into the underlying data, which means results never have to be re-fetched. Modifying objects that affect the query will be reflected in the results immediately. The one exception to this is when using for...in or for...of, which will always iterate over the objects which matched the query when the iteration is started, even if some of them are deleted or modified to be excluded by the filter during the iteration.

                          let              hondas              =              realm              .              objects              (              '              Car              '              ).              filtered              (              '              make = "Honda"              '              );              // hondas.length == 0              realm              .              write              (()              =>              {              realm              .              create              (              '              Car              '              ,              {              make              :              '              Honda              '              ,              model              :              '              RSX              '              });              });              // hondas.length == 1                      

This applies to all Results instances, included those returned by the objects, filtered, and sorted methods.

This property of Results not only keeps Realm fast and efficient, it allows your code to be simpler and more reactive. For example, if your view relies on the results of a query, you can store the Results in a property and access it without having to make sure to refresh its data prior to each access.

You can subscribe to notifications to know when Realm data is updated, indicating when your app's UI should be refreshed for example, without having to re-fetch your Results.

Limiting Results

Most other database technologies provide the ability to 'paginate' results from queries (such as the 'LIMIT' keyword in SQLite). This is often done out of necessity to avoid reading too much from disk, or pulling too many results into memory at once.

Since queries in Realm are lazy, performing this sort of paginating behavior isn't necessary at all, as Realm will only load objects from the results of the query once they are explicitly accessed.

If for UI-related or other implementation reasons you require a specific subset of objects from a query, it's as simple as taking the Results object, and reading out only the objects you need.

                          let              cars              =              realm              .              objects              (              '              Car              '              );              // get first 5 Car objects              let              firstCars              =              cars              .              slice              (              0              ,              5              );                      

Realms

Opening Realms

Opening a Realm is simply performed by calling the static open method on the Realm class. Pass a configuration object. We've seen this used already in examples with a configuration object that includes the schema key:

                          // Get the default Realm with support for our objects              Realm              .              open              ({              schema              :              [              Car              ,              Person              ]})              .              then              (              realm              =>              {              // ...use the realm instance here              })              .              catch              (              error              =>              {              // Handle the error here if something went wrong              });                      

For full details about the configuration object, see the API Reference for configuration. Some of the more common keys for the object, beyond schema, include:

  • path: specify a path to another Realm
  • migration: a migration function
  • sync: a sync object, to open a Realm synchronized with the Realm Object Server
  • inMemory: the Realm will be opened in-memory, and objects are not persisted; once the last Realm instance is closed, all objects vanish

The Default Realm

You may have noticed in all previous examples that the path argument has been omitted. In this case the default Realm path is used. You can access and change the default Realm path using the Realm.defaultPath global property.

Other Realms

It's sometimes useful to have multiple Realms persisted at different locations. For example, you may want to bundle some data with your application in a Realm file, in addition to your main Realm. You can do this by specifying the path argument when initializing your realm. All paths are relative to the writable documents directory for your application:

                          // Open a realm at another path              Realm              .              open              ({              path              :              '              anotherRealm.realm              '              ,              schema              :              [              CarSchema              ]              }).              then              (              /* ... */              );                      

Schema Version

Another option available when opening a Realm is the schemaVersion property. When omitted, the schemaVersion property defaults to 0. You are required to specify the schemaVersion when initializing an existing Realm with a schema that contains objects that differ from their previous specification. If the schema was updated and the schemaVersion was not, an exception will be thrown.

                          const              PersonSchema              =              {              name              :              '              Person              '              ,              properties              :              {              name              :              '              string              '              }              };              // schemaVersion defaults to 0              Realm              .              open              ({              schema              :              [              PersonSchema              ]});                      

If you then later do something like this:

                          const              UpdatedPersonSchema              =              {              // The schema name is the same, so previous `Person` object              // in the Realm will be updated              name              :              '              Person              '              ,              properties              :              {              name              :              '              string              '              ,              dog              :              '              Dog              '              // new property              }              };              // this will throw because the schema has changed              // and `schemaVersion` is not specified              Realm              .              open              ({              schema              :              [              UpdatedPersonSchema              ]});              // this will succeed and update the Realm to the new schema              Realm              .              open              ({              schema              :              [              UpdatedPersonSchema              ],              schemaVersion              :              1              });                      

If you wish to retrieve the current schema version of a Realm, you may do so with the Realm.schemaVersion method.

                          const              currentVersion              =              Realm              .              schemaVersion              (              Realm              .              defaultPath              );                      

Synchronously Opening Realms

You can create a realm instance by simply invoking the constructor and passing a configuration object to it. This is typically not recommended as it blocks and could potentially be a time consuming operation, especially if there are migrations to run or if the realm is synchronized and you don't want to risk modifying data before it's been completely downloaded.

If you still want to do this, the pattern is simple:

                          const              realm              =              new              Realm              ({              schema              :              [              PersonSchema              ]});              // You can now access the realm instance.              realm              .              write              (              /* ... */              );                      

If a Realm has read-only permissions, then you must use the asynchronous api's to open it. Opening a read-only Realm with the above pattern will cause an error.

Migrations

When working with a database your data model will most likely change over time. For example, suppose we have the following Person model:

                          const              PersonSchema              =              {              name              :              '              Person              '              ,              properties              :              {              firstName              :              '              string              '              ,              lastName              :              '              string              '              ,              age              :              '              int              '              }              }                      

We want to update the data model to require a name property, rather than separate first and last names. To do this, we simply change the schema to the following:

                          const              PersonSchema              =              {              name              :              '              Person              '              ,              properties              :              {              name              :              '              string              '              ,              age              :              '              int              '              }              }                      

At this point if you had saved any data with the previous model version there will be a mismatch between the new code and the old data Realm has stored on disk. When this occurs, an exception will be thrown when you try to open the existing Realm with the new schema unless you run a migration.

Performing a Migration

You define a migration and the associated schema version by updating the schemaVersion and defining an optional migration function. Your migration function provides any logic needed to convert data models from previous schemas to the new schema. When opening a Realm the migration function will be applied to update the Realm to the given schema version only if a migration is needed.

If no migration function is supplied then any new properties an automatically added and old properties are removed from the database when updating to the new schemaVersion. If you need to update old or populate new properties when upgrading your version you can do this in the migration function. For example, suppose we want to migrate the Person model declared earlier. You can populate the name property of the new schema using the old firstName and lastName properties:

                          Realm              .              open              ({              schema              :              [              PersonSchema              ],              schemaVersion              :              1              ,              migration              :              (              oldRealm              ,              newRealm              )              =>              {              // only apply this change if upgrading to schemaVersion 1              if              (              oldRealm              .              schemaVersion              <              1              )              {              const              oldObjects              =              oldRealm              .              objects              (              '              Person              '              );              const              newObjects              =              newRealm              .              objects              (              '              Person              '              );              // loop through all objects and set the name property in the new schema              for              (              let              i              =              0              ;              i              <              oldObjects              .              length              ;              i              ++              )              {              newObjects              [              i              ].              name              =              oldObjects              [              i              ].              firstName              +              '                                          '              +              oldObjects              [              i              ].              lastName              ;              }              }              }              }).              then              (              realm              =>              {              const              fullName              =              realm              .              objects              (              '              Person              '              )[              0              ].              name              ;              });                      

Once the migration is successfully completed the Realm and all of its objects can be accessed as usual by your app.

Linear Migrations

With the migration pattern described above you can potentially run into issues when migrating over multiple versions. This could happen if a user skips an app update and a property has been changed multiple times in the versions being skipped. In this case you may need to edit old migration code to correctly update data from old schema to the latest schema.

It's possible to avoid this issue by running multiple migrations sequentially, making sure that the database is upgraded to each previous version and that the associated migration code is run. When following this pattern old migration code should never have to be modified, although you will need to keep all old schema and migration blocks for future use. An example of what this would look like:

                          const              schemas              =              [              {              schema              :              schema1              ,              schemaVersion              :              1              ,              migration              :              migrationFunction1              },              {              schema              :              schema2              ,              schemaVersion              :              2              ,              migration              :              migrationFunction2              },              ...              ]              // the first schema to update to is the current schema version              // since the first schema in our array is at              let              nextSchemaIndex              =              Realm              .              schemaVersion              (              Realm              .              defaultPath              );              while              (              nextSchemaIndex              <              schemas              .              length              )              {              const              migratedRealm              =              new              Realm              (              schemas              [              nextSchemaIndex              ++              ]);              migratedRealm              .              close              ();              }              // open the Realm with the latest schema              Realm              .              open              (              schemas              [              schemas              .              length              -              1              ]);                      

Notifications

The Realm, Results and List objects provide addListener methods to register notification callbacks. Whenever the object is updated, the change notification callback will be called.

There are two kinds of notifications, "Realm Notifications" (simple callbacks notified when write transactions are committed) and "Collection Notifications" (more sophisticated callbacks which receive change metadata on insertions, deletions and updates).

In addition, the Professional Edition and Enterprise Edition provide event handling notifications. Read "The Realm Platform" for more information.

In some cases the listener may be called when the transaction starts—if the Realm is advanced to the latest version, or Realm entities being observed were modified or deleted in a way that triggers notifications. In those cases, the listener runs within the context of the current write transaction, so an attempt to begin a new write transaction within the notification handler will throw an exception. You can use the Realm.isInTransaction property to determine if your code is executing within a write transaction.

Realm Notifications

Realm instances send out notifications to other instances every time a write transaction is committed. To register for notifications:

                          function              updateUI              ()              {              // ...              }              // Observe Realm Notifications              realm              .              addListener              (              '              change              '              ,              updateUI              );              // ..later remove the listener              realm              .              removeListener              (              '              change              '              ,              updateUI              );              // ..or unregister all listeners              realm              .              removeAllListeners              ();                      

Collection Notifications

Collection notifications contain information that describe what changes have occurred at a fine-grained level. This consists of the indices of objects that have been inserted, deleted, or modified since the last notification. Collection notifications are delivered asynchronously: first with the initial results, and then after any write transaction which modifies any of the objects in the collection, deletes objects from the collection, or adds new objects to the collection.

The notification callback function given to addListener receives two parameters when these changes occur. The first one is the collection that changed, and the second one is a changes object with information about the collection indices affected by deletions, insertions and modifications.

The former two, deletions and insertions, record the indices whenever objects start and stop being part of the collection. This takes into account when you add objects to the Realm or delete them from the Realm. For Results this also applies when you filter for specific values and the object was changed so that it is now matching the query or not matching anymore. For collections based on List, this applies when objects are added or removed from the relationship.

Your application is notified about modifications whenever a property of an object has changed, which was previously part of the collection and is still part of it. This happens as well when to-one and to-many relationships change, but doesn't take changes on inverse relationships into account.

                          class              Dog              {}              Dog              .              schema              =              {              name              :              '              Dog              '              ,              properties              :              {              name              :              '              string              '              ,              age              :              '              int              '              ,              }              };              class              Person              {}              Person              .              schema              =              {              name              :              '              Person              '              ,              properties              :              {              name              :              {              type              :              '              string              '              },              dogs              :              {              type              :              '              list              '              ,              objectType              :              '              Dog              '              },              }              };                      

Let's assume you're observing a list of dog owners as given by the model code above. You will be notified about modifications for a matched Person object when:

  • You modify the Person's name property.
  • You add or remove a Dog to the Person's dogs property.
  • You modify the age property of a Dog belonging to that Person.

This makes it possible to discretely control the animations and visual updates made to the content inside your UI, instead of arbitrarily reloading everything each time a notification occurs.

                          // Observe Collection Notifications              realm              .              objects              (              '              Dog              '              ).              filtered              (              '              age < 2              '              ).              addListener              ((              puppies              ,              changes              )              =>              {              // Update UI in response to inserted objects              changes              .              insertions              .              forEach              ((              index              )              =>              {              let              insertedDog              =              puppies              [              index              ];              ...              });              // Update UI in response to modified objects              changes              .              modifications              .              forEach              ((              index              )              =>              {              let              modifiedDog              =              puppies              [              index              ];              ...              });              // Update UI in response to deleted objects              changes              .              deletions              .              forEach              ((              index              )              =>              {              // Deleted objects cannot be accessed directly              // Support for accessing deleted objects coming soon...              ...              });              });              // Unregister all listeners              realm              .              removeAllListeners              ();                      

Sync

Sync for Node.js on Linux is a Professional Edition feature and is not available without a license.

If you are working with Node.js on Linux, you need to specify your license access token to enable the features here. Do this like so:

                          const              token              =              "              eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...              "              ;              // Unlock Professional Edition APIs              Realm              .              Sync              .              setFeatureToken              (              token              );                      

The Realm Platform extends the Realm Database across the network, enabling automatic synchronization of data across devices. In order to do this a new set of types and classes are provided that support these synchronized Realms; these new classes are additive to the existing Realm Mobile Database.

Users

The central object in the Realm Object Server is the Realm User (Realm.Sync.User) associated with a synchronized Realm. A User can be authenticated to a shared Realm via a username/password scheme, or through a number of third-party authentication methods.

Creating and logging in a user requires two things:

  • A URL of a Realm Object Server to connect to.
  • Credentials for an authentication mechanism that describes the user as appropriate for that mechanism (i.e., username/password, access key, etc).

Authentication

Authentication is used to establish the identity of users and log them in. Refer to our authentication documentation for a list of authentication providers supported by the Realm Mobile Platform.

The credential information for a given user can be created in one of several ways:

  • Providing a valid username/password combination
  • Providing a token obtained from a supported third-party authentication service
  • Providing a token and a custom authentication provider (see Custom Authentication)

The username and password authentication is entirely managed by the Realm Object Server, giving you full control over your application's user management. For other authentication methods, your application is responsible for logging into the external service and obtaining the authentication token.

Here are some examples of setting credentials with various providers.

Username/Password
                          Realm              .              Sync              .              User              .              login              (              '              http://my.realm-auth-server.com:9080              '              ,              '              username              '              ,              '              p@s$w0rd              '              ).              then              (              user              =>              {              // user is logged in              // do stuff ...              }).              catch              (              error              =>              {              // an auth error has occurred              });                      

Before a user can log in, the account must be created. You can either do that in advance on the server using the admin dashboard, or by calling register:

                          Realm              .              Sync              .              User              .              register              (              '              http://my.realm-auth-server.com:9080              '              ,              '              username              '              ,              '              p@s$w0rd              '              ,              (              error              ,              user              )              =>              {              /* ... */              });                      
Google
                          const              googleAccessToken              =              '              acc3ssT0ken...              '              ;              Realm              .              Sync              .              User              .              registerWithProvider              (              '              http://my.realm-auth-server.com:9080              '              ,              '              google              '              ,              googleAccessToken              ,              (              error              ,              user              )              =>              {              /* ... */              });                      
Facebook
                          const              fbAccessToken              =              '              acc3ssT0ken...              '              ;              Realm              .              Sync              .              User              .              registerWithProvider              (              '              http://my.realm-auth-server.com:9080              '              ,              '              facebook              '              ,              fbAccessToken              ,              (              error              ,              user              )              =>              {              /* ... */              });                      
Custom Auth
                          // The user token provided by your authentication server              const              accessToken              =              '              acc3ssT0ken...              '              ;              const              user              =              Realm              .              Sync              .              User              .              registerWithProvider              (              '              http://my.realm-auth-server.com:9080              '              ,              '              custom/fooauth              '              ,              accessToken              ,              (              error              ,              user              )              =>              {              /* ... */              }              );                      

Note: the JavaScript SDK does not currently allow you to send additional data. If you need to send more than a single token, please encode the additional data as JSON and pass it through the accessToken parameter, and decode this string on the server side.

Logging Out

Logging out of a synced Realm is simple:

When a user is logged out, the synchronization will stop. A logged out user can no longer open a synced Realm.

Working with Users

The sync server URL may contain the tilde character ("~") which will be transparently expanded to represent the user's unique identifier. This scheme easily allows you to write your app to cater to its individual users. The location on disk for shared Realms is managed by the framework, but can be overridden if desired.

                          Realm              .              Sync              .              User              .              login              (              /* ... */              ,              (              error              ,              user              )              =>              {              if              (              !              error              )              {              Realm              .              open              ({              sync              :              {              user              :              user              ,              url              :              '              realm://object-server-url:9080/~/my-realm              '              ,              },              schema              :              [              /* ... */              ]              }).              then              (              realm              =>              {              /* ... */              });              }              });                      

Realm.Sync.User.current can be used to obtain the currently logged in user. If no users have logged in or all have logged out, it will return undefined. If there are more than one logged in users, an error will be thrown.

                          const              user              =              Realm              .              Sync              .              User              .              current              ;                      

If there are likely to be multiple users logged in, you can get a collection of them by calling Realm.Sync.User.all. This will be empty if no users have logged in.

                          let              users              =              Realm              .              Sync              .              User              .              all              ;              for              (              const              key              in              users              )              {              const              user              =              users              [              key              ];              // do something with the user.              })                      

Opening a Synchronized Realm

You open a synchroized Realm the same say as you open any other Realm. The configuration can be extended with a sync property if you need to configure the synchronization. The optional properties of sync include:

  • error - a callback for error handling/reporting
  • validate_ssl - indicating if SSL certificates must be validated
  • ssl_trust_certificate_path - a path where to find trusted SSL certificates

The error handling is set up by registering a callback (error) as part of the configuration:

                          const              config              =              {              sync              :              {              user              :              userA              ,              url              :              realmUrl              ,              error              :              err              =>              console              .              log              (              err              )              },              schema              :              [{              name              :              '              Dog              '              ,              properties              :              {              name              :              '              string              '              }              }]              };              var              realm              =              new              Realm              (              config              );                      

Partially synchronized Realms

This feature is included as a tech preview. It is likely to change!

Instead of synchronized every object, it is possible to synchronize a subset. This partially synchronized Realm is based on a query, and your client will only receive the objects which fulfil the query. A simple example is:

                          const              config              =              {              sync              :              {              user              :              userA              ,              url              :              realmUrl              ,              partial              :              true              ,              // <-- this enables a partially synced Realm              },              schema              :              [{              name              :              '              Person              '              ,              properties              :              {              name              :              '              string              '              ,              age              :              '              int              '              }              }]              };              var              realm              =              new              Realm              (              config              );              var              partialResults              =              realm              .              subscribeToObjects              (              '              Integer              '              ,              '              age > 5              '              ).              then              ((              results              ,              error              )              =>              {              return              results              ;              });              // partialResults is updated with objects matching the query                      

You may modify objects within the results collection, and these changes will be synced up to the Realm Object Server. Note that conflicts may be resolved differently than if the writes had been made to a fully-synchronized copy of the Realm.

Working with a Synchronized Realm

Once you have opened a Realm using a URL to a Realm Object Server and a User object, you can interact with it as you would any other Realm in JavaScript.

                          realm              .              write              (()              =>              {              realm              .              create              (              '              MyObject              '              ,              jsonData              );              });              var              objects              =              realm              .              objects              (              '              MyObject              '              );                      

Sync Sessions

A synced Realm's connection to the Realm Object Server is represented by a Session object. Session objects can be retrieved by calling realm.syncSession.

The state of the underlying session can be retrieved using the state property. This can be used to check whether the session is active, not connected to the server, or in an error state.

Progress notifications

Session objects allow your app to monitor the status of a session's uploads to and downloads from the Realm Object Server by registering a progress notification callback on a session object by calling [realm.syncSession.addProgressNotification(direction, mode, callback)] or one of the asynchronous methods Realm.open and Realm.openAsync. (these methods support only a subset of the progress notifications modes)

Progress notification callbacks will be invoked periodically by the synchronization subsystem. As many callbacks as needed can be registered on a session object simultaneously. Callbacks can either be configured to report upload progress or download progress.

Each time a callback is called, it will receive the current number of bytes already transferred, as well as the total number of transferable bytes (defined as the number of bytes already transferred plus the number of bytes pending transfer).

To stop receiving progress notifications a callback can be unregistered using [realm.syncSession.removeProgressNotification(callback)]. Calling the function a second time with the same callback is ignored.

There are two progress notification modes for the progress notifications:

  • reportIndefinitely - the registration will stay active until the callback is unregistered and will always report the most up-to-date number of transferable bytes. This type of callback could be used to control a network indicator UI that, for example, changes color or appears only when uploads or downloads are actively taking place.
                          let              realm              =              new              Realm              (              config              );              const              progressCallback              =              (              transferred              ,              transferables              )              =>              {              if              (              transferred              <              transferables              )              {              // Show progress indicator              }              else              {              // Hide the progress indicator              }              };              realm              .              syncSession              .              addProgressNotification              (              '              upload              '              ,              '              reportIndefinitely              '              ,              progressCallback              );              // ...              realm              .              syncSession              .              removeProgressNotification              (              progressCallback              );                      
  • forCurrentlyOutstandingWork - the registration will capture the number of transferable bytes at the moment it is registered and always report progress relative to that value. Once the number of transferred bytes reaches or exceeds that initial value, the callback will be automatically unregistered. This type of progress notification could, for example, be used to control a progress bar that tracks the progress of an initial download of a synced Realm when a user signs in, letting them know how long it is before their local copy is up-to-date.
                          let              realm              =              new              Realm              (              config              );              const              progressCallback              =              (              transferred              ,              transferable              )              =>              {              const              progressPercentage              =              transferred              /              transferable              ;              };              realm              .              syncSession              .              addProgressNotification              (              '              download              '              ,              '              forCurrentlyOutstandingWork              '              ,              progressCallback              );              // ...              realm              .              syncSession              .              removeProgressNotification              (              progressCallback              );                      

The asynchronous methods Realm.open and Realm.openAsync for opening a Realm can also be used to register a callback for sync progress notifications. In this case only 'download' direction and 'forCurrentlyOutstandingWork' mode are supported. Additional callbacks can be registered after the initial open is completed by using the newly created Realm instance

                          Realm              .              open              (              config              )              .              progress              ((              transferred              ,              transferable              )              =>              {              // update UI              })              .              then              (              realm              =>              {              // use the Realm              })              .              catch              ((              e              )              =>              reject              (              e              ));              Realm              .              openAsync              (              config              ,              (              error              ,              realm              )              =>              {              // use the Realm or report an error              },              (              transferred              ,              transferable              )              =>              {              // update UI              },              );                      

Access Control

The Realm Mobile Platform provides flexible access control mechanisms to restrict which users are allowed to sync against which Realm files. This can be used, for example, to create collaborative apps where multiple users write to the same Realm. It can also be used to share data in a publisher/subscriber scenario where a single writing user shares data with many users with read permissions.

There are three permissions that control the access level of a given Realm for a User:

  • mayRead indicates that the user is allowed to read from the Realm.
  • mayWrite indicates that the user is allowed to write to the Realm.
  • mayManage indicates that the user is allowed to change the permissions for the Realm.

Unless permissions are explicitly modified, only the owner (creator) of a Realm can access it. The only exception is admin users: They are always granted all permissions to all Realms on the server.

Write-only permissions (i.e., mayWrite set without mayRead) are not currently supported.

Please refer to the general Realm Object Server documentation on Access Control to learn more about the concept.

Retrieving Permissions

To get a collection of all the Permissions a user has been granted, use the User.getGrantedPermissions method:

                          const              permissions              =              user              .              getGrantedPermissions              (              "              currentUser              "              );              // Permissions is a regular query              const              writePermissions              =              permissions              .              filtered              (              "              mayWrite = true              "              );              // Queries are live and emit notifications              writePermissions              .              addListener              ((              collection              ,              changes              )              =>              {              // handle permission changes              });                      

To get permissions granted by a user, pass in "otherUser".

Modifying Permissions

Modifying the access control settings for a Realm file is performed by either applying permissions directly or offering them.

Granting Permissions

Permission changes can be applied (i.e. granted or revoked) via the User.applyPermissions method in order to directly increase or decrease other users' access level to a Realm.

                          const              condition              =              {              userId              :              '              some-user-id              '              };              const              realmUrl              =              "              realm://my-server.com/~/myRealm              "              ;              user              .              applyPermissions              (              condition              ,              realmUrl              ,              '              read              '              );                      

The condition parameter must be an object containing either

  • userId - use this to apply permissions based on a user's identity (the internal Id that Realm generates).
  • metadataKey and metadataValue - use the key 'email' and an email address as the value to specify a user via the Username/Password provider.

The last argument controls the access level that the user will be granted. Higher access implies all lower tiers, e.g. write implies read, admin implies read and write. If none is passed, this will revoke the user's permissions for this Realm.

Offer/Response

A user can offer permissions to their Realm by sharing the opaque token returned by offerPermissionsAsync:

                          const              realmUrl              =              '              realm://my-server.com/~/myRealm              '              ;              const              oneDay              =              1000              *              60              *              60              *              24              ;              const              expiration              =              new              Date              (              Date              .              now              ()              +              7              *              oneDay              );              userA              .              offerPermissions              (              realmUrl              ,              '              write              '              ,              expiration              )              .              then              (              token              =>              {              /* ... */              });                      

The optional expiresAt argument controls when the offer expires - i.e. using the token after that date will no longer grant permissions to that Realm. Users who have already consumed the token to obtain permissions will not lose their access after that date. If you want to revoke permissions, use applyPermissionsAsync.

Once a user has received a token, e.g. by sharing it via messaging app, or scanning a QR code, they can consume it to obtain the permissions offered:

                          const              token              =              "              ...              "              ;              userB              .              acceptPermissionOffer              (              token              )              .              then              (              realmUrl              =>              Realm              .              open              ({              schema              :              [              /* ... */              ],              sync              :              {              user              :              userB              ,              url              :              realmUrl              }}))              .              then              (              realm              =>              {              // ..use the realm              });                      

Migrating from Realm Object Server 1.x to 2.x

If you upgrade Realm Object Server from version 1.x to 2.x, your Realms must be migrated. The new file format is incompatible, and Realms have to be re-downloaded.

When a synchronized Realm requiring migration is opened, the Realm file will be copied to a backup location and then deleted so that it can be re-downloaded from the Realm Object Server. An exception will be thrown, and you can choose to migrate your objects from the old Realm.

                          Realm              .              open              (              config              )              .              then              (              realm              =>              {              // you have probably already migrated              })              .              catch              (              e              =>              {              if              (              e              .              name              ==              "              IncompatibleSyncedRealmError              "              )              {              const              backupRealm              =              new              Realm              (              e              .              configuration              );              // copy objects from backupRealm              return              ;              }              });                      

Encryption

Please take note of the Export Compliance section of our LICENSE, as it places restrictions against the usage of Realm if you are located in countries with an export restriction or embargo from the United States.

Realm supports encrypting the database file on disk with AES-256+SHA2 by supplying a 64-byte encryption key when creating a Realm.

                          var              key              =              new              Int8Array              (              64              );              // pupulate with a secure key              Realm              .              open              ({              schema              :              [              CarObject              ],              encryptionKey              :              key              })              .              then              (              realm              =>              {              // Use the Realm as normal              var              dogs              =              realm              .              objects              (              '              Car              '              );              });                      

This makes it so that all of the data stored on disk is transparently encrypted and decrypted with AES-256 as needed, and verified with a SHA-2 HMAC. The same encryption key must be supplied every time you obtain a Realm instance.

There is a small performance hit (typically less than 10% slower) when using encrypted Realms.

Troubleshooting

Missing Realm Constructor

If your app crashes, telling you that the Realm constructor was not found, there are a few things you can try:

First of all, run react-native link realm

If that doesn't help, and your problem is on Android, try:

Add the following in your MainApplication.java file:

                          import              io.realm.react.RealmReactPackage              ;                      

And add the RealmReactPackage to the list of packages:

                          protected              List              getPackages              ()              {              return              Arrays              .              asList              (              new              MainReactPackage              (),              new              RealmReactPackage              ()              // add this line              );              }                      

add following two lines in settings.gradle:

            include ':realm' project(':realm').projectDir = new File(settingsDir, '../node_modules/realm/android')          

If your problem is on iOS, try:

  1. Close all simulators/device builds
  2. Stop the package manager running in terminal (or better yet, just restart terminal)
  3. Open the ios folder in your app root in finder
  4. Go into the build folder (note: you won't see this build folder in atom, so just right click ios and click open in finder)
  5. Delete everything inside of the build folder (just move to trash and keep trash around in case you're worried)
  6. Run react-native run-ios to rebuild the whole thing

Chrome Debugging is slow

We are aware of this. The reason for this is that since Realm is written in C++ and runs native code, it has to run on the device/simulator. But given the zero-copy architecture, we need to send values in realm objects over the RPC wire every time you inspect an object that is stored in a Realm.

We are investigating various potential solutions for this problem. If you want to keep track of it, you can follow the GitHub issue.

Crash Reporting

We encourage you to use a crash reporter in your application. Many Realm operations could potentially fail at runtime (like any other disk IO), so collecting crash reports from your application will help identify areas where either you (or us) can improve error handling and fix crashing bugs.

Most commercial crash reporters have the option of collecting logs. We strongly encourage you to enable this feature. Realm logs metadata information (but no user data) when throwing exceptions and in irrecoverable situations, and these messages can help debug when things go wrong.

Reporting Realm Issues

If you've found an issue with Realm, please either file an issue on GitHub or email us at help@realm.io with as much information as possible for us to understand and reproduce your issue.

The following information is very useful to us:

  1. Goals.
  2. Expected results.
  3. Actual results.
  4. Steps to reproduce.
  5. Code sample that highlights the issue (full working projects that we can compile ourselves are ideal).
  6. Version of Realm.
  7. Crash logs & stack traces. See Crash Reporting above for details.

bartonanclund.blogspot.com

Source: https://www.mongodb.com/docs/realm-legacy/docs/javascript/2.0.3/index.html