Realm Blog

RealmPop: Open Source Realtime Gameplay Project

by /

RealmPop is a simple retro multi-player game we developed for our Realm World Tour. It lets iPhone, iPad, and Android devices connect to a Realm Object Server instance and play against each other, and we’ve made it open source so you can download it and take it for a spin yourself!

We tried to find a balance between a very simple demo that would be understandable even to an audience who have never touched Realm before, and an engaging project that both keeps people excited and shows a wide range of Realm features.

Great as the event demo was (just ask all the people who volunteered to play the game live on stage) we could not add too many features to it, because we were demoing everything live (we’re only human after all :)

Hence: RealmPop 1.1!

Today we are releasing an update to RealmPop to address a few issues we discovered during the tour, and to add a more-involved server-side component where the real power of the Realm Mobile Platform lays.

The updated project shows you how to develop part of the game’s logic on the server with the help of our Node.js SDK and compliment the functionality on the mobile clients. We’ve sprinkled comments all around the code too, you’re welcome :)

schema

We’ve updated RealmPop’s README with detailed instructions on how to:

  • install & run Realm Mobile Platform
  • configure & run the RealmPop server app
  • and run the iOS and Android games

So what are you waiting for? Head to the repo https://github.com/realm/RealmPop right now, follow the README and have the RealmPop server and mobile apps running in no time!

PS: What would you like to see next in RealmPop? Server bots? React Native? More advanced multiplayer features? Let us know on twitter and tag with #realmpop.

Read more

Realm ObjC & Swift 2.6: Async Open Realm, Admin Flag, Compact On Launch & Bug Fixes!

by /

We’re releasing version 2.6 of Realm Objective‑C and Realm Swift today. In this release, we’re introducing powerful new APIs to asynchronously open Realms, retrieve the administrative status of Sync Users, compact Realms on first access and applying a few bug fixes to keep your apps running strong.

Asynchronously Open Realms

This release introduces an API to asynchronously open a Realm and deliver it to a block on a given queue.

This performs all work needed to get the Realm to a usable state (such as running potentially time-consuming migrations) on a background thread before dispatching to the given queue. For example:

let config = Realm.Configuration(schemaVersion: 1, migrationBlock: { migration, oldSchemaVersion in
  // potentially lengthy data migration
})
Realm.asyncOpen(configuration: config) { realm, error in
  if let realm = realm {
    // Realm successfully opened, with migration applied on background thread
  } else if let error = error {
    // Handle error that occurred while opening the Realm.
  }
}

In addition, synchronized Realms wait for all remote content available at the time the operation began to be downloaded and available locally.

The default behavior for synchronized Realms is to provide instant access, even when offline, and to incrementally sync data from the Realm Object Server. However, some apps benefit from having the latest state available before presenting it in the UI or performing some operation. For these situations, you may use the asyncOpen method to be vended a Realm only when it has been completely downloaded. For example:

let config = Realm.Configuration(syncConfiguration: SyncConfiguration(user: user, realmURL: realmURL))
Realm.asyncOpen(configuration: config) { realm, error in
  if let realm = realm {
    // Realm successfully opened, with all remote data available
  } else if let error = error {
    // Handle error that occurred while opening or downloading the contents of the Realm.
  }
}

Sync User isAdmin property

{RLM}SyncUser now has an isAdmin property indicating whether the user is a Realm Object Server administrator.

Exposing this information makes it easier for you to write code that can manipulate arbitrary synchronized Realms since you can authoritatively determine if a user has administrative access to all Realms on a Realm Object Server instance.

For example:

SyncUser.logIn(with: .usernamePassword(username: "admin", password: "💯secure"),
               server: serverURL) { user, error in
  if let user = user {
    // can now open a synchronized Realm with this user
    // true if the user is an administrator on the ROS instance
    user.isAdmin == true
  } else if let error = error {
    // handle error
  }
}

Compact On Launch

Realm’s architecture means that file sizes are always larger than the latest state of the data it contains. See our docs on Threading for some of the reasons why this architecture enables some of Realm’s great performance, concurrency and safety advantages.

Additionally, to avoid making expensive system calls to expand the size of a file very frequently, Realm files generally aren’t shrunk at runtime, instead growing by distinct size increments, and new data being written within the free space tracked inside the file.

However, there are cases in which a significant portion of a Realm file is comprised of free space. So this release adds a shouldCompactOnLaunch block property to a Realm’s configuration object to determine if the Realm should be compacted before being returned. For example:

let config = Realm.Configuration(shouldCompactOnLaunch: { totalBytes, usedBytes in
  // totalBytes refers to the size of the file on disk in bytes (data + free space)
  // usedBytes refers to the number of bytes used by data in the file

  // Compact if the file is over 100MB in size and less than 50% 'used'
  let oneHundredMB = 100 * 1024 * 1024
  return (totalBytes > oneHundredMB) && (Double(usedBytes) / Double(totalBytes)) < 0.5
})
do {
  // Realm is compacted on the first open if the configuration block conditions were met.
  let realm = try Realm(configuration: config)
} catch {
  // handle error compacting or opening Realm
}

Under the hood, the compaction operation reads the entire contents of the Realm file, rewrites it to a new file at a different location, then replaces the original file. Depending on the amount of data in a file, this may be an expensive operation.

We encourage you to experiment with the numbers to identify a good balance between performing the compaction too often and letting Realm files grow too large.

Finally, if another process is accessing the Realm, compaction will be skipped even if the configuration block’s conditions were met. That’s because compaction cannot be safely performed while a Realm is being accessed.

Setting a shouldCompactOnLaunch block is not supported for synchronized Realms. This is because compaction doesn’t preserve transaction logs, which must be kept for synchronization.

Other Enhancements

  • Speed up case-insensitive queries on indexed string properties.
  • Add RLMResults’s collection aggregate methods to RLMArray.
  • Add support for calling the aggregate methods on unmanaged Lists.

Bug Fixes

  • Fix a deadlock when multiple processes open a Realm at the same time.
  • Fix value(forKey:)/value(forKeyPath:) returning incorrect values for List properties.

iOS 7 Support

We will continue to support a minimum target iOS version of 7.0 as long as we can, but will be increasing the minimum target iOS version to 8.0 in a future release.


Thanks for reading. Now go forth and build amazing apps with Realm! As always, we’re around on the Realm Forums, Stack Overflow, GitHub, or Twitter.

Read more

Realm Java 3.1: Object Notifications, Backup Recovery and Reverse Relationships

by /

Realm files read or written by this version cannot be opened with previous versions of Realm. Existing files will automatically be upgraded when they are opened. Please be careful about shipping updates to your existing apps!

We’re releasing version 3.1 of Realm Java today, and with it introducing better backup recovery for synchronized Realms, fine-grained object notifications for all Realms, and initial support for reverse relationships. Read on for all the details.

Fine-grained Object Notifications

In Realm Java 3.0, we released fine-grained collection notifications that made it possible to get detailed information about changes to collections. In 3.1, we extend that capability to single object notifications as well with the new RealmObjectChangeListener interface and the ObjectChangeSet class.

Person p = realm.where(Person.class).findFirst();
p.addChangeListener(new RealmObjectChangeListener<Person>() {
   @Override
   public void onChange(Person person, ObjectChangeSet changeSet) {
       if (changeSet.isDeleted()) {
           hide(); // Object was deleted
       } else {
           // Use information about which fields changed to only update part of the UI
           if (changeSet.isFieldChanged("name")) {
               updateName(person.getName());
           }
       }
   }
});

In past releases, single object notifications have had a lot of false positives, in the sense that the listener would trigger even though nothing had changed. This has also been fixed in 3.1, so now single object notifications, fine-grained or not, should only trigger if something in the object changed.

Better Backup Recovery

When your servers go down, you need a plan to recover. That’s why the Realm Mobile Platform has offered the ability to backup your data for a few months now. Under normal conditions, Realm’s synchronization engine works by transferring just the specific operations. When the Realm Object Server confirms the receipt of new operations, the local logs are cleaned up. This helps keep your app’s disk usage small and Realm blazing fast ⚡️.

Furthermore, because Realm is an offline-first database, if your Realm Object Server is down for whatever reason, all your local data stays available.

However, if you need to recover from a backup on your server, your clients will receive a “client reset” error via the sessions error handler. Note that you may continue to use the local Realm as you normally would, but that any subsequent changes, or changes made after the last backup point, will be lost.

Once you receive a “client reset” error, you could inform the user about the situation, stop accessing the Realm and redownload the Realm from the server at the latest backed up version. The ClientResetRequiredError class contains information and methods you can call for manually cleaning up the previous local version of the Realm.

If you choose to not handle the client reset error immediately, the next time your app launches, the previous local version of the Realm will be deleted and redownloaded from the server at the latest backed up version automatically on first access.

final SyncConfiguration config = new SyncConfiguration.Builder(user , url)
       .errorHandler(new SyncSession.ErrorHandler() {
           @Override
           public void onError(SyncSession session, ObjectServerError error) {
               if (error.getErrorCode() == ErrorCode.CLIENT_RESET) {
                   ClientResetRequiredError err = (ClientResetRequiredError) error;
                   closeRealm();
                   err.executeClientReset(); // Manually do the reset
                   err.getBackupFile(); // Reference to backed up file
               } else {
                   // Handle other errors
               }
           }
       })
       .build();

Inverse Relationships (BETA)

In Realm relationships between objects are bidirectional, which means that if you have a reference from Person to his/her Dog, then Realm automatically establishes a relationship in the other direction as well, and will automatically maintain it.

This inverse relationship is normally hidden in your model classes, but today we are shipping a new @LinkingObjects annotation that can make that inverse relationship visible so you can navigate through it.

In order to define an inverse relationship you need to do the following:

Add a RealmResults field with the generic type of the parent object. The field must be final. Realm will automatically fill it out for managed objects. Un-managed objects do not support inverse relationships. Add the @LinkingObjects annotation with the name of the field on the parent object that points to the model class defining the inverse relationship.

Take this example:

public class Person extends RealmObject {
   public String name;
   public int age;
   public Dog dog;
}  

public class Dog extends RealmObject {
   public String name;

   @LinkingObjects("dog")
   public final RealmResults<Person> owners = null;
}

// Use the inverse relationship 
Dog dog = realm.where(Dog.class).findFirst();
dog.owners.size(); // Find number of owners
dog.owners.first(); // Get a reference to the owner of the dog

The true power of reverse relationships will come when you can query across the inverse relationship and we are working hard on adding that for the next release.

Because implementation of queries has not yet been completed, we have marked the @LinkingObjects annotation as @Beta and would love your feedback on this feature.

File format upgrade

In 3.1 the internal Realm file format has been changed. Older Realm files will automatically be upgraded when opened, but doing so means that they no longer can be read by older versions of Realm.

See the CHANGELOG for the full list of changes.


Thanks for reading. Now go forth and build amazing apps with Realm! As always, we’re around on Stack Overflow, GitHub, or Twitter.

Read more

Realm World Tour: That’s a Wrap Time for Round Two!

by /

The first leg of the Realm World Tour just wrapped up, and thanks to the tremendous energy of everyone in the Realm community who participated, it was amazing…check out the highlights!

We put in thousands of miles, visiting 23 different cities over the course of 2 months, meeting thousands of you face to face, and getting you started building apps with the Realm Platform. We laughed, we ate pizza, we tested code, we played games, and best of all we got to hear from you about what you are doing with Realm! We had so much fun, we’ve already started to thinking about what’s next (see below).

 

We couldn’t have done any of this without the help of our fantastic world tour hosts who opened up their offices, event spaces, and restaurant recommendations to us! A big thanks to all the local companies, hosts, and meetups for helping us make the tour happen!

host-logos

A few special shout-outs to:

  • Q42 in Amsterdam for the most amusing host space, which includes a slide that tweets a video of you. https://twitter.com/q42glijbaan
  • Paris hosted by Deezer for the fastest Realm Pop player, who won live on stage with a time of 1.4 seconds!
  • Dallas hosted by BottleRocket for coolest Star Wars memorabilia! ;)
  • Chicago hosted by Trunk Club for having the most awesome office space, and delicious beers on tap!

Announcing the next leg of the Realm World Tour

Bringing the Realm Platform message to 23 cities was so much fun, we want to bring it to a few more. So we’ve started to plan the next leg of the Tour, and we need your help: If you’d like us to come your way, tweet us @Realm with hashtag #RealmWorldTour and hashtag of your city (e.g., #SanFrancisco). Then get the rest of the devs in your city who want to attend Realm Tour to do the same. We definitely want to prioritize the cities where we know we’ll get a great turnout.

Stay in the loop on Realm events and more

If you’re not already on the Realm list, add your email here. We’ll keep you up-to-date on Realm events, content, and product news.

Read more

Realm ObjC & Swift 2.5: Query Improvements, Swift 3.1 Binaries & Bug Fixes!

by /

Realm files read or written by this version cannot be opened with previous versions of Realm. Existing files will automatically be upgraded when they are opened. Old files can still be opened and files open in read-only mode will not be modified. Please be careful about shipping updates to your existing apps!

We’re releasing version 2.5 of Realm Objective‑C and Realm Swift today. In this release, we’re empowering queries with support for diacritic-insensitive string search, adding the ability to compare nested objects against NULL and applying a large number of bug fixes to keep your apps running strong.

We’re also now producing Swift binaries for Swift 3.0, 3.0.1, 3.0.2 and 3.1.

If using synchronized Realms, the Realm Object Server must be running version 1.3.0 or later.

Diacritic-Insensitive String Queries

You may now use the [d] modifier on string comparison operators to perform diacritic-insensitive comparisons. This modifier can even be combined with the case insensitive modifier ([c]).

For example:

  • ==[d] 'u' will match on ü
  • BEGINSWITH[d] 'e' will match on étoile
  • CONTAINS[d] 'n' will match on Piñata
  • ENDSWITH[d] 's' will match on diaçrïtičş
  • ENDSWITH[cd] 'É' will match on café

Note that this cannot be applied to LIKE comparisons.

Multi-level object equality comparisons against NULL

You may now query for multi-level object equality comparisons against NULL. For example:

class CircleObject: Object {
  dynamic var data = ""
  dynamic var next: CircleObject?
}
let realm = try Realm()
realm.objects(CircleObject.self).filter("next.next != nil AND next.next.next = nil")

Other Enhancements

  • Explicitly mark [[RLMRealm alloc] init] as unavailable.
  • Include the name of the problematic class in the error message when an invalid property type is marked as the primary key.

Bug Fixes

  • Fix incorrect column type assertions which could occur after schemas were merged by sync.
  • Eliminate an empty write transaction when opening a synced Realm.
  • Support encrypting synchronized Realms by respecting the encryptionKey value of the Realm’s configuration.
  • Fix crash when setting an {NS}Data property close to 16MB.
  • Fix for reading {NS}Data properties incorrectly returning nil.
  • Reduce file size growth in cases where Realm versions were pinned while starting write transactions.
  • Fix an assertion failure when writing to large RLMArray/List properties.
  • Fix uncaught BadTransactLog exceptions when pulling invalid changesets from synchronized Realms.
  • Fix an assertion failure when an observed RLMArray/List is deleted after being modified.

A Note About Xcode 8.3

We typically produce Objective‑C binaries using the latest stable Xcode version, which as of this week is Xcode 8.3. However, we’ve discovered (rdar://31302382) that Xcode 8.3 produces binaries with bitcode slices about four times as large as previous Xcode versions! This brings the Realm Objective-C framework for iOS from its usual 55MB to about 158MB! So we’ve decided to continue building the Objective-C framework using Xcode 8.2. You may choose to build Realm Objective-C from source using Xcode 8.3, and your end users won’t be affected because bitcode is stripped from the binaries when apps are served from the App Store.


Thanks for reading. Now go forth and build amazing apps with Realm! As always, we’re around on Stack Overflow, GitHub, or Twitter.

Read more

BYO Authentication: Connect Your Users to the Realm Mobile Platform

by /

We’re making it easier than ever to integrate your existing systems with a modern mobile app, by introducing Custom Authentication on the Realm Mobile Platform. With a few lines of JavaScript, you can bring your own authentication to Realm, allowing your users can log in with their existing credentials and begin using any app built on the Realm Mobile Platform. Using Custom Authentication, you’ll be able to build modern mobile apps with single-sign on (SSO) capabilities, and you can even mobilize your whole legacy backend by integrating our new data connector API, so that your users get access to the data and capabilities they expect.

Legacy systems put you in a double bind when you want to build a new, useful mobile app. If you use your existing backends, it’s likely to be incredibly hard to build the new features your users demand — features that require streaming lots of data from many sources, which tend to overwhelm APIs built for a calmer web. But migrating your API to a more developer-friendly platform is likely to be even harder, exposing you to new security risks in untested authentication APIs, and forcing you to solve problems that you thought you already put behind you, this time in a new language and framework.

Wouldn’t it be great to keep the hard work you put into your API, while also getting all the modern development tools that make it easier to build better apps? That’s what bring-your-own authentication does for the Realm Mobile Platform. You get to integrate Realm with your trusted legacy authentication APIs, so that your users simply bring their username and password (or any other tokens or credentials) to your mobile app, and the Realm Mobile Platform handles the work of authenticating them against your existing API. Your developers don’t just avoid rewriting all their auth code: they also get realtime data sync, offline-first capabilities, and enterprise-grade data connectors for your existing databases and backends — all benefits that you get from building your app on the Realm Mobile Platform.

Here’s what it looks like in practice: you just write one short JavaScript file, then add a line to your configuration.yml file:


module.exports = function(deps) {
  return class FooAuthProvider extends deps.BaseAuthProvider {
    // This is used by the ROS when it loads the available
    // authentication providers. This function is required.
    static get name() {
      return 'custom/fooauth';
    }

    // This is used by ROS when it parses the configuration
    // file, to ensure that required default options are
    // available. This function is optional.
    static get defaultOptions() {
      return {
        auth_server: 'https://my.auth.server.example',
      }
    }

    constructor(name, options, requestPromise) {
      super(name, options, requestPromise);

      // Here you can set your instance variables as usual
      this.httpMethod = 'GET';
    }
  };
}

Now we get to the substance of the authentication provider, where we’ll make a request to your authentication API using the credentials that the user provided:


verifyIdentifier(req) {
  // The token submitted by the client
  const token = req.body.data;
  // The client SDKs also support sending additional information
  // in the form of a map/dictionary. This is accessible through
  // the `req.body.user_info` key.

  // The information required to reach your API server that can
  // validate the token. Obviously, this assumes a REST-like API.
  // Please note that `this.options` comes from the configuration file or
  // `defaultOptions()` method defined above. Similarly, `this.httpMethod` is
  // an instance variable defined in the constructor above.
  const httpOptions = {
    uri: `${this.options.authServer}/api/auth?token=${token}`,
    method: this.httpMethod,
    json: true,
  };

  return this.request(httpOptions)
    .catch((err) => {
      // Please see src/node/services/problem/http_problem.js
      // for other error cases
      throw new problem.HttpProblem.Unauthorized({
        detail: `Something bad happened: ${err.toString()}`,
      });
    })
    .then((result) => {
      // This userID has to be unique, and will be used to either
      // - create a user in the ROS
      // - login the user, if it already exists
      return result.userID;
    });
}

By combining easy authentication with the data connector API, you’ll also be able to connect your apps to the data stored behind your legacy systems. Whether your API is as old as SOAP or just as request-driven as REST, the Realm Mobile Platform’s data connector API will give your users real-time, streaming access to their data they need, and your developers get to use the modern, reactive features of the Realm Mobile Database. You’ll be able to build great app experiences quickly, without trying to teach your older, legacy systems the new tricks they’d need to deal with the scale demands of mobile apps.

To start moving faster on your own mobile journey, just jump into the documentation for custom authentication. If you’d like to learn more about how to completely integrate the Realm Mobile Platform with your legacy databases as well, check out our new PostgreSQL data connector API.

Read more

Making PostgreSQL Realtime

by /

PostgreSQL is one of the most powerful and popular databases in use today, and is increasingly used for systems of record at all types of organizations. This works well for many use cases, but things get difficult when you try to build a modern, reactive app connected to your Postgres database. Postgres is fast, but it’s just not designed for realtime, reactive mobile apps.

Today we’re excited to introduce a solution: Realm’s new PostgreSQL Data Connector. This new connector creates a simple two-way bridge between Postgres and the Realm Mobile Platform, effectively making Postgres realtime for mobile apps. Data flows reliably and in a fault-tolerant manner between Postgres and the Realm Platform, which then handles realtime sync with your mobile apps automatically. This means changes made on mobile clients are automatically reflected back to your Postgres database in realtime, and data changes made in Postgres sync in realtime with client-side databases. You can now easily make truly reactive mobile apps with PostgreSQL and Realm.

Realm Mobile Platform as an alternative to REST APIs

The Realm Mobile Platform replaces traditional methods of using REST APIs to get data in and out of backend systems for use in a mobile context. Our automatic realtime sync service efficiently syncs only what has changed in the data model without the need for manual data requests or bandwidth-hogging polling. Realm automatically handles the realtime sync of your native objects—without the need for JSON—between clients and the Realm Object Server (the server-side component of the Realm Mobile Platform). The Realm Object Server can then provide the API integration point between your mobile application and PostgreSQL database to consolidate API management in the backend, where network issues are not a concern. This architecture reduces the number of API calls that each device must make and reduces the need for complex idempotent APIs that can handle unreliable network connectivity.

PostgreSQL Data Connector Demo

Here’s a video to show you an example of how we can link Postgres and Realm Mobile Platform:

Using sample data from a fictional DVD Rental company, we’re able to modify inventory levels via a mobile app or within Postgres and see those changes sync in realtime. It’s a simple example of how Realm can dramatically simplify making Postgres realtime for your applications.

Realm connects your mobile app and Postgres with automatic realtime sync.

We’re excited to show you how Realm can work for you in your environment. You can visit GitHub for the code and an in-depth overview of how to connect the Realm Mobile Platform and PostgreSQL to create reactive, realtime mobile applications with data stored in PostgreSQL.

Read more

Realm Everywhere, with JavaScript: Universal Node.js Support

by /

JavaScript is probably the hardest working programming language in the world these days, and at Realm, we’re big fans. We love it because it fits great with Realm’s reactive architecture, and because JavaScript is virtually omnipresent. We’ve made it a key part of our platform, so that any developer with JS skills can use Realm. We started by shipping support for the Realm Mobile Database to React Native, and then we brought Realm to Node.js on Linux and macOS, which helps power the Realm Mobile Platform. And today we’re happy to announce Node.js support for Windows, meaning that you can use Realm wherever you can run JavaScript.

Realm now supports not only React Native, but also Node.js on Windows, Linux and macOS. Just like with Realm on mobile, you get all the advantages of the Realm Mobile Database — enabling you to easily and performantly persist any data you need to build your app. We’re also hard at work building support for the Realm Mobile Platform on Win32, so that you’ll be able to sync data with ease and build exciting real-time, collaborative apps using JavaScript.

Realm isn’t just easier to use. It also pairs with JavaScript’s advantages to enable better app experiences. Realm’s reactive principles mean data is automatically refreshed as it changes, making it fit beautifully in an event-driven architecture. It’s also cross-platform, so that you can take advantage of JavaScript’s enormous reach in order to deliver apps to your customers, no matter what devices they use. And finally, our universal support for Node.js means you can even use it for server-side use cases — like using Realm and Node.js to do interprocess communication on a webserver.

We’re making it easier to build the coolest, newest, best apps, on every platform, on any device. Today, we’ve taken another big leap in our journey to being a truly universal data platform, and we can’t wait to see what you build with it. Jump into the Realm JS documentation to get started with the Realm Mobile Database.

Read more

Integrating Azure Authentication with Realm

by /

Today we’re pleased to introduce a new method of client authentication with Azure Active Directory for our community of .NET developers using the Realm Mobile Platform. Now organizations can create reactive apps that work with Microsoft App Service Authentication / Authorization for simplified sign on and identity management.

Setting up Azure Active Directory

Each Azure account has a default AD instance pre-created. For the purposes of this post, we’ll use that one, but you can easily create a separate one by following a tutorial similar to this one.

Once you have the directory setup, create a new user by clicking Add a User in the Quick tasks pane:

add-user

Setting up the Application

To authenticate on the device, we’ll need to setup an Application. Go to App registrations and press Add:

add-app

Specify Name, and set Application Type to Native. The Redirect URI will be used by the client library to identify when the login flow has completed, so it has to be a valid Url, but doesn’t need to be a physical endpoint (as we’ll never load it).

app-details

Once the application is created, take a note of its Application Id, as we’ll need it later.

Authenticating on the client

For the client authentication, we’ll use the Active Directory Authentication Library (ADAL) package. It makes obtaining an access token fairly straightforward:

// Call Login() based on your business logic (e.g. when a user presses a button)

const string ApplicationId = "application-id-from-portal";
const string CommonAuthority = "https://login.windows.net/common";
const string RedirectUri = "redirect-uri-from-portal";

public async Task<User> Login()
{
  var authContext = new AuthenticationContext(CommonAuthority);
  var response = await authContext.AcquireTokenAsync("https://graph.windows.net",
                                                     ApplicationId,
                                                     RedirectUri,
                                                     new PlatformParameters(this));

  // We'll use response.AccessToken later
  return null;
}

The last argument of authContext.AcquireTokenAsync is a platform-specific implementation of IPlatformParameters, so if you’re using a shared project to perform the authentication, you could either obtain it via dependency injection, or add an #if PLATFORM directive. Once Login is called, the user will be presented with a webview where they can enter their credentials:

user-login

After successful authentication, the response object will contain some basic user information as well as an access token, that we’ll use to authenticate against the Realm Object Server.

Integrating with Realm

To authenticate against Realm Object Server, we’ll first need to enable the Azure Active Directory provider. Open up configuration.yml, uncomment the azuread section and fill in the Directory Id, that can be found in the Properties section:

# This enables authentication via an Azure Active Directory access token for a specific app.
azuread:
  # The Directory Id as retrieved from the Active Directory properties in the Azure portal.
  tenant_id: 'active-directory-id'

Now head back to the client application’s Login method to wrap it up:

const string ROSUrl = "http://127.0.0.1"; // Or the address where ROS is hosted

public async Task<User> Login()
{
  // same as above
  // var response = (...);

  var credentials = Credentials.AzureAD(response.AccessToken);
  var user = await User.LoginAsync(credentials, ROSUrl);
  return user;
}

What’s next at Realm

We’re excited to expand our support for the Microsoft ecosystem and our announcement today is one small step on that journey. This year, we’ve announced Realm Xamarin 1.0, Windows Desktop support, and easy ways to get your Realm Object Server (part of the Realm Mobile Platform) up and running on Azure. Stay tuned for more coming in 2017!

Read more

Realm Java 3.0: Collection Notifications, Snapshots and Sorting Across Relationships

by /

We’re releasing version 3.0 of Realm Java today. In this release we have enabled sorting across relationships and we’re giving our live collections RealmResults and RealmList a whole lot more life by adding fine-grained collection notifications, so that your app can respond to elements being added, deleted and modified.

Fine-grained Collection Notifications

Up until now, Realm has provided a single shared RealmChangeListener interface that could be registered on our Realm, RealmObject and RealmResults classes. However that interface came with a limitation. It could not provide information about what had changed, only that something had changed. In many cases that was good enough, but in some cases it was not. The most common example being if you wanted to animate changes in a RecyclerView. Due to Realm’s live-updating objects, the solution up until now have been to use a combination of realm.copyFromRealm() and the DiffUtil class from the Android Support Library. This was hardly ideal.

Today, we are shipping fine-grained collection notifications. It is a new interface that can be registered on RealmResults and will provide information about exactly which objects were added, deleted or changed. This will enable you to just refresh those elements that actually did change, making for a much nicer and responsive UI.

We’ve also updated our Android Adapters library, so the RealmRecyclerViewAdapter will now automatically use the fine-grained notifications for smoother animations. Here’s what it looks like in practice, compared to using RecyclerView without collection notifications:

private final OrderedRealmCollectionChangeListener<RealmResults<Person>> changeListener = new OrderedRealmCollectionChangeListener() {
    @Override
    public void onChange(RealmResults<Person> collection, OrderedCollectionChangeSet changeSet) {
        // `null`  means the async query returns the first time.
        if (changeSet == null) {
            notifyDataSetChanged();
            return;
        }
        // For deletions, the adapter has to be notified in reverse order.
        OrderedCollectionChangeSet.Range[] deletions = changeSet.getDeletionRanges();
        for (int i = deletions.length - 1; i >= 0; i--) {
            OrderedCollectionChangeSet.Range range = deletions[i];
            notifyItemRangeRemoved(range.startIndex, range.length);
        }

        OrderedCollectionChangeSet.Range[] insertions = changeSet.getInsertionRanges();
        for (OrderedCollectionChangeSet.Range range : insertions) {
            notifyItemRangeInserted(range.startIndex, range.length);
        }

        OrderedCollectionChangeSet.Range[] modifications = changeSet.getChangeRanges();
        for (OrderedCollectionChangeSet.Range range : modifications) {
            notifyItemRangeChanged(range.startIndex, range.length);
        }
    }
};

Fine-grained collection notifications work just like all other Realm listeners, so if a query was executed asynchronously (for example, by using findAllAsync()), then the fine-grained changeset will also be calculated on a background thread before delivering the result to the UI thread, without the memory overhead of using DiffUtil to calculate what’s changed.

Collection Snapshots

One of the key design principles for Realm is our concept of “live” objects and collections. It means that if you create a RealmResults from a query, it will stay up-to-date whenever the underlying data changes. This is very effective in any reactive architecture, where you can just register a RealmChangeListener and be notified when the query result is updated.

However in some cases, this “live” nature can lead to unexpected problems when looping over a live collection. Take this code for example:

RealmResults<Guest> uninvitedGuests = realm.where(Guests.class)
  .equalTo("inviteSent", false)
  .findAll(); 

for (i = 0; i < uninvitedGuests.size(); i++) {
  realm.beginTransaction()
  uninvitedGuests.get(i).sendInvite();
  realm.commitTransaction();
}

Here, you make a query for all guests not invited, as you want to send an invite to them. If uninvitedGuests were a normal ArrayList, this would work as you expect and all guests would receive an invite.

However because RealmResults are live updated, and because you execute transactions inside the for-loop, Realm will automatically update the RealmResults after each iteration. This would in turn remove the guest from the uninvitedGuests list causing the entire array to shift, but because it is the for-loop keeping track of the current index, this would now be at the wrong position. The result was that only half the guests would receive an invite. Clearly not ideal.

Two solutions existed:

// 1. Wrap the entire loop in a transaction
realm.beginTransaction()
for (i = 0; i < uninvitedGuests.size(); i++) {
  uninvitedGuests.get(i).sendInvite();
}
realm.commitTransaction();

// 2. Loop the list backwards
for (int i = uninvitedGuests.size() - 1; i >= 0; i--) {
  realm.beginTransaction()
  uninvitedGuests.get(i).sendInvite();
  realm.commitTransaction();
}

Neither of these solutions were obvious though, so in Realm Java 0.89 we made the decision to defer all updates of RealmResults to the next looper event (by using Handler.postAtFrontOfQueue).

This had the advantage that the simple for-loop would work as expected, but it came with the price that the RealmResults could now get a little out of sync, e.g. if we deleted the guest objects instead of setting a boolean on them, they would still be present in the query result, but just as invalid objects.

realm.beginTransaction();
guests.get(0).deleteFromRealm(); // Delete the object from Realm
realm.commitTransaction();
guests.get(0).isValid() == false; // You could now get a reference to a deleted object.

This would rarely happen in practise though, so you could say we chose standard iterator behavior over staying true to core Realm architectural decisions.

In 3.0 we are revisiting this decision by making RealmResults fully live again, but to make it easier to work with live collections in simple for-loops, we’re adding a createSnapshot() method that can provide the current stable list. Simple for-loops should now use this snapshot if they intend to modify data in a loop (note that in most cases doing transactions in a loop is still an anti-pattern).

RealmResults<Person> uninvitedGuests = realm.where(Person.class).equalTo("inviteSent", false).findAll();
OrderedRealmCollectionSnapshot<Person> uninvitedGuestsSnapshot = uninvitedGuests.createSnapshot();
for (int i = 0; uninvitedGuestsSnapshot.size(); i++) {
    realm.beginTransaction();
    uninvitedGuestsSnapshot.get(i).setInvited(true);
    realm.commitTransaction();
}

Iterators will use this snapshot behind the scenes, so they continue to work in the same way you expect them to today:

realm.beginTransaction();
RealmResults<Person> uninvitedGuests = realm.where(Person.class).equalTo("inviteSent", false).findAll();
for (Person guest : guests) {
    realm.beginTransaction();
    uninvitedGuests.setInvited(true); 
    realm.commitTransaction();
}

We are doing this for a number of reasons. One of them being internal refactorings needed to support fine-grained collection notifications. The other is that it means the semantics of Realm classes are all the same since both RealmResults and RealmList are fully live, and it is easier to both reason about them and document their usage. This had caused some confusion in the past, but we believe that fully supporting and documenting the live nature of Realm classes means we can offer users the most powerful APIs.

We are aware that this change might cause some headaches in existing code bases, but this change will only affect your work if you’re performing write transactions inside simple for-loops. In every other case, your code will continue to work as normal, and we hope that you agree it is better in the long term.

Sorting across relationships

Until now, it was only possible to sort RealmResults using “direct” properties. Starting with Realm Java 3.0, you can now sort query results by properties on the other side of an objects many-to-one relationships

For example, to sort a collection of Person objects based on their dog’s age, you can now do the following:

RealmResults<Person> persons = realm.where(Person.class).findAllSorted(dog.age, Sort.ASCENDING);

We’ve also shipped a bunch of bug fixes in the last couple releases. To see the full list of changes, check out the changelog.


Thanks for reading. Now go forth and build amazing apps with Realm! As always, we’re around on Stack Overflow, GitHub, or Twitter.

Read more

Realm + Microsoft: Xamarin, Azure, and Windows Desktop

by /

Realm’s mission is to make it easier to build great apps, and we want to bring that reality to as many developers as possible. So today, we’re making it easy for Microsoft developers to use Realm to build highly-scalable, production-ready realtime apps. We’ve added new Realm Mobile Database features to Xamarin, introduced Xamarin support to the Realm Mobile Platform, and even brought the Realm Mobile Database to the Windows Desktop platform.

We’ve worked with Microsoft’s Xamarin team to build a sample app and tutorial using Xamarin and Azure that will show you just how powerful all these new tools are. Read on to see how Realm and Microsoft fit together.

Xamarin and Realm: Introducing Xamarin to the Realm Mobile Platform, plus new Realm Mobile Database features

We’ve been hard at work on Realm Xamarin — our entirely free, entirely open source client-side object database — and after the past several months shipping property (object-level) notifications, backlink support and testing, testing, testing, we’re officially releasing Realm Xamarin 1.0, and declaring it ready for production. We’re grateful to the community of developers who have helped us get here — 521 closed issues later.

But that’s not all we’ve got for Xamarin. Starting today, the Realm Mobile Platform supports Xamarin. Now, C# developers can build cross-platform reactive apps simply by connecting a Realm-backed app to the Realm Object Server. Without writing any serialization or networking code, the Realm Mobile Platform gives you everything you need to build rich, realtime experiences, by handling conflict resolution, user authentication, and customizable permissions. And because you’ve got the Realm Mobile Database storing data on the client, your users also get a first-class offline experience.

Curious what all those features add up to? Well, here’s what it looks like:

To see how easy it is to build the Draw app on your own, check out the tutorial we collaborated on with Microsoft’s Xamarin team. By the end of it, you’ll have a realtime cross-platform app built on Xamarin, syncing with a Realm Object Server deployed on Azure. You can also join our webinar on March 9th to follow along in realtime as we go through it.

If you’re already familiar with the Realm Mobile Platform, open our Realm Object Server documentation, and you can get your apps up and syncing with a single click and a few lines of code.

Realm Database Support for Windows Desktop

Finally, we’re also releasing support for the Realm Mobile Database on Windows Desktop, allowing you to run Realm on the hundreds of millions of computers that support the Win32 API. With this new release, developers receive the same benefits from using an object database and Realm’s APIs as our mobile developer communities enjoy, enabling Realm-backed Windows desktop applications and the ability to create custom tooling that can generate and view Realm data. You simply define a schema, and start using the objects you’re used to. When you’re ready to persist those objects to disk, you just include them in a write transaction, and they’re preserved in our ACID-compliant database until you need to use them again. Check out our documentation to find installation instructions, and get building today.

Start Building with Realm and Microsoft

We’re thrilled to bring new and exciting tools to such an enormous, thriving community of developers, and we can’t wait to see what you’ll build with Realm, Xamarin, and Microsoft. It’s as easy as jumping into the Realm Xamarin documentation. And if you’d like to see the new Microsoft tooling and features in action, join us in a technical webinar this Thursday, March 9th.

Read more

Realm React Native 1.0: Realm Mobile Platform Support

by /

Today, we’ve got two announcements for the React Native community. First, after nearly a year of open source collaboration, Realm React Native has reached 1.0, marking a key milestone as a powerful object database, and a foundation for great reactive apps. We’re also very excited to announce that the Realm Mobile Platform now supports React Native. With just a few lines of code, React Native developers can now build exciting new experiences on top of our realtime platform.

When we launched the beta of Realm React Native early last year, we found lots of uptake from React Native’s passionate developer community, and from companies like TaskRabbit. Because Realm is a cross-platform database, you can build apps that reuse more code, making your data layer more maintainable and less fragile. And Realm’s live objects and collection notifications mean that your app really is reactive — it responds in realtime as the Realm-backed data updates. To see how easy it is to get started, just check out our Realm React Native documentation.

But Realm is more than just a client-side database. With the release of Realm React Native 1.0, React Native developers can now build powerful new apps on top of the Realm Mobile Platform. By connecting to the Realm Object Server and then creating synced Realms in your app, your Realm-backed objects will automatically sync whenever their properties change, while still being stored locally for offline use. The Realm Mobile Platform also gives you tools for handling conflict resolution, user authentication, and customizable permissions, so that you have all you need to build compelling, collaborative experiences.

The Professional and Enterprise Editions also include Event Handling, which lets you write reactive server-side JavaScript code. Now, you can bring reactive principles across your whole codebase, ensuring that your app responds predictably whenever and wherever user data changes.

It’s easy to integrate your own React Native app with the Realm Mobile Platform. Authenticate a user, connect to the Realm Object Server, then reactively update your app’s UI with this code sample:


import React, { Component } from 'react';
import { Text } from 'react-native';
import Realm from 'realm';
import { ListView } from 'realm/react-native';

export default class DogsView extends Component {
    constructor(props) {
        super(props);
        // Initialize the component with an empty data source
        const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
        this.state = { dataSource: ds };
    }

    componentWillMount() {
        // `this.props` contains the username and password passed to the DogsView instance
        Realm.Sync.User.login('https://my-realm-server.com', this.props.username, this.props.password, (error, user) => {
            let realm = new Realm({
                schema: [ { name: 'Dog', properties: { name: 'string' } } ],
                sync: { user, url: 'realms://my-realm-server.com/~/dogs'}
            });
            // Once the user is logged in and we have a synced realm,
            // reset the DataSource with all the Dog objects in the realm.
            // Also subscribe for changes on the Dogs collection and refresh the UI when they occur
			const dogs = realm.objects('Dog');
            this.setState({ realm, dataSource: this.state.dataSource.cloneWithRows(dogs) });
			dogs.addListener(() => this.forceUpdate());
        });
    }

    render() {
        return (<ListView dataSource={this.state.dataSource} renderRow={(item) => <Text>{item.name}</Text>} />);
    }
}

To get started with the Realm Mobile Platform, check out our documentation. Start making something your users will really love — across all their devices, whether they’re online or offline.

Read more

Realm ObjC & Swift 2.4: Object Notifications!

by /

We’re releasing version 2.4 of Realm Objective‑C and Realm Swift today. In this release, we’re giving our live objects a whole lot more life by adding object-level notifications, so that your app can respond as individual objects update.

Object-Level Notifications

Up until now, if you wanted to know that an object changed, you had to get notifications from collections, which tell you when objects contained in that collection get deleted, inserted, or modified. However, you wouldn’t know which properties have changed. Additionally, creating collections in order to asynchronously observe a single object is awkward, costly and difficult to define when an object can’t easily be uniquely represented by a query.

We’ve long supported KVO to observe property-level changes to single objects, but it’s no secret that KVO is pretty gross, you can only observe a single property per KVO notification, and KVO isn’t cross-platform or cross-language. KVO notifications are also run synchronously, which often means blocking your UI thread 🙀.

Today, we’re shipping object-level notifications so that you’re notified of changes on a single object in the most helpful way possible. Object notifications are powered by a very simple API. Like with collection notifications, you simply add a notification block to the object you’d like to observe. Creating the notification will return a NotificationToken; hold onto it as long as you need notifications for the object.

When the notifications start rolling in, the callback lets you see exactly what changed with its ObjectChange struct, which will expose exactly what properties have changed, or whether the observed object has been deleted:

class Message: Object {
  dynamic var isRead = false
  dynamic var content = ""
}

class MessageController: UIViewController {
  private let notificationToken: NotificationToken

  init(message: Message) {
    notificationToken = message.addNotificationBlock { change in
      switch change {
      case .change(let properties):
        if let readChange = properties.first(where: { $0.name == "isRead" }) {
          self.showReadBadge = readChange.newValue as! Bool
        }
        if let contentChange = properties.first(where: { $0.name == "content" }) {
          self.contentView.textValue = contentChange.newValue as! String
        }
      case .deleted:
        self.handleDeletion()
      case .error(let error):
        self.handleError(error)
      }
    }
  }

  deinit {
    notificationToken.stop()
  }
}

When you’re ready to stop watching the object, you call token.stop(), or simply release the token object.

In summary, you create a notification on a managed object with addNotificationBlock, hold onto the returned NotificationToken instance, and handle whatever updates you need to make to your app inside the callback.

A couple caveats: when list properties change, you won’t see newValue or oldValue data, but the notification will still fire. And if you’re in need of making a synchronous UI write, or just need to skip the notification for a given write, you can still use the interface-driven writes feature by passing the object’s notification token to realm.commitWrite(withoutNotifying: [token]).

Bug Fixes

We’ve fixed several error handling issues when renewing expired authentication tokens for synchronized Realms in this release.

We strongly encourage all Realm Mobile Platform users to update to this version to avoid issues with expiring tokens.

Oh, and we also managed to fix an elusive bug causing a “bad transaction log” exception that’s been haunting us for months! #RaceConditions🏎

Deprecating Swift 2

Supporting legacy Swift versions is a lot of work 😅. With less than 5% of active Realm builders on Swift 2.x and a high cost of maintenance for Swift 2 on our end, this release drops support for Swift 2.x.

That makes Realm Swift 2.3.0 is the last version to support Swift 2.x. We apologize for the inconvenience.

A Note About Xcode 8.3 Beta 1

Apple published the first Xcode 8.3 beta earlier this week. We’ve included a change in this release that fixes a compilation issue with Realm Objective-C.

However, we’re still working through Swift 3.1 compilation issues. Please subscribe to #4586 to be notified of any progress to support Xcode 8.3 with Realm Swift.


Thanks for reading. Now go forth and build amazing apps with Realm! As always, we’re around on Stack Overflow, GitHub, or Twitter.

Read more

The Platform Experience: Announcing Realm World Tour

by /

It’s time for us to hit the road! We just shipped Realm Mobile Platform 1.0, so now we’re sending our top product engineers out to events in 20+ cities across three continents, to bring the Realm platform to you live and in realtime ;-) It’s the first-ever Realm World Tour, and we’re excited to get the chance to meet you, to help you get started with Realm, and to hear about what you are working on!

We’ve reached out to leaders of the developer communities at each city, and with their help as local hosts, have planned a great evening for attendees. Each event includes an introduction to the free Developer Edition plus discussion of some of the advanced features, followed by sample code, practical demos, and extensive technical Q&A session — all led by a Realm product engineer. There will also be plenty of time to talk one-to-one, to share best practices, and to learn from each other. And, we’ll have some special attendees-only swag to give out – we’re keeping the design a secret until the tour kick-off in our HQ in San Francisco on February 15!

The Realm World Tour events are free, but space is limited — check out the official web page for the latest info and chance to register.

Read more

Ready for Realtime and Scale: Announcing Realm Mobile Platform 1.0

by /

Today we’re very proud to announce that Realm Mobile Platform 1.0 is now generally available and ready for production use cases ranging from the very smallest to those with massive scale. We’ve been hard at work over the last few months fixing bugs, polishing rough edges, and hardening the code, as well as adding more than a few new features (more on those below). Hitting 1.0 is a huge milestone for all of us at Realm, and we are extremely grateful to the customers and members of the community who have helped us get here with their feedback throughout the beta period!

The Realm Mobile Platform makes it easier for developers to build apps with sophisticated features like realtime collaboration, live messaging, robust offline-first experiences, and more. The platform combines Realm’s popular client-side databases for iOS and Android with the new Realm Object Server, and delivers automatic realtime data synchronization. As a developer, you don’t need to write or maintain networking code or do any serialization, Realm handles the sync for you — you can be sure that the data on the device is always synchronized with the data on the server. Realm also makes it easy to create server-side logic to react instantly to changes in data, and build integrations to existing systems and APIs.

With this release, all three editions of the platform are ready for you to start building, and we have some fun new demo code you can run to try it out. Read on for more of the details… or, if you’d rather just dive in, just download our Draw demo app and the free Developer Edition for Mac or Linux and start exploring.

Three New Enterprise Features

This release also brings three new features to the Enterprise Edition:

Data Integration API

Our new Data Integration API allows developers to easily integrate the Realm Mobile Platform with any data source, making it simple to use Realm for connecting realtime apps and app features to existing data and services. Many of our beta users are leveraging this new Realm feature to “mobilize” their legacy systems, using Realm as a realtime bridge that gives their Android and iOS teams an easy way to build modern, reactive apps connected to data and logic in existing systems of record.

For example, imagine a retailer who wants to launch a new mobile shopping experience, but needs that new app to be seamlessly connected to an existing payment transaction database. Using Realm’s new Data Integration API, Realm is able to reliably connect the existing database to Realm Object Server such that the Object Server and the payment transaction database are synchronized with the same data. To ensure data is accurate in all locations, the API is designed to understand broken connections and restart interrupted transactions. With these guarantees in place, Realm Object Server can now function as middleware between the client-side databases and the payment transaction database, allowing the retailer to leverage their existing database investments with Realm for new projects.

The Data Integration API makes it easy to build your own custom connectors, but we’re also announcing the first of our pre-built connectors, for PostgreSQL. We’re working on others, and based on customer requests expect to soon release pre-built connectors for Oracle, MongoDB, Hadoop, SAP HANA, and Redis.

Horizontal Scalability

We’ve built the Realm platform to be quite robust – depending on the app and the hardware you run it on, a single Realm Object Server can handle well over ten thousand concurrent users. But to allow customers to reach massive scale, we’ve added horizontal scaling to the Enterprise Edition. Included, is a built-in load balancer that automatically handles distributing connections. This makes it possible to deploy multiple instances of Realm Object Server in parallel, so your app can support more than one million concurrent realtime users.

Continuous Backups

Continuous Backups allow you to create automatic backups of your production Realm Object Server data on a secondary server. In the event of disaster (power outage, hardware failure, natural disaster, etc.), you can continue to operate your application from the secondary server. Developers can choose where to locate their secondary backup servers, including a different region, for increased disaster recovery resiliency.

New Features in Enterprise Edition

Getting Started with Realm and the Draw Demo App

Your first step is to install the Realm Platform, on your own machine or on the cloud service of your choice. Unless you have a specific interest in exploring event handling or other Pro Edition features, we recommend you start with the Developer Edition — it is powerful and entirely free of cost, with no time limits, and you can use it for everything from hacking around to live production apps (see the license terms here). Our documentation will walk you through install, and get you up and running.

Once you have Realm installed, you’re ready to run some sample code. Draw is a whiteboard collaboration app that showcases Realm handling realtime data synchronization between multiple users. It’s totally open source, and available along with other Realm demos on GitHub. This video of Draw in action shows the realtime data synchronization between two iPads, and what happens when the cell network temporarily fails.

How to Learn More

If you’d like to get an in-depth walkthrough of the Realm Mobile Platform and a chance to ask questions, our product team will be doing a live technical session. Please register here.

Read more