Skip to main content

Reading and Writing Data

Reading Data

To read remote data, you need to register a DocumentListener through addDocumentListener().

ListenerEvent CallbackPurpose
DocumentEventListeneronDocumentChanged()Handle when data is changed
onDocumentError()Handle when a data sync error occurs

You can read the latest data at the time of the event occurrence through the onDocumentChanged() callback method. The event callback function passes the data including the data of the child nodes, and if the document does not exist, an empty document is passed.

caution

If too many listeners are registered, performance issues may occur.

The following code is an example of reading data every time the user profile information changes.

appDoc.addDocumentListener(object : DocumentListener {
override fun onDocumentChanged(document: SyncDocument, fromRemote: Boolean) {
val fullProfile: FullUserProfile? = document.value()
println("User profile : $fullProfile")
}

override fun onDocumentError(document: SyncDocument, e: SyncError) {
// TODO: Handle data sync error
}
})

Exploration of Document Nodes

To access child nodes from the root document, you can use the child() method. If the node type is a list, you can get the child nodes of the list node using the array index.

val companyDoc = appDoc?.child("company")
val wantedDoc = companyDoc?.child("wanted")
val frontEndDoc = wantedDoc?.child("0")
val backEndDoc = wantedDoc?.child("1")
val notExistDoc = wantedDoc?.child("2") // This document does not exist, so its value is null.

Alternatively, you can explore child nodes at once using the paths() method.

val sameFrontEndDoc = appDoc?.paths("company", "wanted", "0") // This document is equal to frontEndDoc.

Writing Data

Adding Items

You can save Document data by passing the field values and field names as parameters to the setKeyValue() method. Below is a simple code for adding a member.

[Remote document data]
{
"name": "42dot",
"since": 2020,
"members": [
{
"name": "normal",
"age": 20,
"level": 1
},
{
"name": "vip",
"age": 40,
"level": 5
}
]
}
data class User(val name:String, val age:Int, val level:Int)
data class Mall(val name:String, val members:List<User>, val blackList:List<User>?)

val membersDoc = mallDoc?.child("members")
val newCustomer = User("Stranger", 30, 0)
membersDoc?.setKeyValue(newCustomer, "2")

In the above example, a new user was added after exploring the member node. You can also write it in a simpler way as follows.

// Set an object from root node with paths.
mallDoc?.setKeyValue(newCustomer, "members.2")
// You can append an object explicitly.
membersDoc?.appendToArray(newCustomer)

Below is the code attempting to add a new member before the vip member.

membersDoc?.insertToArray(1, newCustomer)
caution

setKeyValue sets the given value, so to add a new object at a specific position in the array, use the insertToArray method.

Let's add a new blackList field to the mallDoc Object node using the setKeyValue method.

[Expected data]
{
"name": "42dot",
"since": 2020,
"members": [
{
"name": "normal",
"age": 20,
"level": 1
},
{
"name": "vip",
"age": 40,
"level": 5
}
],
"blackList": [
{
"name": "bad",
"age": 12,
"level": 0
}
]
}
mallDoc?.setKeyValue(listOf(User("bad", 12, 0)), "blackList")

Updating Items

setKeyValue() method can be used to simply update new values. Below is the code that changes the mall establishment date to 2021 and the age of the normal member to 21.

mallDoc?.setKeyValue(2021, "since")
mallDoc?.setKeyValue(21, "members.0.age")

Deleting Items

You can delete field data by entering the path you want to delete into removeKeyValue(). Below is the code that deletes the newly added member and the new field value.

mallDoc?.unsetKeyValue("since")
mallDoc?.unsetKeyValue("members.2")
//You can also delete a user from membersDoc.
membersDoc?.unsetKeyValue("2")
//Or you can delete a user using array method.
membersDoc?.deleteInArray(2, 1)