Docs Menu
Docs Home
/ /
Datos del modelo

Datos del modelo con sincronización de dispositivos - SDK de Kotlin

Esta página describe el modelo de datos de Device Sync y cómo se utiliza para mapear datos del esquema de App Services utilizado por Device Sync al esquema de Realm utilizado por el SDK de Kotlin en el cliente.

Esta página no:

Para obtener una explicación detallada de la sincronización del dispositivo, consulte Comience a utilizar Atlas Device Sync en la documentación de Atlas App Services.

Tip

La tabla de la sección Lista de Asignación de Tipos de Esquema de esta página ofrece una referencia rápida de los tipos de datos compatibles y cómo se asignan entre Realm y App Services. Para obtener un recurso más completo, consulte Asignación de Modelos de Datos en la documentación de App Services.

El modelo de datos de Atlas Device Sync está definido por los siguientes esquemas, que permiten a Device Sync mapear sus datos entre el cliente y Atlas:

  • Esquema de reino: el modelo de objetos del lado del cliente en su aplicación que define sus datos como clases Kotlin usando el SDK de Kotlin.

  • Esquema de App Services: el esquema del lado del servidor en Atlas App Services que define sus datos en BSON. Para obtener más información, consulte Esquemas en la documentación de App Services.

Device Sync utiliza estos esquemas para validar y convertir objetos entre el formato Kotlin y BSON al sincronizar datos. Cuando sincronizas datos desde el cliente, Device Sync convierte automáticamente los tipos de datos de Realm Kotlin a BSON. Luego, cuando el dispositivo cliente sincroniza datos de Atlas a través de Device Sync, el SDK convierte los datos BSON nuevamente en objetos Kotlin.

Para utilizar Device Sync, debe definir un esquema de Realm y un esquema de App Services, y ambos esquemas deben ser coherentes entre sí.

Puede definir primero su esquema en la aplicación cliente o en Atlas, según sus preferencias y el caso de uso. Después, puede generar un esquema correspondiente con los modelos de objetos correspondientes.

Si está desarrollando una nueva aplicación cliente, probablemente desee iterar sobre el modelo de datos de la aplicación. Después de definir un modelo de objetos directamente en el código de la aplicación, puede habilitar el modo de desarrollo en App Services para generar automáticamente un esquema de App Services compatible.

Modo de desarrollo es una configuración que permite que Device Sync infiera y actualice esquemas a partir de modelos de datos del lado del cliente cuando sincronizas datos desde el cliente. Para obtener más información, consulta Modo de desarrollo en la documentación de App Services.

Si está desarrollando una aplicación cliente que trabaja con datos ya existentes en Atlas, puede generar un esquema a partir de esos datos y, a continuación, generar modelos de objetos del SDK para usarlos en su aplicación cliente Kotlin. Para obtener más información, consulte Sincronizar datos en Atlas con una aplicación cliente en la documentación de App Services.

Existen algunos requisitos para sincronizar objetos correctamente. Como se mencionó anteriormente, debe tener esquemas de Realm y App Services que coincidan y que contengan los objetos que desea sincronizar.

Además, Device Sync requiere que:

  • Sus modelos de objetos deben tener un campo de clave principal llamado _idPuede ser de tipo String, Int o ObjectId. Device Sync lo utiliza para identificar objetos en las colecciones de Atlas.

    Si un objeto no tiene definido un campo _id, Realm mostrará el siguiente error de validación de esquema: There must be a primary key property named '_id' on a synchronized Realm.

  • Cada clase debe tener al menos un campos consultables.

    Cuando el modo de desarrollo está habilitado, los campos que se incluyen en las consultas de suscripción de cliente se agregan automáticamente como campos consultables en Atlas. Para obtener más información sobre la configuración de suscripciones con el SDK de Kotlin, consulte la sección "Descripción general de suscripciones".

Los objetos de Realm son instancias con nombres únicos de clases Kotlin definidas en su esquema de Realm que determinan las propiedades y relaciones de los objetos de ese tipo.

App Services asigna objetos de Realm a Atlas de las siguientes maneras:

  • Los nombres de los objetos de dominio se asignan a las colecciones de Atlas en la fuente de datos de Device Sync vinculada. Tenga en cuenta lo siguiente:

    • Cuando el modo de desarrollo está habilitado, App Services crea automáticamente una colección y un esquema para cada nuevo tipo de objeto de Realm que sincronice.

    • Los objetos incrustados no se almacenan en su propia colección en Atlas. Esto se debe a que no pueden existir fuera de su tipo de objeto principal. Consulte la sección "Objetos incrustados" en esta página para obtener más información.

  • El esquema del objeto Realm se asigna a un esquema de App Services dentro de su colección apropiada.

En el siguiente ejemplo, tenemos objetos Frog y Pond con propiedades básicas definidas en nuestro esquema de Realm:

Objetos del reino de las ranas y los estanques
// Maps to `Frog` collection
class Frog : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
var age: Int? = null
}
// Maps to `Pond` collection
class Pond : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
}

En Atlas, podemos ver cómo estos tipos de objetos se asignan a los esquemas de App Services correspondientes: cada objeto se asigna a su respectiva colección. También vemos ejemplos de objetos de rana y estanque que se ajustan a este modelo de datos:

Colección de ranas en App Services
{
"title": "Frog",
"type": "object",
"required": [
"_id",
"name"
],
"properties": {
"_id": {
"bsonType": "objectId"
},
"age": {
"bsonType": "long"
},
"name": {
"bsonType": "string"
}
}
}
Colección de estanques en App Services
{
"title": "Pond",
"type": "object",
"required": [
"_id",
"name"
],
"properties": {
"_id": {
"bsonType": "objectId"
},
"name": {
"bsonType": "string"
}
}
}
Ejemplo de objeto Rana en Atlas
{
"_id": ObjectId("5af712eff26b29dc5c51c60f"),
"name": "Kermit",
"age": 42
}
Ejemplo de objeto Pond en Atlas
{
"_id": ObjectId("5af714eff24b294c5251cf04"),
"name": "Kermit's Pond"
}

El modelo de objetos de Realm podría incluir relaciones entre objetos. Existen dos tipos principales de relaciones:

  • Relación de uno a uno: un objeto está relacionado de una manera específica con no más de otro objeto del Reino.

  • Relación de muchos: un objeto está relacionado de una manera específica con varios objetos Realm.

Las relaciones se asignan mediante propiedades que hacen referencia a la clave principal del otro objeto Realm.

Para obtener más información sobre cómo modelar relaciones en un esquema de App Services, consulte Relaciones en la documentación de App Services.

Una relación de uno a uno asigna una propiedad a una sola instancia de otro objeto Realm. Las relaciones de uno a uno deben ser opcionales. Para obtener más información sobre cómo se definen las relaciones de uno a uno en el SDK de Kotlin, consulte Definir una propiedad de relación de uno a uno.

Usando los objetos del ejemplo anterior, considere un caso donde un Frog puede tener un estanque favorito. Podemos agregar una propiedad favoritePond a nuestro modelo Frog que sea un enlace opcional a un objeto Pond.

Rana con relación de uno a uno con el estanque
class Frog : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
var age: Int? = null
// To-one relationship (MUST be optional)
var favoritePond: Pond? = null
}

En el esquema de App Services, vemos que la nueva propiedad se traduce en un campo favoritePond:

  • El campo no está en la matriz required porque es una propiedad opcional.

  • Su tipo es objectId y enlaza a un objeto Pond específico en la colección Pond independiente. Esto se debe a que definimos la clave principal en nuestro modelo Pond como objectId.

El esquema Pond no cambia. Al ser una relación de uno a uno, es unidireccional; Pond no tiene relación con Frog.

Esquema de servicios de aplicaciones
{
"title": "Frog",
"type": "object",
"required": [
"_id",
"name"
],
"properties": {
"_id": {
"bsonType": "objectId"
},
"age": {
"bsonType": "long"
},
"favoritePond": {
"bsonType": "objectId"
},
"name": {
"bsonType": "string"
}
}
}

Una relación de varios asigna una propiedad a cero o más instancias de otro objeto Realm. Para obtener más información sobre cómo se definen las relaciones de varios en el SDK de Kotlin, consulte Definir una propiedad de relación de varios.

Consideremos otro caso donde un Frog puede tener varios estanques favoritos en lugar de solo uno. Añadimos una propiedad favoritePonds a nuestro modelo Frog, que es una lista de Pond objetos. Si la rana no tiene estanques favoritos, esta lista está vacía. A medida que la rana obtiene estanques favoritos, podemos crear nuevos Pond objetos y añadirlos a la lista favoritePonds de la rana.

Rana con relación demasiado grande con el estanque
class Frog : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
var age: Int? = null
// To-many relationship (can have many ponds)
var favoritePonds: RealmList<Pond> = realmListOf()
}

En el esquema de App Services, vemos que la nueva propiedad se traduce en un campo favoritePonds que contiene todos los objetos Pond relacionados con el objeto Frog:

  • El campo no está en la matriz required porque es una propiedad opcional.

  • El tipo de este campo es una matriz de tipo objectId. Esto se debe a que definimos la clave principal en nuestro modelo Pond como objectId.

Nuevamente, el esquema Pond no cambia porque Pond no tiene relación con Frog.

Esquema de servicios de aplicaciones
{
"title": "Frog",
"type": "object",
"required": [
"_id",
"name"
],
"properties": {
"_id": {
"bsonType": "objectId"
},
"age": {
"bsonType": "long"
},
"favoritePonds": {
"bsonType": "array",
"items": {
"bsonType": "objectId"
}
},
"name": {
"bsonType": "string"
}
}
}

Una relación inversa vincula un objeto con cualquier otro objeto que haga referencia a él mediante una relación definida de uno a muchos, denominada vínculo de retroceso. Para obtener más información sobre cómo se definen las relaciones inversas en el SDK de Kotlin, consulte Definir una relación inversa.

Los esquemas de App Services no admiten relaciones inversas. Esto se debe a que representan una relación implícita en Realm que se actualiza automáticamente al modificar el vínculo de retroceso. Esto significa que no se puede establecer directamente el valor de una relación inversa, y esta no existe en Atlas. En su lugar, Realm deriva y actualiza dichas relaciones automáticamente en la aplicación cliente, basándose en el modelo de objetos de Realm.

Consideremos un caso donde el objeto Pond tiene una relación inversa con el objeto Frog.

Estanque con relación inversa a la rana
class Pond : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
// Backlink to the `Frog` that has this `Pond` as its favorite
val frog: RealmResults<Frog> by backlinks(Frog::favoritePonds)
}
class Frog : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
var age: Int? = null
// To-many relationship (can have many ponds)
var favoritePonds: RealmList<Pond> = realmListOf()
}

En el esquema de App Services, vemos que tiene una Frog relación de varios con Pond mediante la favoritePonds propiedad. Sin embargo, la frog propiedad, que representa la relación inversa con Frog de nuestro Pond modelo,no está presente. Esto se debe a que la relación inversa no se puede definir explícitamente en Atlas. No obstante, Realm la actualizará automáticamente al agregar o eliminar un objeto de la relación.

Esquema de servicios de aplicaciones
// `Pond` schema in App Services DOES NOT contain the
// `frog` inverse relationship property
{
"title": "Pond",
"type": "object",
"required": [
"_id",
"name"
],
"properties": {
"_id": {
"bsonType": "objectId"
},
"name": {
"bsonType": "string"
}
}
}
{
"title": "Frog",
"type": "object",
"required": [
"_id",
"name"
],
"properties": {
"_id": {
"bsonType": "objectId"
},
"age": {
"bsonType": "long"
},
"favoritePonds": {
"bsonType": "array",
"items": {
"bsonType": "objectId"
}
},
"name": {
"bsonType": "string"
}
}
}

Los objetos incrustados representan datos anidados dentro de un único objeto principal específico. Puedes hacer referencia a un tipo de objeto incrustado desde los tipos de objeto principal de la misma forma que definirías una relación. Para más información sobre cómo se definen los objetos incrustados en el SDK de Kotlin, consulta Definir un objeto incrustado.

Sin embargo, a diferencia de los objetos Realm normales, los objetos incrustados no se almacenan en su propia colección en Atlas. Se almacenan como parte del documento del objeto principal y no son accesibles fuera de él.

En el siguiente ejemplo, tenemos un objeto Frog con una propiedad favoritePond que hace referencia a un único objeto Pond incrustado y un objeto Forest con una propiedad de relación forestPonds que hace referencia a una lista de muchos objetos Pond incrustados:

Rana y bosque con relaciones de estanque integradas
class Frog : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
var age: Int? = null
// Embed a single object (MUST be optional)
var favoritePond: EmbeddedPond? = null
}
class Forest : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
// Embed multiple objects (can have many ponds)
var forestPonds: RealmList<EmbeddedPond> = realmListOf()
}
class EmbeddedPond : EmbeddedRealmObject {
var name: String? = null
}

En el esquema de Servicios de aplicación, se observa que los objetos incrustados se mapean en documentos de cada tipo principal:

Esquema de servicios de aplicaciones
{
"title": "Frog",
"type": "object",
"required": [
"_id",
"name"
],
"properties": {
"_id": {
"bsonType": "objectId"
},
"age": {
"bsonType": "long"
},
"favoritePond": {
"title": "EmbeddedPond",
"type": "object",
"required": [],
"properties": {
"name": {
"bsonType": "string"
}
}
},
"name": {
"bsonType": "string"
}
}
}
{
"title": "Forest",
"type": "object",
"required": [
"_id",
"name"
],
"properties": {
"_id": {
"bsonType": "objectId"
},
"forestPonds": {
"bsonType": "array",
"items": {
"title": "EmbeddedPond",
"type": "object",
"required": [],
"properties": {
"name": {
"bsonType": "string"
}
}
}
},
"name": {
"bsonType": "string"
}
}
}

Las siguientes tablas muestran cómo los tipos de objeto de Realm se asignan a un tipo BSON de esquema de App Services correspondiente. Para obtener una lista completa de los tipos de esquema de App Services compatibles, sus asignaciones y propiedades disponibles, consulte "Asignación de modelos de datos" en la documentación de App Services.

En la siguiente tabla se enumeran los tipos de datos de Kotlin admitidos y ejemplos de cómo las propiedades declaradas se asignan entre un esquema de Realm y un esquema de App Services.

Para obtener más información sobre los tipos de datos de Kotlin compatibles con el SDK de Kotlin y cómo definirlos en su modelo de datos, consulte Tipos de datos de Kotlin.

Tipo de datos de Kotlin
Objeto de reino
Esquema de servicios de aplicaciones

String

var stringReq: String = ""
"stringReq": {
"bsonType": "string"
}

Byte

var byteReq: Byte = 0
"byteReq": {
"bsonType": "long"
}

Short

var shortReq: Short = 0
"shortReq": {
"bsonType": "long"
}

Int

var intReq: Int = 0
"intReq": {
"bsonType": "long"
}

Long

var longReq: Long = 0L
"longReq": {
"bsonType": "long"
}

Float

var floatReq: Float = 0.0f
"floatReq": {
"bsonType": "float"
}

Double

var doubleReq: Double = 0.0
"doubleReq": {
"bsonType": "double"
}

Boolean

var boolReq: Boolean = false
"boolReq": {
"bsonType": "bool"
}

Char

var charReq: Char = 'a'
"charReq": {
"bsonType": "long"
}

En la siguiente tabla se enumeran los tipos de datos BSON de MongoDB admitidos y ejemplos de cómo las propiedades declaradas se asignan entre un esquema de Realm y un esquema de App Services.

Para obtener más información sobre los tipos de datos BSON de MongoDB compatibles con el SDK de Kotlin y cómo definirlos en su modelo de datos, consulte Tipos de datos de Kotlin.

Tipo BSON de MongoDB
Objeto de reino
Esquema de servicios de aplicaciones
var objectIdReq: ObjectId = ObjectId()
"objectIdReq": {
"bsonType": "objectId"
}

Decimal128

var decimal128Req: Decimal128 = Decimal128("123.456")
"decimal128Req": {
"bsonType": "decimal"
}

En la siguiente tabla se enumeran los tipos de datos específicos de Realm admitidos y ejemplos de cómo las propiedades declaradas se asignan entre un esquema de Realm y un esquema de App Services.

Para obtener información sobre los tipos de datos específicos de Realm que admite el SDK de Kotlin y cómo definirlos en su modelo de datos, consulte Tipos de datos de Kotlin.

Tipo específico del reino
Objeto de reino
Esquema de servicios de aplicaciones
var uuidReq: RealmUUID = RealmUUID.random()
"uuidReq": {
"bsonType": "uuid"
}
var realmInstantReq: RealmInstant = RealmInstant.now()
"realmInstantReq": {
"bsonType": "date"
}
var realmAnyOpt: RealmAny? = RealmAny.create("foo")
"realmAnyOpt": {
"bsonType": "mixed"
}
var mutableRealmIntReq: MutableRealmInt = MutableRealmInt.create(0)
"mutableRealmIntReq": {
"bsonType": "long"
}
var listReq: RealmList<CustomObjectType> = realmListOf()
"listReq": {
"bsonType": "array",
"items": {
"bsonType": "uuid"
}
}
var setReq: RealmSet<String> = realmSetOf()
"setReq": {
"bsonType": "array",
"uniqueItems": true,
"items": {
"bsonType": "string"
}
}
var dictionaryReq: RealmDictionary<String> = realmDictionaryOf()
"dictionaryReq": {
"bsonType": "object",
"additionalProperties": {
"bsonType": "string"
}
}
var realmObjectPropertyOpt: CustomObjectType? = null
"realmObjectPropertyOpt": {
"bsonType": "<PRIMARY_KEY_TYPE>"
}
var embeddedProperty: EmbeddedObjectType? = null
"embeddedProperty": {
"title": "EmbeddedObjectType",
"type": "object",
"required": [],
"properties": {
"name": {
"bsonType": "string"
}
}
}

Volver

Cambiar un modelo de objeto

En esta página