Realm Kotlin 1.6.0

Christian Melchior
Realm Blog

--

We just released Realm Kotlin 1.6.0 to Maven Central and Gradle Plugin Portal. This release includes support for calling Atlas Functions, new RealmAny and Decimal128 datatypes, backlinks for embedded objects, updates to the Core database that significantly reduces the size of write-heavy databases, and much more.

Atlas Functions Support

It is now possible to call Atlas Functions directly through the Kotlin SDK. This is done through a new functions property in the Userclass. It is available after logging in.

runBlocking {
val app = App("my-app-id")
val credentials = Credentials.usernamePassword("my-email", "my-password")
val user: User = app.login(credentials)

// Call a function configured on Atlas App Services
val response: String = user.functions.call("function-name", "foo", 42)
}

It supports passing in and returning BsonValues with default conversion of primitive values like Int, String, and other types allowed in Realm model classes.

JSON objects are also supported, both as input and output by using BsonDocument .

runBlocking {
val user: User = getUser()
val inputObj = BsonDocument("param1" to BsonString("value1"), "param2" to BsonInt32(42))
val responseObj: BsonDocument = functions.call("foo", inputObj)
val name: BsonString = responseObj["name"]!!.asString()
val age: BsonInt32 = responseObj["age"]!!.asInt32()
}

Support for using Kotlin Serialization for input and output arguments will come in a later release.

RealmAny and Decimal128 datatypes

RealmAny is a data type that can be used to model data that has a flexible schema and can contain several different types. Null values are expressed using the Kotlin type system:

import io.realm.kotlin.types.RealmAny

class Person: RealmObject {
var mixed: RealmAny? = null // Must be marked with `?`
}

val obj: Person = realm.write {
copyToRealm(Person().apply {
mixed = RealmAny.create("stringValue")
})
}

when (obj.mixed?.type) {
RealmAny.Type.INT -> showInteger(obj.mixed.asInt())
RealmAny.Type.STRING -> showString(obj.mixed.asString())
null -> showNull()
else -> throw IllegalStateException()
}

Decimal128 brings compatibility with Decimal128 available in MongoDB and brings with it the capability to represent very small or very large floating point numbers.

import org.mongodb.kbson.Decimal128

// Usage in model classes
class Person: RealmObject {
var floatingPoint: Decimal128 = Decimal128("0.73e-7")
var list: RealmList<Decimal128> = realmListOf()
}

Core 13

Realm Kotlin 1.6.0 also upgrades the Realm Core database to version 13, which brings a number of improvements:

  • Realm will now use a lot less memory and disk space when different versions of realm objects are used.
  • Realm will now continuously track and reduce the size of the Realm file when it is in use rather than only when opening the file with Configuration.compactOnLaunch enabled.
  • OpenSSL has been upgraded from 1.1.1n to 3.0.7.

Note, this will automatically update the file format to version 23, which requires at least version 13 of Realm Studio to read. A compatible version can be downloaded here.

Copy objects from Realm

An extension function called copyFromRealm() has been added to all Realm objects, lists, sets, and query results. This makes it possible to copy all data inside the object from Realm into memory and detaches it from the Realm lifecycle creating a standalone copy.

class Person: RealmObject {
var name: String = ""
var children: RealmList<Person> = realmListOf()
}

val configuration = RealmConfiguration.create(schema = setOf(Person::class))
val realm = Realm.open(configuration)

val managedObj: Person = realm.writeBlocking {
copyToRealm(Person())
}

// Copy managed objects
val unmanagedObj = managedObj.copyFromRealm()
assertFalse(unmanagedObj.isManaged())

// Copy collections list RealmList and RealmSet
val copiedList: List<Person> = managedObj.children.copyFromRealm()

// Copy query results
val persons: List<Person> = realm.query<Person>().find().copyFromRealm()

Rename persisted properties

A new @PersistedName annotation has been introduced making it possible to remap property names stored in Realm. This makes it easier to work with names that are not platform idiomatic and reduces the need for migrations. Both the original and mapped names can be used when querying for data.

class Person: RealmObject {
@PersistedName("_id")
var id = ObjectId()
}

// Both of these will work
val person1 = realm.query<Person>("_id = $0", getId()).first().find()
val person2 = realm.query<Person>("id = $0", getId()).first().find()

And much more…

Realm Kotlin 1.6.0 also brings improvements to working with backlinks in embedded objects, support for custom user data when working with synchronized Realms, making copies of Flexible Sync realms, logging in using authentication functions, resetting passwords using functions, and more.

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

--

--