Join us at MongoDB.local London on 7 May to unlock new possibilities for your data. Use WEB50 to save 50%.
Register now >
Docs Menu
Docs Home
/ /
Realm

Serialization - Kotlin SDK

The Realm Kotlin SDK supports Kotlin Serialization. You can serialize specific Realm data types using stable serializers, or user-defined classes with an experimental full-document serialization API.

El Realm Kotlin SDK proporciona serializadores para los siguientes tipos de datos para KSerializer:

Tipo de datos de Realm
KSerializer for Type

MutableRealmInt

MutableRealmIntKSerializer::class

RealmAny

RealmAnyKSerializer::class

RealmDictionary

RealmDictionaryKSerializer::class

RealmInstant

RealmInstantKSerializer::class

RealmList

RealmListKSerializer::class

RealmSet

RealmSetKSerializer::class

RealmUUID

RealmUUIDKSerializer::class

Los serializadores se encuentran en io.realm.kotlin.serializers.

Para ver ejemplos de cómo Realm serializa los diferentes tipos de datos, consulte Ejemplos de salida de serialización.

Deserializing Realm data types generates unmanaged data instances.

You can register a serializer for a specific property. Use the @Serializable annotation to bind to a specific Realm data type serializer.

class Frog : RealmObject {
var name: String = ""
@Serializable(RealmListKSerializer::class)
var favoritePonds: RealmList<String> = realmListOf()
}

You can register a serializer for all occurrences of that type within a file by adding the declaration to the top of the file:

@file:UseSerializers(RealmSetKSerializer::class)
import io.realm.kotlin.ext.realmSetOf
import io.realm.kotlin.serializers.RealmSetKSerializer
import io.realm.kotlin.types.RealmSet
import kotlinx.serialization.UseSerializers

Luego, cualquier objeto que tenga propiedades de ese tipo dentro del archivo puede usar el serializador sin registrarlo individualmente:

// These objects have RealmSet properties that get serializers
// from declaring `@file:UseSerializers(RealmSetKSerializer::class)`.
// No need to individually declare them on every `RealmSet` property in the file.
class Movie : RealmObject {
var movieTitle: String = ""
var actors: RealmSet<String> = realmSetOf()
}
class TVSeries : RealmObject {
var seriesTitle: String = ""
var episodeTitles: RealmSet<String> = realmSetOf()
}

Para vincular automáticamente todos los tipos Realm con sus serializadores, puedes añadir un fragmento que contenga todos los serializadores en la parte superior de un archivo:

@file:UseSerializers(
MutableRealmIntKSerializer::class,
RealmAnyKSerializer::class,
RealmDictionaryKSerializer::class,
RealmInstantKSerializer::class,
RealmListKSerializer::class,
RealmSetKSerializer::class,
RealmUUIDKSerializer::class
)

Estos ejemplos ilustran cómo los diferentes tipos de datos de Realm se serializan usando un codificador JSON:

Tipo de datos de Realm
Serialization Type and Example

MutableRealmInt

Serializes using a regular integer value.

MutableRealmInt.create(35) serializes to 35

RealmAny

Serializes using a map containing a union of all values and its type.

RealmAny.create("hello world") serializes to {"type": "STRING", "string": "hello world"}

RealmAny.create(20) serializes to {"type": "INT", "int": 20}

RealmDictionary

Serializes using a generic list.

realmDictionaryOf("hello" to "world") serializes to {"hello": "world"}

Reino instantáneo

Serializes as a BsonDateTime.

RealmInstant.now() serializes to {"$date": {"$numberLong": "<millis>"}}

RealmList

Serializes using a generic list.

realmListOf("hello", world) serializes to ["hello", "world"]

RealmSet

Serializes using a generic list.

realmSetOf("hello", world) serializes to ["hello", "world"]

BsonObjectId or ObjectId

Serializes as a BsonObjectId.

ObjectId.create() serializes to {"$oid": <ObjectId bytes as 24-character, big-endian hex string>}

RealmUUID

Serializes as a BsonBinary.

RealmUUID.random() serializes to { "$binary": {"base64": "<payload>", "subType": "<t>"}}

RealmObject

Serializes using the polymorphic setup defined by the user. Do this via the SerializersModule:

val json = Json {
serializersModule = SerializersModule {
polymorphic(RealmObject::class) {
subclass(SerializableSample::class)
}
}
}

Nueva en la versión 1.9.0.

Las API del SDK de Realm Kotlin que se comunican directamente con MongoDB Atlas utilizan codificación EJSON. El SDK ofrece dos tipos de codificadores EJSON:

  • Un codificador limitado pero estable

  • Un codificador experimental que ofrece serialización completa de documentos

The APIs that use these encoders include:

La compatibilidad con la serialización EJSON del SDK de Kotlin de Realm depende de la biblioteca oficial de serialización de Kotlin. Debe agregar la serialización de Kotlin.a tu proyecto. Usa la misma versión que la del SDK de Kotlin de Realm. Consulta la Matriz de Compatibilidad de Versiones en el repositorio de GitHub de realm-kotlin para obtener información sobre las dependencias compatibles con cada versión.

The @Serializable annotation in the following examples comes from the Kotlin Serialization framework.

The stable encoder does not support user-defined classes. You can use these argument types with the stable encoder:

  • Primitives

  • BSON

  • MutableRealmInt

  • RealmUUID

  • ObjectId

  • RealmInstant

  • RealmAny

  • Arreglo

  • Colección

  • Map

To return a collection or map, you can use BsonArray or BsonDocument.

You can call a Function using the stable encoder with a valid argument type, and deserialize the result.

In this example, we call the getMailingAddress Function with two string arguments, and get the result as a BsonDocument:

// The `getMailingAddress` function takes a first name and last name and returns an address as a BsonDocument
val address = user.functions.call<BsonDocument>("getMailingAddress", "Bob", "Smith")
assertEquals(address["street"], BsonString("123 Any Street"))

Puede crear un Credential para usar con la autenticación de funciones personalizadas utilizando el codificador estable como un mapa o BsonDocument un:

val credentials = Credentials.customFunction(
mapOf(
"userId" to 500,
"password" to "securePassword"
)
)
val bsonCredentials = Credentials.customFunction(
BsonDocument(
mapOf(
"userId" to BsonInt32(500),
"password" to BsonString("securePassword")
)
)
)
app.login(credentials)

Puedes acceder a un perfil de usuario o datos de usuario personalizados utilizando el codificador estable como un(a) BsonDocument:

val user = app.currentUser!!
val userProfile = user.profileAsBsonDocument()
assertEquals(userProfile["email"], BsonString("my.email@example.com"))
val user = app.currentUser!!
val customUserData = user.customDataAsBsonDocument()
assertEquals(BsonString("blue"), customUserData?.get("favoriteColor"))

The full-document encoder enables you to serialize and deserialize user-defined classes. You can define and use custom KSerializers for your type with Atlas features that communicate directly with MongoDB Atlas using EJSON encoding. The full-document encoder supports contextual serializers.

Importante

Esto es experimental

La implementación actual de la serialización completa de documentos es experimental. Llamar a estas API cuando su proyecto utiliza una versión de Kotlin Serialization diferente a la de la dependencia de Realm puede causar un comportamiento indefinido. Consulte la matriz de compatibilidad de versiones en el repositorio de GitHub realm-kotlin para obtener información sobre las dependencias admitidas de cada versión.

To use this feature, add one or more of the following imports to your file as relevant:

import kotlinx.serialization.Serializable
import io.realm.kotlin.annotations.ExperimentalRealmSerializerApi
import org.mongodb.kbson.ExperimentalKBsonSerializerApi
import kotlinx.serialization.modules.SerializersModule
import io.realm.kotlin.serializers.RealmListKSerializer

When you use serialization in the Realm Kotlin SDK, you can define a serializer in one of two ways:

  • Agregar la anotación @Serializable a una clase

  • Define a custom KSerializer for your type, and pass it to the relevant API

@Serializable
class Person(
val firstName: String,
val lastName: String
)

Puedes configurar un serializador EJSON personalizado para tu aplicación en el AppConfiguration, como en un caso donde desees utilizar un serializador contextual:

@Serializable
class Frogger(
val name: String,
@Contextual
val date: LocalDateTime
)
AppConfiguration.Builder(FLEXIBLE_APP_ID)
.ejson(
EJson(
serializersModule = SerializersModule {
contextual(DateAsIntsSerializer)
}
)
)
.build()

Because the full-document serialization API is experimental, you must add the relevant @OptIn annotations for the APIs you use.

@OptIn(ExperimentalRealmSerializerApi::class)

You can call a Function using the experimental API with arguments or return types that use custom serializers.

En este ejemplo, llamamos a la función getMailingAddressForPerson con un objeto Person serializado y obtenemos el resultado como un objeto Address deserializado:

@Serializable
class Address(
val street: String,
val city: String,
val state: String,
val country: String,
val postalCode: String
)
@Serializable
class Person(
val firstName: String,
val lastName: String
)
// The `getMailingAddressForPerson` function takes a Person object and returns an Address object using the experimental serializer
val address = user.functions.call<Address>("getMailingAddressForPerson"){
add(Person("Bob", "Smith"))
}
assertEquals(address.street, "123 Any Street")

Tip

Atlas Function calls for the stable serializer and the experimental API serializer share the same method name. When invoking a function with no parameters, you must provide an empty block in the instruction for the experimental API.

val color = user.functions.call<PersonalFavorites>("favouriteColor") {}

Puedes definir un serializador personalizado para la autenticación de función personalizada usando la API experimental:

@Serializable
class CustomUserCredential(
val userId: Int,
val password: String
)

And use it when creating a custom function credential:

val credentials = Credentials.customFunction(
CustomUserCredential(
userId = 500,
password = "securePassword"
)
)
app.login(credentials)

Define a custom serializer for user profile or custom data:

@Serializable
class UserProfile(
val email: String
)
@Serializable
class UserCustomData(
val favoriteColor: String
)

Y utiliza el serializador personalizado cuando accedas al perfil del usuario o a datos de usuario personalizados:

val user = app.currentUser!!
val userProfile = user.profile<UserProfile>()
assertEquals(userProfile.email, "my.email@example.com")
val user = app.currentUser!!
val customUserData = user.customData<UserCustomData>()
assertEquals("blue", customUserData!!.favoriteColor)

Serialization methods used by libraries that depend on reflection, such as GSON do not work with the SDK by default.

This is because the SDK compiler plugin injects a hidden field into object models, prefixed with io_realm_kotlin_. The SDK uses this hidden field to manage internal object state. Any library that relies on fields instead of getters and setters needs to ignore this hidden field.

Para utilizar el SDK con bibliotecas externas como GSON, excluya los campos ocultos de la serialización mediante una coincidencia de prefijo:

var gson: Gson = GsonBuilder()
.setExclusionStrategies(object: ExclusionStrategy {
override fun shouldSkipField(f: FieldAttributes?): Boolean =
f?.name?.startsWith("io_realm_kotlin_") ?: false
override fun shouldSkipClass(clazz: Class<*>?): Boolean =
false
})
.create()

Volver

React to Changes