/realm-nodejs-example

A skeleton app to be used as a reference for how to use MongoDB's Realm Node.js SDK.

Primary LanguageTypeScript

Connection State Change & Error Handling In Realm Node.js SDK

A skeleton app to be used as a reference for how to use MongoDB's Realm Node.js SDK specifically around detecting various changes in e.g. connection state, user state, and sync errors, in order to better guide developers.

This example app has been transferred to MongoDB's Realm JS repository.

Project Structure

The following shows the project structure and the most relevant files.

├── src
│   ├── atlas-app-services  - Configure Atlas App
│   │   ├── config.ts
│   │   └── getAtlasApp.ts
│   ├── models              - Simplified data model
│   │   ├── Kiosk.ts
│   │   ├── Product.ts
│   │   └── Store.ts
│   ├── index.ts            - Entry point
│   ├── logger.ts           - Replaceable logger
│   ├── realm-auth.ts       - Main Realm auth usage examples
│   └── realm-query.ts      - Data access/manipulation helper
└── other..

Main file for showcasing Realm usage pertaining to connection and error handling:

Use Cases

This app focuses on showing where and when you can (a) perform logging and (b) handle specific scenarios based on observed changes. It specifically addresses the following points:

  • Logging in using email/password authentication.
  • Listening when a user is logged out or removed.
  • Listening when a user's tokens are refreshed.
  • Listening when the underlying sync session:
    • Tries to connect
    • Gets connected
    • Disconnects
    • Fails to reconnect
  • Listening for sync errors.
  • Listening for pre and post client resets.
  • Generally providing best practices for the surrounding Realm usage such as opening and closing of realms, configurations, adding subscriptions, etc.
  • Includes useful comments around the use of Realm.
  • Note that an over-simplified data model is used. This app also writes data to confirm the functionality.

Realm Details

  • RealmJS version: ^12.0.0
  • Device Sync type: Flexible

Background

Sync Error Handling

Sync error handling is centralized in a single callback function that can be defined in the Realm configuration. The callback will be invoked on each synchronization error that occurs and it is up to the user to react to it or not.

Device Sync will automatically recover from most of the errors; however, in a few cases, the exceptions might be fatal and will require some user interaction.

Connection Changes

Connection changes can be detected by adding a listener callback to the Realm's sync session. The callback will be invoked whenever the underlying sync session changes its connection state.

Since retries will start automatically when disconnected, there is no need to manually reconnect.

Convenience method:

  • Check if the app is connected: app.syncSession?.isConnected()

User Event Changes and Tokens

User event changes can be detected by adding a listener callback to the logged in user. The callback will be invoked on various user related events including refresh of auth token, refresh token, custom user data, removal, and logout.

Access tokens are created once a user logs in and are refreshed automatically by the SDK when needed. Manually refreshing the token is only required if requests are sent outside of the SDK.

By default, refresh tokens expire 60 days after they are issued. In the Admin UI, you can configure this time for your App's refresh tokens to be anywhere between 30 minutes and 180 days, whereafter you can observe the relevant client listeners being fired.

Convenience methods:

  • Get the user's access token: app.currentUser?.accessToken
  • Get the user's refresh token: app.currentUser?.refreshToken

Client Reset

The server will reset the client whenever there is a discrepancy in the data history that cannot be resolved. By default, Realm will try to recover any unsynced changes from the client while resetting. However, there are other strategies available: You can discard the changes or do a manual recovery.

Getting Started

Prerequisites

Set Up an Atlas App Services App

To sync Realm data you must first:

  1. Create an App Services App
  2. Enable Email/Password Authentication
  3. Enable Flexible Sync with Development Mode on.
    • When Development Mode is enabled, queryable fields will be added automatically.
    • Queryable fields used in this app: _id, storeId

After running the client and seeing the available collections in Atlas, set read/write permissions for all collections.

Install Dependencies

npm install

Run the App

  1. Copy your Atlas App ID from the App Services UI.
  2. Paste the copied ID as the value of the existing variable ATLAS_APP_ID in src/atlas-app-services/config.ts:
export const ATLAS_APP_ID = "YOUR_APP_ID";
  1. Start the script.
npm start

Troubleshooting

  • If permission is denied:
  • Removing the local database can be useful for certain errors.
    • When running the app, the local database will exist in the directory mongodb-realm/.
    • To remove it, run: npm run rm-local-db