Install Realm Object Server

macOS

On macOS, this installation is as simple as downloading a file:

Download the macOS bundle

Navigate to your downloads folder and open the “realm-mobile-platform” folder.

Start Realm Object Server by double-clicking the file start-object-server.command. This file will open a terminal window and start Realm Object Server for you.

Linux

Under Linux, Realm’s package repositories are managed through a service called PackageCloud. Run the following commands to set up the package repositories, then install and start Realm Object Server:

# Setup Realm's package repository
curl -s https://packagecloud.io/install/repositories/realm/realm/script.rpm.sh | sudo bash

# Install the Realm Object Server
sudo yum -y install realm-object-server-developer

# Enable and start the service
sudo chkconfig realm-object-server on
sudo service realm-object-server start
# Setup Realm's package repository
curl -s https://packagecloud.io/install/repositories/realm/realm/script.rpm.sh | sudo bash

# Install the Realm Object Server
sudo yum -y install realm-object-server-developer

# Enable and start the service
sudo systemctl enable realm-object-server
sudo systemctl start realm-object-server
# Setup Realm's package repository
curl -s https://packagecloud.io/install/repositories/realm/realm/script.deb.sh | sudo bash

# Update repositories
sudo apt-get update

# Install the Realm Object Server
sudo apt-get install realm-object-server-developer

# Enable and start the service
sudo systemctl enable realm-object-server
sudo systemctl start realm-object-server

We also provide public AMIs for Amazon EC2, based on Ubuntu 16.04. For details on the difference between Paravirtual and HVM see this guide.

  Paravirtual HVM
ap-northeast-1 (Tokyo) ami-b6eda5d1 ami-3beca45c
eu-west-1 (Ireland) ami-0d1c316b ami-cc1d30aa
us-east-1 (N. Virginia) ami-d14190c7 ami-1843920e

You can launch these AMIs just as any other Amazon EC2 AMI. Make sure you open port 22/TCP (ssh) and 9080/TCP (dashboard and client access). The default SSH user is ubuntu.

Setting Up The Realm Dashboard

You will need access to a web browser either on the local Linux machine, or remotely over the network. If you are using a remote browser, you will need to know the network IP address or hostname of the server you just installed ROS (Realm Object Server) on. Replace localhost with the appropriate IP address or hostname in the URL below.

Open a new browser window and go to http://localhost:9080. The login page for the Realm Dashboard will be displayed. If your Linux server is not your local machine, replace localhost with the IP address of your server.

Create an admin user by entering your email and password. After registering, you can log in using these credentials.

The Realm Dashboard will show you the status of the Realm Object Server, including active network connections, active Realms, and the amount of network traffic being generated by connected apps.

Configuring The Server

Realm Object Server includes a configuration file in YAML format that comes with sensible defaults for a development environment. The configuration file can be edited to customize the installation and make it production-ready. In the following we will refer to the configuration file as configuration.yml.

The various configuration options available in configuration.yml are described below. The default location of the configuration file depends on your platform:

The configuration file is in /etc/realm/configuration.yml.

The configuration file is in realm-object-server/object-server inside your Realm Mobile Platform folder.

Paths in the configuration file can be either absolute or relative. If relative, they are resolved according to the current working directory. We recommend always using absolute paths to avoid confusion.

Mandatory Settings

A few options are mandatory to set in order to be able to start Realm Object Server. We recommend specifying these in configuration.yml, but they can also be given as command line arguments.

The mandatory configuration defines:

  1. An existing directory where Realm Object Server will store all its files,
  2. Paths to a key pair used for securing access to ROS to only allow authenticated clients to access it. The keys given must be in PEM format and they must be a matching pair.

Here is a summary of the settings:

Configuration key CLI argument Description
storage.root_path --root Path to the directory where ROS will store all its data files
auth.public_key_path --public-key Path to the public key (stored in PEM format) used to authenticate client tokens
auth.private_key_path --private-key Path to the private key (stored in PEM format) used to authenticate client tokens

Network

In its default configuration Realm Object Server runs internal backend services as well as a proxy module. The backend services are only reachable from the host running the server, and all traffic to them are passed through the proxy module which listen on all interfaces. The following diagram should explain the default configuration:

Proxy config diagram

In the following we show how to change this default configuration.

Backend Services

Realm Object Server internally starts two backend services. The sync service is responsible for core synchronization functionality, and listens on port 27800. The http service handles requests for authentication and the dashboard and listens on port 27080. By default, the services only listen on the host’s IPv4 loopback address (127.0.0.1) and requests are routed through the proxy module.

Should you wish to disable the proxy module and let backend services listen to all IPv4 and IPv6 interfaces this can be achieved by setting the appropriate listen_address to ::. Similarly, the listening ports can be changed by modifying the appropriate listen_port.

Here is a summary of the settings:

Configuration key Default Description
network.sync.listen_address 127.0.0.1 Address the sync service should bind to
network.sync.listen_port 27800 Port the sync service should bind to
network.http.listen_address 127.0.0.1 Address the http service should bind to
network.http.listen_port 27080 Port the sync service should bind to

Proxy Module

The included reverse proxy module dispatches all incoming traffic to the appropriate backend service. This proxy is capable of handling both HTTP, WebSocket, HTTPS and Secure WebSocket traffic (but exclusively traffic destined for the Realm Object Server, this is not a general purpose proxy). In the default configuration, the HTTP proxy listens on all IPv4 and IPv6 interfaces on port 9080, but the HTTPS proxy is disabled. Both variants of the proxy can be enabled simultaneously.

It is recommended that you keep the Sync and HTTP services listening on localhost (default) and simply use the proxy for external access.

If you wish, you can disable the included proxy module and replace it with a standalone proxy installation or use ROS by exposing the backend services on the network for direct client access.

Here is a summary of the proxy’s configuration settings:

Configuration key Default Description
proxy.http.enable true Set to false to disable the HTTP Proxy
proxy.http.listen_address :: Supply an interface address, 0.0.0.0 for all IPv4 interfaces or :: for all IPv4 and IPv6 interfaces
proxy.http.listen_port 9080 Supply an alternative port for the HTTP Proxy
proxy.https.enable false Set to true to enable the HTTPS Proxy
proxy.https.listen_address :: Supply an interface address, 0.0.0.0 for all IPv4 interfaces or :: for all IPv4 and IPv6 interfaces
proxy.https.listen_port 9443 Supply an alternative port for the HTTPS Proxy
proxy.https.certificate_path   Path to the HTTPS Proxy’s certificate file, in PEM format
proxy.https.private_key_path   Path to the HTTPS Proxy’s private key file, in PEM format

If you wish to enable the HTTPS Proxy, you must provide certificate and private key files in PEM format by setting the proxy.https.certificate_path and proxy.https.private_key_path options. The certificate cannot be self-signed.

You must also choose a port number above 1024, as the Realm Object Server does not run as root. It is recommended to use the default port (9443).

If you would like to be able to connect to Realm Object Server on a port lower than 1024, such as the default HTTPS port 443, you can forward traffic to the port that Realm Object Server is listening on:

sudo iptables -A PREROUTING -t nat -p tcp --dport 443 -j REDIRECT --to-port 9443

Here is an example of a working proxy configuration with HTTPS:

proxy:
  https:
    enable: true
    listen_address: ‘::'
  http:
    enable: false

Logging

Realm Object Server logs messages information about its state and progress. Logs can be written to the console or to a file depending on the logging.path configuration, and the logging detail can be tuned by changing the logging.level option.

The default value for logging.path depends on the platform:

Logs are written to /var/log/realm-object-server.log.

Logs are output on the terminal that launched Realm Object Server.

The value for logging.level can be one of 9 possible values:

logging.level Detail level
all all possible messages
trace used to trace protocol and internal server state
debug internal server debugging messages
detail shows summary of synchronization transactions
info good for production (default)
warn log only warning messages
error log only errors
fatal errors that cause the ROS to exit
off all output suppressed

Here is a summary of the settings:

Configuration key Default macOS Default linux Description
logging.path   /var/log/realm-object-server.log Path to the file where logs should be written. If no value is set, output is written to stdout/stderr.
logging.level info info The amount of detail in the log output, see valid values above

Administering The Server

The Realm Object Server service uses standard service commands:

sudo service realm-object-server status
sudo service realm-object-server start
sudo service realm-object-server stop
sudo service realm-object-server restart

The Realm Object Server service definition uses standard systemctl commands:

sudo systemctl status realm-object-server
sudo systemctl start realm-object-server
sudo systemctl stop realm-object-server
sudo systemctl restart realm-object-server

To start the server double-click on the start-object-server.command file in the realm-mobile-platform directory you originally downloaded.

To stop the macOS version of the server, simply press CTRL-C in the terminal window that was opened by the start-object-server.command.

The Realm Dashboard

Stats

The Realm Dashboard

The Realm Dashboard is an administrative interface to the Realm Object Server used to create/manage users and observe the performance of the Realm Object Server.

User Management

An admin user can create users and grant or remove administrative privileges.

Data Browser

The Realm Browser is only available for macOS.

The Realm Browser allows developers to observe and edit Realms. The Realm Broswer can connect to either macOS or Linux instances of the Realm Object Server.

To use the Connect to Object Server option in Realm Browser, you must retrive your admin token that was automatically generated, under Linux the token can be view with:

cat /etc/realm/admin_token.base64

on macOS the token is stored in the realm-object-server folder.

Browsing Realms with the Realm Browser for macOS

Upgrading

macOS

Upgrades to the macOS version of the Object Server are delivered by a new macOS download bundle from Realm

Linux

If you are upgrading from a version prior to 1.0.0-BETA-4.8, we have renamed the package. Please follow the uninstall documentation followed by the install documentation.

Realm’s package service for stand-alone servers makes the upgrade process is very simple:

# Stop the service before upgrading
sudo service realm-object-server stop

# Install a new version if available
sudo yum -y upgrade realm-object-server-developer

# Restart the server to continue operation
sudo service realm-object-server start
# Stop the service before upgrading
sudo systemctl stop realm-object-server

# Install a new version if available
sudo yum -y upgrade realm-object-server-developer

# Restart the server to continue operation
sudo systemctl start realm-object-server
# Update the package definitions
sudo apt-get update

# Stop the service before upgrading
sudo systemctl stop realm-object-server

# Install a new version if available
sudo apt-get upgrade realm-object-server-developer

# Restart the server to continue operation
sudo systemctl start realm-object-server

Linux Professional Edition

This feature is limited to our Professional and Enterprise editions. Learn more about them and start a free trial.

If you are upgrading to the Professional Edition of the Realm Object Server, you must first uninstall the Developer Edition. Then, using the access token you’ve received from us via email, follow these steps according to your distribution:

# Set the token variable:
export PACKAGECLOUD_TOKEN=<the token you received via email>

# Setup Realm's package repository
curl -s https://$PACKAGECLOUD_TOKEN:@packagecloud.io/install/repositories/realm/ros-professional/script.rpm.sh | sudo bash

# Install the Realm Object Server
sudo yum -y install realm-object-server-professional

# Enable and start the service
sudo chkconfig realm-object-server on
sudo service realm-object-server start
# Set the token variable:
export PACKAGECLOUD_TOKEN=<the token you received via email>

# Setup Realm's package repository
curl -s https://$PACKAGECLOUD_TOKEN:@packagecloud.io/install/repositories/realm/ros-professional/script.rpm.sh | sudo bash

# Install the Realm Object Server
sudo yum -y install realm-object-server-professional

# Enable and start the service
sudo systemctl enable realm-object-server
sudo systemctl start realm-object-server
# Set the token variable:
export PACKAGECLOUD_TOKEN=<the token you received via email>

# Setup Realm's package repository
curl -s https://$PACKAGECLOUD_TOKEN:@packagecloud.io/install/repositories/realm/ros-professional/script.deb.sh | sudo bash

# Update repositories
sudo apt-get update

# Install the Realm Object Server
sudo apt-get install realm-object-server-professional

# Enable and start the service
sudo systemctl enable realm-object-server
sudo systemctl start realm-object-server

Linux Enterprise Edition

This feature is limited to our Enterprise editions. Learn more.

If you are upgrading to the Enterprise Edition of the Realm Object Server, you must first uninstall the Developer/Professional Edition. Then, using the access token you’ve received from us via email, follow these steps according to your distribution:

# Set the token variable:
export PACKAGECLOUD_TOKEN=<the token you received via email>

# Setup Realm's package repository
curl -s https://$PACKAGECLOUD_TOKEN:@packagecloud.io/install/repositories/realm/ros-enterprise/script.rpm.sh | sudo bash

# Install the Realm Object Server
sudo yum -y install realm-object-server-enterprise

# Enable and start the service
sudo chkconfig realm-object-server on
sudo service realm-object-server start
# Set the token variable:
export PACKAGECLOUD_TOKEN=<the token you received via email>

# Setup Realm's package repository
curl -s https://$PACKAGECLOUD_TOKEN:@packagecloud.io/install/repositories/realm/ros-enterprise/script.rpm.sh | sudo bash

# Install the Realm Object Server
sudo yum -y install realm-object-server-enterprise

# Enable and start the service
sudo systemctl enable realm-object-server
sudo systemctl start realm-object-server
# Set the token variable:
export PACKAGECLOUD_TOKEN=<the token you received via email>

# Setup Realm's package repository
curl -s https://$PACKAGECLOUD_TOKEN:@packagecloud.io/install/repositories/realm/ros-enterprise/script.deb.sh | sudo bash

# Update repositories
sudo apt-get update

# Install the Realm Object Server
sudo apt-get install realm-object-server-enterprise

# Enable and start the service
sudo systemctl enable realm-object-server
sudo systemctl start realm-object-server

Uninstalling

Should you need to uninstall Realm Object Server, the process is straightforward:

# Stop the service before uninstalling
sudo service realm-object-server stop

# Optional/Recommended: Backup your data:
# cp -a /var/lib/realm{,.backup}

# Remove the packages.  Data is retained under /var/lib/realm.
sudo yum -y erase realm-object-server-developer

# Remove the packages (older than 1.0.0-BETA-4.8)
sudo yum -y erase realm-object-server-de
# Stop the service before uninstalling
sudo systemctl stop realm-object-server

# Optional/Recommended: Backup your data:
# cp -a /var/lib/realm{,.backup}

# Remove the packages.  Data is retained under /var/lib/realm.
sudo yum -y erase realm-object-server-developer

# Remove the packages (older than 1.0.0-BETA-4.8)
sudo yum -y erase realm-object-server-de
# Stop the service before uninstalling
sudo systemctl stop realm-object-server

# Optional/Recommended: Backup your data:
# cp -a /var/lib/realm{,.backup}

# Remove the packages.  Data is retained under /var/lib/realm.
sudo apt-get remove realm-object-server-developer

# Remove the packages (older than 1.0.0-BETA-4.8)
sudo apt-get remove realm-object-server-de
# Stop the service before uninstalling
Press CTRL-C in the controlling terminal window

# Remove the packages
Drag the realm-mobile-platform folder to the trash

Troubleshooting

Verify Port Access

Certain factors may impact external (non-localhost) access to the Realm Object Server’s synchronization facility, and the Realm Dashboard. In order to enable access, it may be necessary to open port 9080 on your server(s).

Using the standard Linux tools, these commands will open access to the port:

sudo iptables -A INPUT -p tcp -m tcp --dport 9080 -j ACCEPT
sudo service iptables save

Please refer to the CentOS 6 Documentation for more information regarding how to configure your firewall.

sudo firewall-cmd --get-active-zones
sudo firewall-cmd --zone=public --add-port=9080/tcp --permanent
sudo firewall-cmd --reload
sudo ufw allow 9080/tcp
sudo ufw reload

If your environment does not use your distribution’s standard firewall, you will have to modify these instructions to fit your environment.

Configuration Errors

Generally the default settings will work well for most installations. Most settings inside the Realm config file are commented out (the system has pre-programmed default values) and show examples of how they can be to customized. If the configuration file has been customized and there is a problem, error messages will be written to the default log location (in the terminal window under macOS or /var/log/realm-object-server.log on Linux systems).

If the Realm Object Server will not start, an error in the configuration file is usually the cause. To debug the config file, you can use the built-in checker by starting a terminal and using:

realm-object-server --check-configuration /etc/realm/configuration.yml

If running under macOS, replace the configuration file path with the path to your configuration.yml.

When an error occurs, the server’s parser will print a detailed error message stating the problem and possibly highlighting the line the error occurred on. Once all errors (if any) were corrected, the server will start; stop the server by pressing ^C and then start it normally by rebooting the system or restarting the Realm Object Server using systemd on Linux or the start-object-server.command on macOS.

Error messages are usually self-explanatory, but here are some potential hints:

  • To be able to run ROS, the following settings are mandatory:
    • Storage root directory: Where Realm Object Server should store all its files. Please set storage.root_path or give the --root CLI argument. The directory must exist before ROS can start.
    • Authentication key pair: For securing access to ROS to only authenticated clients. Please set auth.private_key_path or give the --private-key CLI argument, and please set auth.public_key_path or give the --public-key CLI argument. The keys given must be in PEM format and they must be a matching pair.
  • The configuration for listening ports must not be overlapping, meaning that listen_port values must be unique in the file. Additionally, the ports must not be bound in another process.

  • The HTTPS proxy will only start if given paths to a valid certificate and private key in proxy.https.certificate_path and proxy.https.private_key_path. The certificate and private key must be in PEM format and they must be a matching pair. The certificate cannot be self-signed.

Operational Errors

Occasionally it can be useful for debugging purposes to check the Realm Object Server logs - which are in the terminal window on macOS or /var/log/realm-object-server.log on Linux systems - ROS produces two specific classes of error and warning diagnostics that may be useful to system admins and developers.

Session Specific Errors

  • 204 “Illegal Realm path (BIND)” Indicates that the Realm path is not valid for the user.

  • 207 “Bad server file identifier (IDENT)” Indicates that the local Realm specifies a link to a server-side Realm that does not exist. This is most likely because the server state has been completely reset.

  • 211 “Diverging histories (IDENT)” Indicates that the local Realm specifies a server version that does not exists. This is most likely because the server state has been partially reset (for example because a backup was restored).

Client Level Errors

  • 105 “Wrong protocol version (CLIENT)” The client and the server use different versions of the sync protocol due to a mismatch in upgrading.

  • 108 “Client file bound in other session (IDENT)” Indicates that multiple sync sessions for the same client-side Realm file overlap in time.

  • 203 “Bad user authentication (BIND, REFRESH)” Indicates that the server has produced a bad token, or that the SDK has done something wrong.

  • 206 “Permission denied (BIND, REFRESH)” Indicates that the user does not have permission to access the Realm at the given path.

Conflict Resolution

One of the defining features of mobile is the fact that you can never count on being online. Loss of connectivity is a fact of life, and so are slow networks and choppy connections. But people still expect their apps to work!

This means that you may end up having two or more users making changes to the same piece of data independently, creating conflicts. Note that this can happen even with perfect connectivity as the latency of communicating between the phone and the server may be slow enough that they can end up creating conflicting changes at the same time.

What Realm does in this case is that it merges the changes after the application of specific rules that ensure that both sides always end up converging to the same result even, though they may have applied the changes in different order.

This means that you no longer have the kind of perfect consistency that you could have in a traditional database, what you have now is rather what is termed “strong eventual consistency”. The tradeoff is that you have to be aware of the rules to ensure the consistent result you want, but the upside is that by following a few rules you can have devices working entirely offline and still converging on meaningful results when they meet.

At a very high level the rules are as follows:

  • Deletes always wins. If one side deletes an object it will always stay deleted, even if the other side has made changes to it later on.

  • Last update wins. If two sides has updated the same property, the value will end up as the last updated.

  • Inserts in lists are ordered by time. If two items are inserted at the same position, the item that was inserted first will end up before the other item. This means that if both sides append items to the end of a list they will end up in order of insertion time.

Primary Keys

To ensure uniqueness of objects, you can assign them primary keys. Let’s say your app has a global “settings” object. If you just do a check on startup and add it if it does not exist, you can easily end up with two or more instances of the object as multiple instances of the app all adds their own version.

The solution here is to assign the object a primary key so that you communicate the intent of this being the same object, even if it is being created multiple times simultaneously. The system is smart enough to recognize default values, so that properties you have changed won’t be overwritten by later (empty) objects.

Strings

Not exposed in client API’s yet

Strings are special in that you can see them both as scalar values and as lists of characters. This means that you can set the string to a new string (replacing the entire string) or you can edit the string. If multiple users are editing the same string, you want conflicts to be handled at the character level (similar to the experience you would have in something like Google docs).

Counters

Not exposed in client API’s yet

Using integers for counting is also a special case. The way that most programming languages would implement an increment operation (like v += 1), is to read the value, increment the result, and then store it back. This will obviously not work if you have multiple parties doing it simultaneously (they may both read 10, increment it to 11, and when it merges you would get the result of 11 rather than the intended 12).

To support this common use case we offer a way to express the intent that you are incrementing (or decrementing) the value, giving enough hints to the merge that it can reach the correct result. Just as with the strings above, it gives you the choice of updating the entire value, or editing it in a way that conveys more meaning, and allow you to get more precise control of the conflict resolution.

Custom Conflict Resolution

The standard way to do custom conflict resolution is to just change the value into a list. Then each side can add its updates to the list and apply any conflict resolution rules it wants directly in the data model.

You can use this technique to implement max, min, first write wins, last write wins and pretty much any kind of resolution you can think of.

Access Control

Realm Object Server includes access control mechanisms to restrict which users are allowed to sync against which Realm files. There are two concepts: Authentication and Authorization. In order to grant some user access to a Realm, Realm Object Server authenticates the user to verify the identity of the user, and authorizes that the user has the correct permissions to access the Realm. More specifically:

  • Realm Object Server uses configurable authentication providers to validate user credentials and authenticate users. A client connects to the server using some user credentials, and these are given to an appropriate provider for validation. If the credentials are valid, the user is granted access to Realm Object Server. A new user account is created if the credentials are not coupled to an existing account.
  • After the client is granted access as a user, it can request read or write access to a specific path identifying a Realm. If the user has the requested access permissions for the given path, the user is authorized to access the Realm, and normal sync operations can begin.

Authentication

Authentication providers allow developers to utilize third-party authentication mechanisms to control access to Realm apps that go beyond Realm’s own username/password mechanism. Realm supports Facebook, Google, and Apple’s iCloud.

These third-party providers currently operate at the single-server level, and will need to be set up on each server that needs to make use of a given authentication mechanism. The setup is done by providing a set of key-value pairs that identify the authentication mechanism and the required keys/secrets.

This information goes into the auth.providers section of the Realm configuration.yml file.

Below are examples that demonstrate how to integrate each of these third-party authentication providers and where applicable links to the developer pages for those services. Complete examples of all authentication providers can be found in the Realm Object Server configuration.yml file.

Password

Username/Password authentication is always enabled.

Google

After getting Google OAuth2.0 API Access, enter the client ID key in the google stanza:

google:
  clientId: '012345678901-abcdefghijklmnopqrstvuvwxyz01234.apps.googleusercontent.com'

Facebook

Facebook Authentication requires no configuration besides enabling the facebook provider:

facebook: {}

Facebook client tokens received by Realm Object Server will be checked for validity against the Facebook APIs, so ROS needs to be able to contact those.

iCloud

iCloud is only available on Apple platforms: iOS, tvOS, watchOS, and macOS.

In order to access CloudKit using Realm Object Server, need to create a public key, then connect to Apple’s CloudKit web dashboard and create a CloudKit access key for your application. These keys will be used to configure the Realm Object Server’s CloudKit authentication module for a specific Realm. The steps for these are slightly different, depending on whether you are on Linux or macOS.

  1. Open a terminal in the Realm Mobile Platform directory

  2. Generate a private key using the following OpenSSL commands. openssl ecparam -name prime256v1 -genkey -noout -out cloudkit_eckey.pem

  3. Generate a public key to be submitted to the CloudKit Dashboard openssl ec -in cloudkit_eckey.pem -pubout The output from the command will be a base64 public key string; copy it and save it.

  4. Generate a CloudKit access key. Using your Apple developer account, log in to Apple’s CloudKit Dashboard; select the application for which you would like to generate an access key.

  5. In the left-hand side of the dashboard, select “API Access”, and then in the middle section, select the drop-down menu (its default setting is “API Tokens”) and select “Server-to-Server Keys”. Select “Add Server-to-Server Key”.

  1. Generate a private key using the following OpenSSL commands. sudo openssl ecparam -name prime256v1 -genkey -noout -out /etc/realm/cloudkit_eckey.pem

  2. Generate a public key to be submitted to the CloudKit Dashboard openssl ec -in /etc/realm/cloudkit_eckey.pem -pubout The output from the command will be a base64 public key string; copy it and save it.

  3. Generate a CloudKit access key. Using your Apple developer account, log in to Apple’s CloudKit Dashboard; select the application for which you would like to generate an access key.

  4. In the left-hand side of the dashboard, select “API Access”, and then in the middle section, select the drop-down menu (its default setting is “API Tokens”) and select “Server-to-Server Keys”. Select “Add Server-to-Server Key”.

Generating an access key with the CloudKit Dashboard

On the panel that is revealed, give the new key a name, and paste in the public key text generated in Step 1 above. Click “Save” in the lower right corner.

After a few seconds, a key will be generated and displayed in the “Key ID” section across the top of the page. This is the key ID needed to configure the Realm CloudKit authentication module.

Security note: Create a new private key for each application you plan on using with Realm CloudKit authentication. Reusing private keys can compromise all Realms using the shared key if the private key itself becomes compromised or needs to be revoked.

In addition to the Key ID from Apple, you will need the CloudKit Container name of your CloudKit app (this will be on the application’s page on the Dashboard), the private key you generated in Step 1, and the Realm App ID for your app.

An example of a fully configured CloudKit stanza will look like this:

cloudkit:
  ## The Key ID from CloudKit.
  key_id: '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'

  ## The path to the certificate.
  private_key_path: 'cloudkit_eckey.pem'

  ## The container identifier, in reverse domain name notation.
  container: "iCloud.io.realm.exampleApp.ios"

  ## The environment in which CloudKit should be used. The default is
  ## 'development'. For production deployment on the App Store, you must
  ## specify 'production'.
  environment: 'development'

Please ensure that the path to the private_key_path is correct. On Linux, it needs to be /etc/realm/cloudkit_eckey.pem, if you have followed the steps above.

Authorization

Realm Object Server includes an authorization mechanism that controls which users are granted read and write permissions for specific Realms. 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.

The fundamental abstraction is the permission, a unique relation between a User and a Realm containing three boolean flags that describes what the user is allowed to do with the Realm:

  • 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 of a Realm can access it. The only exception is admin users: They are always granted all permissions to all Realms on the server.

It is possible to modify both default user permissions as well as individual user permissions for a Realm as described in modifying permissions. If a user requests access to a Realm for which it has no individual user permissions, the default user permissions for the Realm are used to determine if the user should be authorized. If neither individual user permissions nor default user permissions have been created, access is denied.

Admin-Realm

Realm Object Server has a single global admin-Realm. This is the authoritative data store containing the complete set of permissions for all Realm files and users controlled by the server. Request to access a Realm can only be authorized after checking the permissions stored in the admin-Realm. Only Realm Object Server is able to write to this Realm, meaning that permissions are modified exclusively by Realm Object Server.

Modifying Permissions

Though permissions are modified exclusively by Realm Object Server, a user with the mayManage permission on a Realm can request the server to modify the permissions for that Realm to grant read or write access to other users. Such a request is made by creating a PermissionChange object and writing that to the management-Realm for the user. When the management-Realm has been synchronized with Realm Object Server, the PermissionChange object will be processed by the server and the changes will be stored in the admin-Realm.

Management-Realm

The user-specific management-Realm allows users to indirectly make changes to the set of permissions stored in the admin-Realm. Objects created in the management-Realm can be understood as a request to the server with the status indicated by the fields statusCode and statusMessage. The server processes each object individually in the order it receives them. It first attempts to verify the request, and only carries out the requested modification if the request is valid. If the modification succeeded the server sets statusCode = 0 and may add a description of its consequences in the statusMessage field. Alternatively, in case of failure the server will set statusCode to some error code > 0 and add an error message in statusMessage.

The PermissionChange Object

A user creates PermissionChange objects in the management-Realm in order to change permissions for existing Realm files and users. Realm Object Server carries out the permission change only if the user creating the object has the mayManage permission for the existing Realm file. In the following description, we will assume that the user has the mayManage permission on the existing Realm. The PermissionChange object contains the following fields:

realmUrl 	// string: the URL of the realm
userId 		// string: the identity for a user
mayRead		// boolean (optional): is the user allowed to read from the realm?
mayWrite	// boolean (optional): is the user allowed to write to the realm?
mayManage	// boolean (optional): is the user allowed to manage the realm?

The three boolean fields mayRead, mayWrite and mayManage are optional, and indicate the new permissions to be granted to the specified user for the Realm file on the given path. If a flag is not set in the PermissionChange object, the existing value for that flag will remain.

The string fields userId and realmUrl are required. They are used to determine the affected user and Realm for which permissions should change.

Setting userId='*' indicates that the default user permissions for the affected Realm should be modified, and setting realmUrl='*' indicates that all Realms owned by the requesting user should be affected. That is, if a user creates a PermissionChange object with fields { realmUrl='*', userId='*', mayRead=true } the default user permissions will include read access for all Realms owned by the user requesting the change. Note that changing the default user permissions will not remove permissions already granted to individual users.

Load Balancing

This feature is limited to our Enterprise editions. Learn more.

The Realm Object Server is designed for high-performance and even a single instance can handle tens of thousands of concurrent connections. However, for large-scale applications that expect hundreds or millions of concurrent connections, multiple servers are required. Realm Mobile Platform Enterprise Edition offers a complete solution to horizontally scale to any number of Realm Object Servers supporting even the largest applications.

The system works via an included load balancer designed to support the persistent two-way connections utilized by the client and server.

Installation

Each backend node operates independently from other backend nodes in the same cluster. Each backend node runs an instance of the realm-sync-worker binary, which is the name of the synchronization worker that normally runs as part of the Realm Object Server. It requires no configuration, but must be reachable from the server instance running the Realm Object Server.

To install the sync worker, you need to setup the enterprise repository as described above.

# Set the token variable:
export PACKAGECLOUD_TOKEN=<the token you received via email>

# Setup Realm's Enterprise package repository. No need to do it if you already installed the ROS Enterprise
curl -s https://$PACKAGECLOUD_TOKEN:@packagecloud.io/install/repositories/realm/ros-enterprise/script.rpm.sh | sudo bash

# Install the Realm Object Server standalone sync worker:
sudo yum -y install realm-sync-worker

# Replace /etc/realm/token-signature.pub with the one from the Realm Object
# Server.

# Enable and start the service
sudo chkconfig realm-sync-worker on
sudo service realm-sync-worker start
# Set the token variable:
export PACKAGECLOUD_TOKEN=<the token you received via email>

# Setup Realm's Enterprise package repository. No need to do it if you already installed the ROS Enterprise
curl -s https://$PACKAGECLOUD_TOKEN:@packagecloud.io/install/repositories/realm/ros-enterprise/script.rpm.sh | sudo bash

# Install the Realm Object Server standalone sync worker:
sudo yum -y install realm-sync-worker

# Replace /etc/realm/token-signature.pub with the one from the Realm Object
# Server.

# Enable and start the service
sudo systemctl enable realm-sync-worker
sudo systemctl start realm-sync-worker
# Set the token variable:
export PACKAGECLOUD_TOKEN=<the token you received via email>

# Setup Realm's Enterprise package repository. No need to do it if you already installed the ROS Enterprise.
curl -s https://$PACKAGECLOUD_TOKEN:@packagecloud.io/install/repositories/realm/ros-enterprise/script.deb.sh | sudo bash

# Update repositories
sudo apt-get update

# Install the Realm Object Server
sudo apt-get install realm-sync-worker

# Replace /etc/realm/token-signature.pub with the one from the Realm Object
# Server.

# Enable and start the service
sudo systemctl enable realm-sync-worker
sudo systemctl start realm-sync-worker

Configuration

In the Realm Object Server’s configuration.yml, the “sync.servers” section describes the cluster of backend nodes. For the purposes of load balancing, each backend node must be identified with a unique ID, which can be any string as long as it is a valid filesystem path component.

Example:

sync:
  servers:
  - id: 'alpha'
    address: '::'
    port: 7800
  - id: 'beta'
    address: 'beta.local'
    port: 7800
  - id: 'delta'
    address: 'delta.local'
    port: 7800

The example configuration files provided as part of the Realm Object Server installation provide additional details.

The “address” field of each cluster backend node is interpreted specially if the address designates an IP address representing all interfaces, i.e. “0.0.0.0” or “::” if using IPv6. This indicates to the Realm Object Server that a local synchronization worker should be started listening on the IP address of localhost (“127.0.0.1” or “::1” respectively).

The sync workers work out of the box and only require additional configuration if multiple workers are started on a single instance, or if they should listen on an interface other than 127.0.0.1.

High Availability

There are a number of different approaches to HA, and your architecture, business requirements, or budget all affect which choice is best for your application. Realm Mobile Platform aims to offer a number of different options to reduce downtime and data loss.

Offline-First

One of the unique aspects of Realm Mobile Platform is that it is designed to be offline-first. Architecturally, this means that clients retain a local copy of data from the server and read or write directly to this. The client SDK then sends the changes asynchronously when network connectivity is available and Realm Object Server automatically integrates these changes in a deterministic manner. The result of such a system, is that it is inherently highly available from the perspective of the client. Reads and writes can always occur locally irrelevant of the network conditions or server operations.

Failover

The highest level of server availability is offered through a failover system. We are currently working on a clustering solution that supports automatic failover so there is no loss of service. This functionality will be available in the Enterprise Edition. To learn more and to get early access, please contact us.

Backup

The Realm Object Server provides one or two backup systems, depending on your Edition.

  • The manual backup system is included in all versions of Realm Mobile Platform via a command line utility. It can be triggered during server operations to create a copy of the data in the Object Server.
  • The continuous backup system, available only in the Enterprise Edition, is a backup server running alongside the main process in the Realm Object Server. It continuously watches for changes across all synchronized Realms and sends changes to one or more backup clients.

Both systems create a directory of Realms from which the Realm Object Server can be restarted after a server crash. The backed up data includes the user Realms, all user account information, and all other metadata used by the Object Server. Both manual and continuous backups can be made from a running Realm Object Server without taking it offline.

Continuous Backup

This feature is limited to our Enterprise editions. Learn more.

The continuous backup is part of the Realm Mobile Platform Enterprise Edition. See above for upgrading to EE.

Continuous backup uses a client-server. A backup server monitors the state of a running Realm Object Server. Changes on the object server are sent asynchronously to one or more backup clients. All clients will have a slightly delayed copy of the server state.

The continuous backup system communicates without encryption and authenticated access! To stay secure, run the backup system behind a firewall.

Backup Server

The backup server is installed as part of the realm-object-server and the realm-sync-worker. To enable it, run:

sudo chkconfig realm-object-server-backup-server on
sudo service realm-object-server-backup-server start
# Starts automaticaly when starting the realm-object-server
sudo systemctl enable realm-object-server
sudo systemctl start realm-object-server
sudo systemctl status realm-object-server-backup-server
sudo systemctl enable realm-object-server
sudo systemctl start realm-object-server
sudo systemctl status realm-object-server-backup-server

The configuration is done in the Realm Object Server YAML file (/etc/realm/configuration.yml) under the backup section. The keys used by the backup server are:

Configuration key Default Description
backup.enable true Set to false to disable backup.
backup.network.listen_address 127.0.0.1 The IP address/interface
backup.network.listen_port 27810 The listening port of the backup
backup.logging.level info Logging levels described in Logging
backup.logging.path /var/log/realm-object-server-backup-server.log (Linux) Log file path. Empty value for stderr.

If backing up a node in a cluster of sync workers, the backup server will read the sync worker configuration file instead, located at /etc/realm/sync-worker-configuration.yml.

Backup Client

The Realm Object Server Backup Client is started on every machine where a backup is needed. The backup client is configured in a separate YAML file.

To install the backup client, you need to setup the enterprise repository as described above.

# Set the token variable:
export PACKAGECLOUD_TOKEN=<the token you received via email>

# Setup Realm's Enterprise package repository. No need to do it if you already installed the ROS Enterprise
curl -s https://$PACKAGECLOUD_TOKEN:@packagecloud.io/install/repositories/realm/ros-enterprise/script.rpm.sh | sudo bash

# Install the Realm Object Server Backup Client
sudo yum -y install realm-object-server-backup-client

# Edit the configuration to point to an ROS with backup enabled. The default configuration assumes ROS and the Backup Server live on the same machine.
vim /etc/realm/object-server-backup-client.yml

# Enable and start the service
sudo chkconfig realm-object-server-backup-client on
sudo service realm-object-server-backup-client start
# Set the token variable:
export PACKAGECLOUD_TOKEN=<the token you received via email>

# Setup Realm's Enterprise package repository. No need to do it if you already installed the ROS Enterprise
curl -s https://$PACKAGECLOUD_TOKEN:@packagecloud.io/install/repositories/realm/ros-enterprise/script.rpm.sh | sudo bash

# Install the Realm Object Server
sudo yum -y install realm-object-server-backup-client

# Edit the configuration to point to an ROS with backup enabled. The default configuration assumes ROS and the Backup Server live on the same machine.
vim /etc/realm/object-server-backup-client.yml

# Enable and start the service
sudo systemctl enable realm-object-server-backup-client
sudo systemctl start realm-object-server-backup-client
# Set the token variable:
export PACKAGECLOUD_TOKEN=<the token you received via email>

# Setup Realm's Enterprise package repository. No need to do it if you already installed the ROS Enterprise.
curl -s https://$PACKAGECLOUD_TOKEN:@packagecloud.io/install/repositories/realm/ros-enterprise/script.deb.sh | sudo bash

# Update repositories
sudo apt-get update

# Install the Realm Object Server
sudo apt-get install realm-object-server-backup-client

# Edit the configuration to point to an ROS with backup enabled. The default configuration assumes ROS and the Backup Server live on the same machine.
vim /etc/realm/object-server-backup-client.yml

# Enable and start the service
sudo systemctl enable realm-object-server-backup-client
sudo systemctl start realm-object-server-backup-client

The configuration file is in /etc/realm/object-server-backup-client.yml.

The keys of the backup client configuration are

Configuration key Default Description
storage.root_path   The directory where the backup should be stored. A recovered Realm Object Server can be started with this directory as root path.
network.server_address   The IP address/interface of the backup server.
network.server_port 27810 The IP address/interface of the backup server.
network.reconnect_delay 2000 The delay (in milliseconds) between attempts to reach the backup server. The client automatically reconnects after connection loss.
logging.level info Logging levels described in Logging
logging.path /var/log/realm-object-server-backup-client.log (Linux) Log file path. Empty value outputs to stderr.

Quickstart Guide

The quickstart guide will install the enterprise editon of Realm Object Server, the backup client, and the backup server on the same machine and enable them, using the default configurations.

# Set the token variable:
export PACKAGECLOUD_TOKEN=<the token you received via email>

# Setup Realm's Enterprise package repository. No need to do it if you already installed the ROS Enterprise
curl -s https://$PACKAGECLOUD_TOKEN:@packagecloud.io/install/repositories/realm/ros-enterprise/script.rpm.sh | sudo bash

# Install the Realm Object Server and the backup client
sudo yum -y install realm-object-server-enterprise
sudo yum -y install realm-object-server-backup-client

# Enable and start the ROS service
sudo chkconfig realm-object-server on
sudo service realm-object-server start

# Enable and start the backup server service
sudo chkconfig realm-object-server-backup-server on
sudo service realm-object-server-backup-server start

# Enable and start the backup client service
sudo chkconfig realm-object-server-backup-client on
sudo service realm-object-server-backup-client start

# Check that the files are in sync
md5sum /var/lib/realm/object-server/0/user_data/__admin.realm
md5sum /var/lib/realm/object-server-backup-client/0/user_data/__admin.realm
# Set the token variable:
export PACKAGECLOUD_TOKEN=<the token you received via email>

# Setup Realm's Enterprise package repository. No need to do it if you already installed the ROS Enterprise
curl -s https://$PACKAGECLOUD_TOKEN:@packagecloud.io/install/repositories/realm/ros-enterprise/script.rpm.sh | sudo bash

# Install the Realm Object Server and the backup client
sudo yum -y install realm-object-server-enterprise
sudo yum -y install realm-object-server-backup-client

# Enable and start the ROS service
sudo systemctl enable realm-object-server
sudo systemctl start realm-object-server

# Check that the backup server service is running
sudo systemctl status realm-object-server-backup-server

# Enable and start the backup client service
sudo systemctl enable realm-object-server-backup-client
sudo service realm-object-server-backup-client start

# Check that the files are in sync
md5sum /var/lib/realm/object-server/0/user_data/__admin.realm
md5sum /var/lib/realm/object-server-backup-client/0/user_data/__admin.realm
# Set the token variable:
export PACKAGECLOUD_TOKEN=<the token you received via email>

# Setup Realm's Enterprise package repository. No need to do it if you already installed the ROS Enterprise.
curl -s https://$PACKAGECLOUD_TOKEN:@packagecloud.io/install/repositories/realm/ros-enterprise/script.deb.sh | sudo bash

# Update repositories
sudo apt-get update

# Install the Realm Object Server
sudo apt-get install realm-object-server-enterprise
sudo apt-get install realm-object-server-backup-client

# Enable and start the ROS service
sudo systemctl enable realm-object-server
sudo systemctl start realm-object-server

# Check that the backup server service is running
sudo systemctl status realm-object-server-backup-server

# Enable and start the backup client service
sudo systemctl enable realm-object-server-backup-client
sudo service realm-object-server-backup-client start

# Check that the files are in sync
md5sum /var/lib/realm/object-server/0/user_data/__admin.realm
md5sum /var/lib/realm/object-server-backup-client/0/user_data/__admin.realm

Manual Backup

The manual backup is a console command that backs up a running instance of the Realm Object Server. This command can be executed on a server without shutting it down, any number of times, in order to create an “at rest” backup that can be stored on long-term storage for safekeeping. In order to be as agnostic as possible regarding the way the backup will be persisted, the command simply creates a directory structure containing everything the server needs to get started again in the event of a disk failure.

It is recommended that the resulting directory is compressed and sent to an off-site location, such as Amazon S3 or Online C14.

Because Realms can be modified during the backup process, the backup command uses Realm’s transaction features to take a consistent snapshot of each Realm. However, since the server is running continuously, the backed up Realms do not represent the state of the server at one particular instant in time. A Realm added to the server while a backup is in progress might be completely left out of the backup. Such a Realm will be included in the next backup.

To run realm-backup at the command line, type:

realm-backup SOURCE TARGET
  • SOURCE is the data directory of the Realm Object Server (typically configured in /etc/realm/configuration.yml under storage.root_path).
  • TARGET is the directory where the backup files will be placed. This directory must be empty or absent when the backup starts for safety reasons.

After the backup command completes, TARGET will be a directory with the same sub directory structure as SOURCE and a backup of all individual Realms.

Server Recovery From A Backup

If the data of a Realm Object Server is lost or otherwise corrupted, a new Realm Object Server can be restarted with the backed up data. This is done simply by stopping the server and copying the latest backup directory (e.g., the TARGET directory in the manual backup procedure, or the storage.root_path directory specified by a continuous backup client) into the Realm Object Server’s data directory (e.g., the SOURCE directory in the manual backup procedure). After the backup has been fully copied into the Realm Object Server’s data directory, the server may be restarted.

Client Recovery From A Backup

Any data added to the Object Server after its most recent backup will be lost when the server is restored from that backup. Since Realm Mobile Database clients communicate with the Object Server continuously, though, it’s possible for them to have been updated with that newer data that’s no longer on the server.

In the case of such an inconsistency, the Realm Object Server will send an error message to the client, and refuse to synchronize data. The error messages relating to synchronization inconsistencies are:

  • 207 “Bad server file identifier (INTENT)”
  • 208 “Bad client file identifier (IDENT)”
  • 209 “Bad server version (IDENT, UPLOAD)”
  • 211 “Diverging histories (IDENT)”

If the client receives one of these error messages, the only way to continue synchronization from the server is to start over: erase all the data in the local copy of the Realm that received the error, and re-sync with the server. This way, the client will have all the data (and only the data) on the Object Server and will be in a consistent state.

Note that if this happens, the client will lose any data that only existed on its local, inconsistent copy of the synchronized Realm (i.e., data that was added to it between the time the Object Server crashed and was restored from its backup). The best way to minimize this potential data loss is to use the continuous backup system. If you can’t do that, run the manual backup system frequently.

Monitoring

This feature is limited to our Professional and Enterprise editions. Learn more about them and start a free trial.

Realm Object Server supports sending metrics to statsd, which is assumed to be listening at localhost:8125. You can then forward these metrics to graphite or similar systems for monitoring.

All metrics keys start with a prefix of realm.<hostname>:

realm.example.com.server.connection.accept.succeeded
realm.example.com.server.connection.accept.failed
realm.example.com.server.protocol.bind.received
realm.example.com.auth.password.attempted
realm.example.com.auth.password.failed
realm.example.com.auth.password.failure.username_invalid
realm.example.com.auth.password.failure.password_check_failed

Counters

This counter is incremented when the Realm Object Server is started.

  • <prefix>.server.started

These counters are incremented when synchronization fails to start. This indicates the clients need to delete their Realm files and reload them from the server.

  • <prefix>.protocol.ident.failure.bad_server_version
  • <prefix>.protocol.ident.failure.diverging_histories
  • <prefix>.protocol.ident.failure.bad_client_file_ident

These counters are incremented when sessions start and terminate. A session is considered to start on connection, before authentication.

  • <prefix>.session.started
  • <prefix>.session.terminated

These counters indicate token-related failures.

  • <prefix>.protocol.client.token.failure.invalid_base64
  • <prefix>.protocol.client.token.failure.invalid_json
  • <prefix>.protocol.client.token.failure.missing_key: a token accepted without authentication because the key is missing
  • <prefix>.protocol.client.token.failure.signature_mismatch
  • <prefix>.protocol.client.token.failure.expired

These counters indicate different types of synchronization protocol messages sent/received.

  • <prefix>.protocol.download.sent
  • <prefix>.protocol.bind.received
  • <prefix>.protocol.client.received
  • <prefix>.protocol.ident.received
  • <prefix>.protocol.mark.received
  • <prefix>.protocol.refresh.received
  • <prefix>.protocol.unbind.received
  • <prefix>.protocol.upload.received

These counters track failures during protocol message processing.

  • Bind
    • <prefix>.protocol.bind.failure.bad_authentication
    • <prefix>.protocol.bind.failure.illegal_realm_path
    • <prefix>.protocol.bind.failure.permission_denied
    • <prefix>.protocol.bind.failure.reuse_of_session_ident
    • No token_expired counter here, because the token has not been provided yet. But the token provided with the bind message is checked and bad_authentication is raised if it is expired or invalid.
  • Ident
    • <prefix>.protocol.ident.failure.bad_server_file_ident
    • <prefix>.protocol.ident.failure.bound_in_other_session
    • <prefix>.protocol.ident.failure.permission_denied
    • <prefix>.protocol.ident.failure.token_expired
  • Refresh
    • <prefix>.protocol.refresh.failure.bad_authentication
    • <prefix>.protocol.refresh.failure.permission_denied
    • No token_expired counter here, because it is not considered an error to provide a new token while the current one has already expired. But the token provided with the refresh message is checked and bad_authentication is raised if it is expired or invalid.
  • Upload
    • <prefix>.protocol.upload.failure.bad_changeset
    • <prefix>.protocol.upload.failure.bad_client_version
    • <prefix>.protocol.upload.failure.bad_server_version
    • <prefix>.protocol.upload.failure.permission_denied
    • <prefix>.protocol.upload.failure.token_expired
  • Mark
    • <prefix>.protocol.mark.failure.token_expired

These counters track low-level protocol errors.

  • <prefix>.protocol.read.head.error.bad_message_before_activation
  • <prefix>.protocol.read.head.error.bad_session_ident
  • <prefix>.protocol.read.head.error.bad_syntax
  • <prefix>.protocol.read.head.error.ident_message_after_activation
  • <prefix>.protocol.read.head.error.limits_exceeded
  • <prefix>.protocol.read.head.error.message_after_unbind
  • <prefix>.protocol.read.head.error.premature_ident_message
  • <prefix>.protocol.read.head.error.unknown_message
  • <prefix>.protocol.read.head.error.wrong_protocol_version

Every protocol error counts against either connection.errored or session.errored.

  • <prefix>.protocol.connection.errored
  • <prefix>.protocol.session.errored

Lastly, these counters track connection events.

  • <prefix>.connection.accept.failed
  • <prefix>.connection.accept.succeeded
  • <prefix>.connection.read.failure.limits_exceeded
  • <prefix>.connection.read.failed
  • <prefix>.connection.write.failed
  • <prefix>.connection.started
  • <prefix>.connection.terminated
  • <prefix>.connection.removed

Gauges

The number of connections/sessions currently open. Multiple sessions can be served through a connection.

  • <prefix>.connection.opened
  • <prefix>.session.opened

Server-Side Scripting

The Professional and Enterprise editions of the Realm Mobile Platform provide a Node.js-based API for the Realm Object Server, including an event handling API that reacts to changes across Realms and a Data Access API that allows server applications to access and change any shared Realm with administrative access. For more details, read the appropriate sections in the Realm JavaScript documentation: