Replacing SQLite with Realm (Android)

Daneel Smuts
22sevencraft
Published in
3 min readDec 8, 2016

“Hey, let’s replace our SQLite database with Realm. It will make everything better.” — a hapless developer

We’ve been using SQLite as our app’s database since its inception. It’s been working well, but as with any long-living software, code rot, many hands and lack of knowledge of original intent has deteriorated the integrity of our users’ experience. Our ability to “move fast and break things” was more “churn out masses of boilerplate code and caress it into submission”

Tempted by juicy new database frameworks like Firebase, SugarORM and Realm, we decided to investigate the feasibility of replacing SQLite with Realm. Realm has been on our radar for some time, but regular breaking changes in pre-1.0 form lead us to remain observers until the APIs settled down. The release of versions 1.0 (Mobile Database) and 2.0 (Mobile Platform) indicated production-ready maturity; exactly what we’ve been waiting for.

But first, the pros and cons of SQLite in our experience

Pros

  • It’s built into Android, all for free.
  • SQL is easy to understand and lots of people have experience with it.
  • There is a built-in standard way of working with it in Android (CursorLoaders and RecyclerViews).

Cons

  • CursorLoaders can become hairy when you have many queries feeding views or lists.
  • Many layers of boilerplate code, especially when adding a new table. In fact, it involved so much boilerplate that we’ve resorted to occasionally dumping JSON into a String column instead of building out separate tables and maintaining relationships. Which is bad. Really bad.
  • You can’t reuse your schema and the associated code across different platforms like iOS or React Native.

There’s no shortage of tutorials covering Realm’s usage in a sparkly new app, but guidance and findings on slotting it into an existing app are few and far between; hence this write-up.

Our evaluation

Armed with a few days to spend on this, we came up with a lit of questions, and as a way of getting answers. We decided to do a deep dive and replace the cursor loader-based RecyclerView on a particular view in our app, the one with the most data records, with a Realm-backed one.

This approach offered a real-life experience touching the whole spectrum from data modelling, initial insertion, querying and displaying in a list — all while attempting to adhere to our existing app architecture in a learning by doing fashion.

Question: Can Realm slot into our existing cursorloader-fed views with minimal refactoring?

Answer: Yes. Realm supplies a RealmRecyclerViewAdapter for binding to Realm data. Adding new transactions to Realm automagically make them appear in the RecyclerView. Score!

Question: Can it persist data in a similar fashion to to our existing implementation?

Answer: Yes. When you insert records into Realm, you can even give it a raw JSON response, and it should insert records correctly. If you require more control, you can deserialize the JSON yourself and insert records individually too.

Question: Can the Realm models match our existing data models?

Answer: Yes. For the sake of keeping our existing model (in our test case a transaction from your spending history) working on other views, a new Realm-specific transaction model (extends RealmObject) was created using http://www.jsonschema2pojo.org . This offered the chance to start with a clean slate and move all accessor logic to a transaction repository

Question: Does its migration framework offer the same flexibility as SQLite?

Answer: Yes. A direct clone of our existing migration framework was made and found to offer the same control as before

Question: Will such a switch allow us to spend more time innovating and less on boilerplating?

Answer: Yes. Adding a table is now a straightforward process: Create the Realm model and build a repository and presenter. That’s it. Much better workflow!

Conclusion

We love it! And we are going to move our persistence over to use it.

In our case our Realm transaction model (POJO) can match the model used in the JSON data representation used to retrieve data from our networking API. This means JSON responses can be fed directly into Realm (realm.createOrUpdateAllFromJson()) for deserialization and persistence — no need for manual intervention to redirect datasets to their relevant tables.

We expected at least a few hiccups along the way, but were surprised by the maturity of the Realm API.

--

--