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-825c25e5 ami-535c2534
eu-west-1 (Ireland) ami-57291e24 ami-51291e22
us-east-1 (N. Virginia) ami-542bc042 ami-5d2bc04b

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 autentication providers can be found in the Realm Object Server configuration.yml file.

Password

  • Username/Password authentication is always enabled

Google

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 does not require any configuration besides enabling the facebook provider. 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). Enabling facebook authentication is done as follows:

facebook: {}

iCloud

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

In order to access CloudKit using Realm Object Server, you will 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 then used to configure the Realm Object Server’s CloudKit authentication module for a specific Realm. The steps for these are slightly different dependending 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 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 which allows controlling which users are granted read or 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.

In the following we will discuss the technical implementation of the authorization system. The fundamental abstraction is the permission, which is 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.

Data Access

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

Realms can be accessed and changed server-side by using the Node.js API. When opening Realms using this API you need to provide a User object and sync url rather than a Realm path. You can obtain a User object from the admin token directly, or you can authenticate as an individual user by calling one of the create or login methods:

Admin-based

For server-side access, full adminstrative access is desirable. This is possible by using the special crafted admin token that is generated when you start the server:

Linux:

cat /etc/realm/admin_token.base64

On macOS the token is stored in the realm-object-server folder within the zip:

cat realm-object-server/admin_token.base64

This can be used to synchronously construct a Realm.Sync.User object which can be passed into the Realm constructor to open a connection to any Realm on the server-side.

// Open a Realm using the admin user
var adminToken = '3x4mpl3T0k3n…';
var adminUser = Realm.Sync.User.adminUser(adminToken);
var realm = new Realm({
  sync: {
    user: admin_user,
    url: 'realm://object-server-url:9080/~/my-realm',
  },
  schema: [{...}]
});

Note that this bypasses the authentication service of the Realm Object Server. That means new Realms created in this way won’t be tracked internally, leaving them unavailable for notifications via the global listener API.

We only recommend the admin token for server-side use, such as querying or writing to existing synchronized Realms or with the event-handling.

For all other use-cases, use the authentication bound to individual users.

User-based

You can authenticate as an individual user via username/password by calling one of the create or login methods. Authentication via any other of the configured providers is possible via registerWithProvider. This method doesn’t differentiate explicitly between account creation and logging into an existing account. Accounts are automatically created if necessary. These user-based API methods work asynchronous.

The code sample below demonstrates logging in as a user via username and password to access the private Realm my-realm.

// Open a Realm as an individual user using username/password-based authentication
Realm.Sync.User.login('http://object-server-url:9080/', 'username', [email protected]$w0rd', (error, user) => {
  if (!error) {
    var realm = new Realm({
      sync: {
        user: user,
        url: 'realm://object-server-url:9080/~/my-realm',
      },
      schema: [{...}],
    });

    realm.write(() => {
      ...
    });
  }
});

The following code sample shows how to authenticate via Facebook to access the private Realm my-realm.

// Open a Realm as an individual user using Facebook as identity provider
const fbAccessToken = 'acc3ssT0ken...';
Realm.Sync.User.registerWithProvider('http://object-server-url:9080/', 'facebook', fbAccessToken, (error, user) => {
  if (!error) {
    var realm = new Realm({
      sync: {
        user: user,
        url: 'realm://object-server-url:9080/~/my-realm'
      },
      schema: [{...}],
    });

    realm.write(() => {
      ...
    });
  }
});

Using Synced Realms

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.object('MyObject');

Event Handling

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

An exclusive feature of the Enterprise Edition of Realm Object Server is event handling capabilities. This functionality is provided in the server-side Node.js SDK, that is also used to access data managed by the Realm Object Server. The Node.js SDK offers a global event listener API which hooks into the Realm Object Server and allows you to observe changes across Realms. This could mean listening to every Realm for changes or Realms that match a specific pattern. For example, if your app architecture separated user settings data into a Realm unique for each user where the virtual path was /~/settings, then a listener could be setup to react to changes to any user’s settings Realm.

Whenever a change is synchronized to server, it will trigger a notification which allows you to run custom server-side logic in response to the change. The notification will inform you about the virtual path of the updated Realm and provide the Realm object and fine-grained information on which objects changed. The change set provides the object indexes broken down by class name for any inserted, deleted, or modified object in the last synchronized transaction.

The sample below listens for changes to a user-specific private Realm at the virtual path /~/private. It will look for updated Coupon objects in these Realms and verify their code, if it wasn’t verified yet and write the result of the verification into the isValid property of the Coupon object.

var Realm = require('realm');

var dirPath = '.'; // the Realms will be stored into a subdirectory `realms` within this path
var adminToken = '3x4mpl3T0k3n…';
var adminUser = Realm.Sync.User.adminUser(adminToken);
Realm.Sync.addListener(syncBaseUrl, adminUser, regex, 'change', handleChange);

// The regular expression you provide restricts the observed Realm files to only the subset you
// are actually interested in. This is done in a separate step to avoid the cost
// of computing the fine-grained change set if it's not necessary.
var regex = '/^\/([0-9a-f]+)\/private$/';

// The handleChange callback is called for every observed Realm file whenever it
// has changes. It is called with a change event which contains the path, the Realm,
// a version of the Realm from before the change, and indexes indication all objects
// which were added, deleted, or modified in this change
function handleChange(changeEvent) {
  // Extract the user ID from the virtual path, assuming that we're using
  // a filter which only subscribes us to updates of user-scoped Realms.
  var matches = changeEvent.path.match(/^\/([0-9a-f]+)\/private$/);
  var userId = matches[1];

  var realm = changeEvent.realm;
  var coupons = realm.objects('Coupon');
  var couponIndexes = changeEvent.changes.Coupon.insertions;

  for (var couponIndex in couponIndexes) {
    var coupon = coupons[couponIndex];
    if (coupon.isValid !== undefined) {
      var isValid = verifyCouponForUser(coupon, userId);
      // Attention: Writes here will trigger a subsequent notification.
      // Take care that this doesn't cause infinite changes!
      realm.write(function() {
        coupon.isValid = isValid;
      });
    }
  }

  // Always explicitly close the Realm when you're done!
  realm.close();
}

Note that Realms can be only observed when they are tracked in the admin-Realm. This can be achieved by always creating them via authentication bound 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.

Backups

To provide the most basic level of server availability, Realm provides two backup systems: a manual backup and continuous backup. The manual backup is included in all versions of Realm Mobile Platform via a command-line utility. This can be triggered during server operations to create a copy of the data in Realm Object Server.

To reduce the risk of data loss further, the Enterprise Edition of Realm Mobile Platform offers continuous backup. The system operates as a backup server running alongside the main process in Realm Object Server to continuously watch for changes across all synchronized Realms and asynchronously send changes to one or more backup clients. Compared to the manual backup, this greatly reduces the time window for data loss since the backup is automatically kept up-to-date.

For more details on how to utilize the backup functionality, read Backup.

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

Realm provides two backup systems, a continuous backup and a manual backup. The continuous backup is a client-server system and the manual backup is a single executable that makes a local backup.

The manual and the continuous backup create similar results; a directory of Realms from which a Realm Object Server can be restarted after a server crash with disk failure. The backed up data comprises the user Realms, all user account information, and all other internal information used by the Realm Object Server. Backups can take place on a running object server.

Continuous Backup

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

The continous backup is part of the Enterprise edition. See above for upgrading to the Enterprise edition. The continuous backup consists of backup servers and backup clients. A backup server monitors the state of a running Realm Object Server. One or more backup clients connect to a given backup server. The backup server will continuously update all connected backup clients giving them a slightly delayed copy of the server state.

Backup Server
Installation

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.

Installation

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.
Network Security

The continuous backup system communicates without encryption and authenticated access. It is recommended to run the backup system behind a firewall.

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/user_data/__admin.realm
md5sum /var/lib/realm/object-server-backup-client/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/user_data/__admin.realm
md5sum /var/lib/realm/object-server-backup-client/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/user_data/__admin.realm
md5sum /var/lib/realm/object-server-backup-client/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.

Performing A Manual Backup

realm-backup is an executable command used as

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 by copying the TARGET directory of the latest backup into SOURCE while the server is stopped. The server may only be started after the backup has been fully copied into SOURCE.

Client Recovery From A Backup

Since the clients communicate with the server continuously, data could have been exchanged between a client and a server after the latest backup. When a server recovers from its latest backup, there could be an inconsistency in the synchronization between some clients and the recovered server. The Realm Object Server system can detect this inconsistency

In the case of inconsistencies, the client will receive, from the server, one of the error messages

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

After one of these errors, the client Realm cannot participate in further synchronization with the server.

The only way to continue synchronization with the server is to start all over from an empty Realm and let the server deliver data. Starting from an empty Realm could lead to data loss since the the original client Realm could contain data unknown to the server.

It is highly recommended to either use the continuous backup system or to run the manual backup frequently to avoid a situation where synchronization must be restarted.