Realm Kotlin 1.8

Christian Melchior
Realm Blog

--

We just released Realm Kotlin 1.8.0 to Maven Central and Gradle Plugin Portal. This release includes support for @PersistedName support for model classes name, authentication change listeners, locally encrypted Realms across multiple processes, a new RealmLog class with improved logging, and more.

@PersistedName support on class names

In Realm Kotlin 1.6 we introduced the @PersistedName annotation for properties that made it possible to use different names in Kotlin and in the Realm file itself. With 1.8, this support has been extended to also support class names:

@PersistedName("RealmParent")
class Parent: RealmObject {
var name: String = ""
var age: Int = 0
var child: Child? = null
}

When using this annotation, typed queries will continue to work as normal, but unnamed backlink queries and DynamicRealm queries must use the persisted name:

// Works as normal
val parents = realm.query<Person>().find()

// Unnamed backlink queries, where you want to find all children
// that has a Parent with an id = 42 linking to them
val children = realm.query<Child>("@links.RealmParent.child.id == $0", 42).find()

// Queries inside migrations
RealmConfiguration.Builder(schema = setOf(...))
.schemaVersion(1)
.migration(
AutomaticSchemaMigration {
val parents = it.newRealm.query("RealmParent").find()
}
)
.build()

Manual compaction

Before Realm Kotlin 1.8, it was possible to compact and reduce the size of the Realm file on disk by either adding a RealmConfiguration.Builder.compactOnLaunch() or Realm.writeCopyTo(config) but both of these approaches required you to open the Realm file which could be cumbersome in some cases.

In 1.8 a new manual Realm.compactRealm(config) method has been added that should make this easier. This works for both local and synchronized Realms.

val config = RealmConfiguration.create(schema = setOf(...))
val didCompact: Boolean = Realm.compactRealm(config)

Authentication listeners

For multi-user apps using Device Sync it has previously been hard to track the state of users in a single location. With 1.8, we introduce a new App.authenticationChangesAsFlow() method that allows you to listen to user auth changes using the new AuthenticationChange class

val app = App.create("appId")
CoroutineScope(Dispatchers.Default).launch {
app.authenticationChangeAsFlow().collect { change: AuthenticationChange ->
when(change) {
LoggedIn -> println("${change.user} logged in")
LoggedOut -> println("${change.user} logged out")
Removed -> println("${change.user} was removed")
}
}
}

Improved logging

Logging has been improved with the addition of a new global RealmLog singleton class as well as more detailed logging from the Realm storage layer. This means that if you enable a log level of LogLevel.DEBUG or higher it is possible to get much more insight into what Realm is doing under the hood.

// Change the log level
RealmLog.level = LogLevel.DEBUG
// Add a custom logger
RealmLog.add(object: RealmLogger {
override val level: LogLevel = LogLevel.DEBUG
override val tag: String = "Realm"
override fun log(
level: LogLevel,
throwable: Throwable?,
message: String?,
vararg args: Any?
) {
// Handle logs in a custom way
}
})

With the addition of these APIs, the old way of configuring logging through either AppConfiguration, SyncConfiguration or RealmConfiguration has been deprecated.

It is worth noting that if your app is using two different app ids and you have configured the log level differently for each app, this will no longer work and only the last applied log level will be used across both apps.

val config1 = AppConfiguration.Builder("app1")
.log(level = LogLevel.DEBUG)
.build()
val config2 = AppConfiguration.Builder("app2")
.log(level = LogLevel.INFO)
.build()
// In this case, both apps will use LogLevel.INFO
val app1 = App(config1)
val app2 = App(config2)

For all other use cases, using either the new or deprecated APIs will behave the same.

Multiprocess encryption support

With Realm Kotlin 1.8, the restriction on using encryption on files accessed by multiple processes is removed. This means that you will no longer see an Encrypted interprocess sharing is currently unsupported message when trying to access an encrypted Realm file from another process.

Note: Synced Realms do still not support multiprocess, encrypted or not. This restriction will also be lifted in a future release.

Thanks for reading. You can see the full changelog here.

Start using Atlas Device Sync for free, today. Atlas Device Sync is a fully-managed mobile backend-as-a-service. Leverage out-of-the-box infrastructure, data synchronization capabilities, built-in network handling, and much more to quickly launch enterprise-grade mobile apps.

If you are still using Realm Java in your Kotlin project, you can learn more about how easy it is to migrate to Realm Kotlin here.

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

--

--