Thursday, December 13, 2018

Playing with Android Realm

A long time ago I used to do a lot of Android development, up to Android Honeycomb and Gingerbread. I have used various client side databases, including
  • SQLite
  • SQLCipher
  • Couchbase-Lite
A couple of years ago I heard about Realm DB and wondered how well it works with Android. Realm database, by realm.io is an object database that seems to be growing in popularity, not only for Android development, but also for iOS, Xamarin and others. (It would be good to see a Unity3D SDK, but doesn't seem to be on the horizon). Creating a data model is very easy in Android, as all stroed Realm objects are mapped to Java objects, so it is just a matter of defining your objects as *POJO* Java classes.
I decided to make a sample Android application that uses Realm for local storage.

Impressions of Realm

I found using Realm to be very easy to setup and very easy to understand the API. Creating Model classes was simple and, even though my use case only required two very simple model classes, I think extending to more complicated applications would not cause many headaches.
To keep track of the realm connection I either wanted to create some singleton manager class, or just extend the Android base Application class and use the instance of that as a quasi-singleton. Creating the initial realm is simple:
Realm.init(this);
RealmConfiguration config = new RealmConfiguration.Builder()
                    .name("MasterData")
                    .encryptionKey(masterBytes).build();
Realm.setDefaultConfiguration(config);
mRealm = Realm.getDefaultInstance();

Realm Queries

I found querying Realm to be relatively straightforward. For instance getting al passwords is as easy as

RealmQuery<PasswordModel> pwQuery  = ((SecureXApplication) getApplication()).getRealm().where(PasswordModel.class);

Getting all notes associated with given password, given the password's id:

RealmQuery<NoteModel> query = mRealm.where(NoteModel.class);
            query.equalTo("passwordId", passwordId);
RealmResults<NoteModel> results = query.findAll();

Overall, it feels easier to use than SQLite on Android, especially if the amount of data is not large, or highly relational. I am not sure how Realm would fare trying to negotiate huge join queries on multiple tables.
Also, as with SQLCipher, Realm allows for data encryption, which is something I am always interested in. Of course, managing the database encryption key is another matter - one that I didn't solve with my demonstration application. Realm's specific encryption process uses AES-256 with CBC mode. As far as I know there is no possiblity to use any other encryption algorithm. If Realm could work with Unity3D on Android then it would be a useful way to store encrypted data on the device, especially data that I don't want the user looking at, or modifying.

Problems

I didn't really encounter many problems, although one issue was annoying.
What if I want to rekey my database? SQLCipher offers the functionality to rekey the database, which is sometimes useful, in cases where you suspect the user has access to the data. Or in my demo app's case, if the user wants to change his master password. That functionality is not a deal breaker, but is something that would put Realm up there with SQLCipher for encryption.

ODBC with J to connect to MySQL Database

If you are using the J programming language and wish to connect to a DBMS (MySQL, PostgreSQL, etc), you can use J's ODBC interface. W...