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:
Explica cómo definir un modelo de objetos de Realm en la aplicación cliente. Para saber cómo, consulta "Definir un modelo de objetos de Realm - SDK de Kotlin".
Explica cómo configurar la sincronización de dispositivos en una aplicación cliente. Para saber cómo, consulta "Añadir sincronización de dispositivos a una aplicación - SDK de Kotlin".
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.
Define un Device Sync modelo de datos
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.
Generar un esquema desde la aplicación cliente
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.
Generar un esquema con datos Atlas existentes
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.
Requisitos de sincronización del dispositivo
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 tipoString,IntoObjectId. 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".
Mapeo de Objetos Realm
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:
// Maps to `Frog` collection class Frog : RealmObject { var _id: ObjectId = ObjectId() var name: String = "" var age: Int? = null } // Maps to `Pond` collection class Pond : RealmObject { 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:
{ "title": "Frog", "type": "object", "required": [ "_id", "name" ], "properties": { "_id": { "bsonType": "objectId" }, "age": { "bsonType": "long" }, "name": { "bsonType": "string" } } }
{ "title": "Pond", "type": "object", "required": [ "_id", "name" ], "properties": { "_id": { "bsonType": "objectId" }, "name": { "bsonType": "string" } } }
{ "_id": ObjectId("5af712eff26b29dc5c51c60f"), "name": "Kermit", "age": 42 }
{ "_id": ObjectId("5af714eff24b294c5251cf04"), "name": "Kermit's Pond" }
Mapeo de relaciones entre reinos
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.
Relaciones de mapa a uno
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.
class Frog : RealmObject { 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
requiredporque es una propiedad opcional.Su tipo es
objectIdy enlaza a un objetoPondespecífico en la colecciónPondindependiente. Esto se debe a que definimos la clave principal en nuestro modeloPondcomoobjectId.
El esquema Pond no cambia. Al ser una relación de uno a uno, es unidireccional; Pond no tiene relación con Frog.
{ "title": "Frog", "type": "object", "required": [ "_id", "name" ], "properties": { "_id": { "bsonType": "objectId" }, "age": { "bsonType": "long" }, "favoritePond": { "bsonType": "objectId" }, "name": { "bsonType": "string" } } }
Relación de muchos
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.
class Frog : RealmObject { 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
requiredporque 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 modeloPondcomoobjectId.
Nuevamente, el esquema Pond no cambia porque Pond no tiene relación con Frog.
{ "title": "Frog", "type": "object", "required": [ "_id", "name" ], "properties": { "_id": { "bsonType": "objectId" }, "age": { "bsonType": "long" }, "favoritePonds": { "bsonType": "array", "items": { "bsonType": "objectId" } }, "name": { "bsonType": "string" } } }
Relación inversa
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.
class Pond : RealmObject { 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 { 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.
// `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" } } }
Objetos incrustados
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:
class Frog : RealmObject { 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 { 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:
{ "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" } } }
Lista de mapeo de tipos de esquema
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.
Tipos de Kotlin
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 | ||||
|---|---|---|---|---|---|---|
| | | ||||
| | | ||||
| | | ||||
| | | ||||
| | | ||||
| | | ||||
| | | ||||
| | | ||||
| | |
BSON Types
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 | ||||
|---|---|---|---|---|---|---|
| | |||||
| | |
Tipos de reino
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 | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| | ||||||||||||
| | ||||||||||||
| | ||||||||||||
| | ||||||||||||
| | ||||||||||||
| | ||||||||||||
| | ||||||||||||
| | ||||||||||||
| |