Docs Menu

Docs HomeDevelop ApplicationsAtlas Device SDKs

Quick Start - Kotlin SDK

On this page

  • Define Your Object Model
  • Open a Realm
  • Create, Read, Update, and Delete Objects
  • Watch for Changes
  • Close a Realm
  • Add Device Sync (Optional)
  • Prerequisites
  • Initialize the App
  • Authenticate a User
  • Open a Synced Realm
  • Next: Check out the Template Apps and Tutorial

This page contains information to quickly use Realm with the Kotlin SDK. The optional Add Device Sync section illustrates how to get Atlas Device Sync integrated into your application.

Before you begin, ensure you have installed the Kotlin SDK for your platform.

Note

Using this Quick Start with KMP

If you're running this project in a fresh Kotlin Multiplatform (KMP) template project, you can copy and paste the following snippets into the Greeting.greeting() method in the commonMain module.

Your application's data model defines the structure of data stored within Realm. You can define your application's data model via Kotlin classes in your application code with Realm Object Models.

To define your application's data model, add a class definition to your application code. The example below illustrates the creation of an 'Item' model that represents Todo items in a Todo list app.

class Item() : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var isComplete: Boolean = false
var summary: String = ""
var owner_id: String = ""
constructor(ownerId: String = "") : this() {
owner_id = ownerId
}
}

Use RealmConfiguration.create() to open a realm using default parameters. Pass your configuration to the Realm factory constructor to generate an instance of that realm:

val config = RealmConfiguration.create(schema = setOf(Item::class))
val realm: Realm = Realm.open(config)

For more information on how to control the specifics of the RealmConfiguration you would like to open (e.g. name, location, schema version), refer to Open & Close a Realm.

Once opened, you can create objects within a realm in a write transaction block.

To create a new Item, instantiate an instance of the Item class and add it to the realm in a write transaction block:

realm.writeBlocking {
copyToRealm(Item().apply {
summary = "Do the laundry"
isComplete = false
})
}

You can retrieve a collection of all Todo items in the realm with query.find():

// all items in the realm
val items: RealmResults<Item> = realm.query<Item>().find()

You can also filter a collection to retrieve a more specific collection of objects:

// items in the realm whose name begins with the letter 'D'
val itemsThatBeginWIthD: RealmResults<Item> =
realm.query<Item>("summary BEGINSWITH $0", "D")
.find()
// todo items that have not been completed yet
val incompleteItems: RealmResults<Item> =
realm.query<Item>("isComplete == false")
.find()

Find more information about string Realm queries in Filter Data.

To modify a Todo item, update its properties in a write transaction block:

// change the first item with open status to complete to show that the todo item has been done
realm.writeBlocking {
findLatest(incompleteItems[0])?.isComplete = true
}

Finally, you can delete a Todo item by calling mutableRealm.delete() in a write transaction block:

// delete the first item in the realm
realm.writeBlocking {
val writeTransactionItems = query<Item>().find()
delete(writeTransactionItems.first())
}

You can watch a realm, collection, or object for changes with the observe method.

Important

Serverless Limitations

You cannot watch for changes if the data source is an Atlas serverless instance. MongoDB serverless currently does not support change streams, which are used on watched collections to listen for changes.

In the following example, we listen for changes on all Item objects.

// flow.collect() is blocking -- run it in a background context
val job = CoroutineScope(Dispatchers.Default).launch {
// create a Flow from the Item collection, then add a listener to the Flow
val itemsFlow = items.asFlow()
itemsFlow.collect { changes: ResultsChange<Item> ->
when (changes) {
// UpdatedResults means this change represents an update/insert/delete operation
is UpdatedResults -> {
changes.insertions // indexes of inserted objects
changes.insertionRanges // ranges of inserted objects
changes.changes // indexes of modified objects
changes.changeRanges // ranges of modified objects
changes.deletions // indexes of deleted objects
changes.deletionRanges // ranges of deleted objects
changes.list // the full collection of objects
}
else -> {
// types other than UpdatedResults are not changes -- ignore them
}
}
}
}

Later, when you're done observing, cancel the job to cancel the coroutine:

job.cancel() // cancel the coroutine containing the listener

To close a realm and all underlying resources, call realm.close(). The close() method blocks until all write transactions on the realm have completed.

realm.close()

This section illustrates how to authenticate with an Anonymous User, and open a Flexible Sync realm to begin syncing data between devices.

The code snippets in this section require the following:

To use App Services features such as authentication and sync, access your App Services App using your App ID. You can find your App ID in the App Services UI.

val app = App.create(YOUR_APP_ID)

To authenticate and log in a user, call App.login. When anonymous authentication is enabled, users can immediately log into your app without providing any identifying information:

val credentials = Credentials.anonymous()
val user = app.login(credentials)

Once you have initialized your Atlas App Services App, authenticated a user, and defined your object model, you can create a SyncConfiguration.

If you have opened a local realm following the Open a Realm section above, replace the RealmConfiguration with the SyncConfiguration described below.

Pass the authenticated user and the Item class to the SyncConfiguration.Builder function to create a Flexible Sync Configuration.

Important

Initial Subscriptions

You need at least one subscription before you can read from or write to the realm. Use initialSubscriptions to define the initial subscription set when the Realm file is first opened. Pass the query you wish to subscribe to and a name for the subscription to the add() function.

The example below specifies a subscription named "User's Items" with all Item objects.

// create a SyncConfiguration
val config = SyncConfiguration.Builder(
user,
setOf(Item::class)
) // the SyncConfiguration defaults to Flexible Sync, if a Partition is not specified
.initialSubscriptions { realm ->
add(
realm.query<Item>(
"owner_id == $0", // owner_id == the logged in user
user.id
),
"User's Items"
)
}
.build()
val realm = Realm.open(config)

Check out the template app to experiment with another quick way to start coding with the Realm Kotlin SDK. The Kotlin SDK template, labeled android.kotlin.todo.flex, is a premade application that integrates Realm and Atlas Device Sync into a customizable android app.

Alternatively, if you are interested in a guided experience, you can read our Android with Kotlin SDK tutorial that expands on the template app.

← Install the Kotlin SDK