Menu Docs
Página inicial do Docs
/ /
Atlas Device SDKs
/ / /

Modelar dados com Device Sync - Kotlin SDK

Nesta página

  • Definir um Modelo de dados Realm do Realm Mobile Sync
  • Gerar um esquema a partir do aplicativo do cliente
  • Gerar um esquema com dados Atlas existentes
  • Requisitos de sincronização de dispositivos
  • Mapeamento de Objeto de Realm
  • Mapeamento de relacionamentos com o Realm
  • Mapear relacionamentos para um
  • Relacionamento com muitos
  • Relacionamento inverso
  • Objetos embarcados
  • Lista de mapeamento de tipos de esquema
  • Tipos de Kotlin
  • Tipos de JSON
  • Tipos de Realm

Esta página descreve o Modelo de dados Realm do Realm Mobile Sync e como ele é usado para mapear dados do esquema do App Services usado pelo Realm Mobile Sync para o esquema Realm usado pelo Kotlin SDK no cliente.

Esta página não:

Para obter uma explicação detalhada do Device Sync, consulte Introdução ao Atlas Device Sync na documentação do Atlas App Services .

Dica

A tabela na seção Lista de mapeamento de tipos de esquema nesta página fornece uma referência rápida para tipos de dados suportados e como eles mapeiam entre o Realm e o App Services. Para obter um recurso mais abrangente, consulte Mapeamento do modelo de dados na documentação do App Services.

O Modelo de dados Realm do Atlas Device Sync é definido pelos seguintes esquemas, o que permite ao Realm Mobile Sync mapear seus dados entre o cliente e o Atlas:

  • Esquema de Realm: o modelo de objeto do lado do cliente em seu aplicativo que define seus dados como classes do Kotlin usando o Kotlin SDK.

  • Esquema do App Services: o esquema do lado do servidor no Atlas App Services que define seus dados no BSON. Para obter mais informações, consulte Esquemas na documentação do App Services.

O Realm Mobile Sync usa esses esquemas para validar e converter objeto entre o formato Kotlin e BSON ao sincronizar dados. Quando você sincroniza dados do cliente, o Realm Mobile Sync converte automaticamente os tipos de dados Realm Kotlin em BSON. Em seguida, quando o dispositivo cliente sincroniza os dados do Atlas via Device Sync, o SDK converte os dados BSON de volta para objetos Kotlin.

Para usar o Realm Mobile Sync, você deve definir um esquema Realm e um esquema App Services, e ambos os esquemas devem ser consistentes entre si.

Você pode definir seu esquema no aplicativo cliente ou no Atlas primeiro, dependendo da sua preferência e caso de uso. Em seguida, você pode gerar um esquema correspondente com modelos de objetos correspondentes.

Se você estiver desenvolvendo uma nova aplicação cliente, é provável que queira iterar no Modelo de dados Realm no aplicação cliente. Depois de definir um modelo de objeto diretamente no código do aplicativo cliente, você pode ativar o modo de desenvolvimento no App Services para gerar um esquema correspondente do App Services automaticamente.

O modo de desenvolvimento é uma configuração que permite ao Device Sync inferir e atualizar esquemas com base em modelos de dados do lado do cliente quando você sincroniza dados do cliente. Para obter mais informações, consulte Modo de desenvolvimento na documentação do App Services.

Se você estiver desenvolvendo um aplicação cliente que funcione com dados que já existem no Atlas, poderá gerar um esquema a partir desses dados e, em seguida, gerar modelos de objeto do SDK para usar em seu aplicativo cliente Kotlin . Para saber mais, consulte Sincronizar dados no Atlas com um aplicativo de cliente na documentação do App Services.

Existem alguns requisitos para sincronizar objetos com êxito. Conforme descrito anteriormente, você deve ter esquemas correspondentes do Realm e do App Services que contenham os objetos que você deseja sincronizar.

Além disso, o Realm Mobile Sync exige que:

  • Seus modelos de objeto devem ter um campo de chave primária chamado _id. Pode ser do tipo String, Int ou ObjectId. O Realm Mobile Sync usa isso para identificar objeto nas collection do Atlas.

    Se um objeto não tiver um campo _id definido, o Realm lançará o seguinte erro de validação de esquema: There must be a primary key property named '_id' on a synchronized Realm.

  • Cada classe deve ter pelo menos um campo de query.

    Quando o modo de desenvolvimento está habilitado, o campo que você inclui na query de assinatura do cliente são adicionados automaticamente como campo de query no Atlas. Para obter mais informações sobre como configurar assinaturas com o Kotlin SDK, consulte Visão geral das assinaturas.

Objeto de Realm são as instâncias nomeadas exclusivamente de classes Kotlin definidas em seu esquema de Realm que determinam a propriedade e o relacionamento dos objeto desse tipo.

O App Services mapeia Objeto de Realm para o Atlas das seguintes maneiras:

  • Os nomes de Objeto de Realm são mapeados para as collection do Atlas no seu Realm Mobile Sync vinculado. Observe o seguinte:

    • Quando o modo de desenvolvimento está habilitado, o App Services cria automaticamente uma collection e um esquema para cada novo Tipo de objeto de Realm que você sincroniza.

    • Objetos embarcados não são armazenados em sua própria collection no Atlas. Isso ocorre porque eles não podem existir fora de seu tipo de objeto pai. Consulte a seção Objetos incorporados nesta página para obter mais informações.

  • O esquema de objetos do Realm é mapeado para um esquema do App Services dentro de sua collection apropriada.

No exemplo a seguir, temos objetos Frog e Pond com propriedades básicas definidas em nosso Realm Schema:

Frog e Pond Objeto de Realm
// 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 = ""
}

No Atlas, podemos ver como esses Tipo de objeto de Realm são mapeados para esquemas correspondentes do App Services -- cada objeto é mapeado para sua respectiva collection. Também vemos exemplos de objeto de rãs e pequenos campos que estão em conformidade com este Modelo de dados Realm:

collection Frog no App Services
{
"title": "Frog",
"type": "object",
"required": [
"_id",
"name"
],
"properties": {
"_id": {
"bsonType": "objectId"
},
"age": {
"bsonType": "long"
},
"name": {
"bsonType": "string"
}
}
}
Collection de pools no App Services
{
"title": "Pond",
"type": "object",
"required": [
"_id",
"name"
],
"properties": {
"_id": {
"bsonType": "objectId"
},
"name": {
"bsonType": "string"
}
}
}
Exemplo de objeto de Rã no Atlas
{
"_id": ObjectId("5af712eff26b29dc5c51c60f"),
"name": "Kermit",
"age": 42
}
Exemplo de objeto de Lagoa no Atlas
{
"_id": ObjectId("5af714eff24b294c5251cf04"),
"name": "Kermit's Pond"
}

Seu modelo de objetos do Realm pode incluir relacionamento entre objetos. Existem dois tipos principais de relacionamentos:

  • Relacionamento para um: um objeto está relacionado de uma forma específica a não mais do que um outro objeto de Realm.

  • Relacionamento entre muitos: um objeto está relacionado de uma maneira específica a vários objeto de Realm.

Os relacionamentos são mapeados por propriedades que referenciam a chave primária do outro objeto do Realm.

Para obter mais informações sobre como modelar relacionamentos em um esquema do Atlas App Services , consulte Relacionamentos na documentação do Atlas App Services .

Um relacionamento para um mapeia uma propriedade para uma única instância de outro Objeto de Realm. Relacionamento um-para-um devem ser opcionais. Para obter mais informações sobre como os relacionamentos um-para-um são definidos no Kotlin SDK, consulte Definir uma propriedade de relacionamento para um.

Usando os objetos no exemplo acima, considere um caso em que um Frog pode ter um pool favorito. Podemos adicionar uma propriedade favoritePond ao nosso modelo Frog que é um link opcional para um objeto Pond .

Rã com relacionamento um-para-um com o Lago
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
}

No esquema do App Services, vemos a nova propriedade ser convertida em um campo favoritePond:

  • O campo não está na array required porque é uma propriedade opcional.

  • Seu tipo é um objectId vinculado a um objeto Pond específico na coleção Pond separada. Isso ocorre porque definimos a chave primária em nosso modelo Pond como objectId.

O esquema Pond não muda. Como este é um relacionamento para um, é um relacionamento unidirecional; o Pond não tem relacionamento com Frog.

appservices schema
{
"title": "Frog",
"type": "object",
"required": [
"_id",
"name"
],
"properties": {
"_id": {
"bsonType": "objectId"
},
"age": {
"bsonType": "long"
},
"favoritePond": {
"bsonType": "objectId"
},
"name": {
"bsonType": "string"
}
}
}

Um relacionamento para muitos mapeia uma propriedade para zero ou mais instâncias de outro Objeto de Realm. Para obter mais informações sobre como os relacionamentos para muitos são definidos no Kotlin SDK, consulte Definir uma propriedade de relacionamento para muitos.

Considere outro caso em que um Frog pode ter muitos pools favoritos em vez de apenas um. Adicionamos uma propriedade favoritePonds ao nosso modelo Frog que é uma lista de objetos Pond . Se a rã não tiver lagunas favoritas, esta é uma lista vazia. À medida que a rã obtém suas poás favoritas, podemos criar novos objetos Pond e anexá-los à lista favoritePonds da rã.

Rã com relacionamento um-para-muitos com o Lago
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()
}

No esquema do App Services, vemos a nova propriedade ser convertida em um campo favoritePonds que contém todos os objetos Pond relacionados ao objeto Frog :

  • O campo não está na array required porque é uma propriedade opcional.

  • O tipo deste campo é uma array do tipo objectId. Isso ocorre porque definimos a chave primária em nosso modelo Pond como um objectId.

Novamente, que o esquema Pond não muda porque o Pond não tem relacionamento com Frog.

appservices schema
{
"title": "Frog",
"type": "object",
"required": [
"_id",
"name"
],
"properties": {
"_id": {
"bsonType": "objectId"
},
"age": {
"bsonType": "long"
},
"favoritePonds": {
"bsonType": "array",
"items": {
"bsonType": "objectId"
}
},
"name": {
"bsonType": "string"
}
}
}

Um relacionamento inverso vincula um objeto a qualquer outro objeto que se refira a ele em um relacionamento definido como "um" ou "muitos" chamado de backlink. Para obter mais informações sobre como os relacionamentos inversos são definidos no Kotlin SDK, consulte Definir um relacionamento inverso.

Os esquemas do App Services não oferecem suporte a relacionamentos inversos. Isso ocorre porque o relacionamento inverso representa um relacionamento implícito no Realm que é atualizado automaticamente quando o backlink é modificado. Isso significa que você não pode definir diretamente o valor de um relacionamento inverso, e o relacionamento não existe no Atlas. Em vez disso, o Realm deriva e atualiza esses relacionamento para você na aplicação cliente com base em seu modelo de objetos do Realm.

Considere um caso em que o objeto Pond tem um relacionamento inverso ao objeto Frog .

Lagoa com relacionamento inverso com a rã
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()
}

No esquema do App Services, vemos que o Frog tem o relacionamento para-muitos com o Pond por meio da propriedade favoritePonds . No entanto, a propriedade frog que representa o relacionamento inverso para um Frog do nosso modelo Pond não está presente. Isso ocorre porque o relacionamento inverso não pode ser explicitamente definido no Atlas. No entanto, o Realm o atualizará automaticamente sempre que você adicionar ou remover um objeto do relacionamento.

appservices schema
// `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"
}
}
}

Objeto incorporado representam dados aninhados dentro de um único objeto pai específico. Você pode referenciar um objeto incorporado Tipo de objeto de Realm a partir dos Tipo de objeto de Realm principais da mesma forma que definiria um relacionamento. Para obter mais informações sobre como os objetos incorporados são definidos no Kotlin SDK, consulte Definir um objeto incorporado.

No entanto, ao contrário dos objeto de Realm, o objeto incorporado não são armazenados em sua própria collection no Atlas. Em vez disso, eles são armazenados como parte do documento do objeto pai e não são acessíveis fora do objeto pai.

No exemplo a seguir, temos um objeto Frog com uma propriedade favoritePond que referencia um único objeto Pond incorporado e um objeto Forest com uma propriedade de relacionamento forestPonds que referencia uma lista de muitos objetos Pond incorporados :

Frog ephest com relacionamentos de Pond incorporados
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
}

No esquema do App Services, vemos o mapa de objetos incorporados para documentos em cada tipo principal:

appservices schema
{
"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"
}
}
}

As tabelas a seguir demonstram como Realm os tipos de objetos de são mapeados para um Atlas App Services BSON tipo de de esquema correspondente . Para obter uma lista completa dos tipos de esquema suportados do Atlas App Services e seus mapeamentos e propriedades disponíveis, consulte Mapeamento de Modelo de Dados na documentação do Atlas App Services .

A tabela a seguir lista os tipos de dados Kotlin com suporte e exemplos de como as propriedades declaradas são mapeadas entre um esquema do Realm e um esquema do App Services.

Para obter mais informações sobre os tipos de dados Kotlin suportados pelo Kotlin SDK e como defini-los em seu Modelo de dados Realm, consulte Tipos de dados do Kotlin.

Tipo de Dados de Kotlin
Objeto de Realm
appservices schema
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"
}

A tabela a seguir lista os tipos de dados BSON do MongoDB suportados e exemplos de como as propriedades declaradas são mapeadas entre um esquema do Realm e um esquema do App Services.

Para obter mais informações sobre os tipos de dados BSON do MongoDB suportados pelo Kotlin SDK e como defini-los em seu Modelo de dados Realm, consulte Tipos de dados do Kotlin.

Tipo de JSON do MongoDB
Objeto de Realm
appservices schema
var objectIdReq: ObjectId = ObjectId()
"objectIdReq": {
"bsonType": "objectId"
}
Decimal128
var decimal128Req: Decimal128 = Decimal128("123.456")
"decimal128Req": {
"bsonType": "decimal"
}

A tabela a seguir lista os tipos de dados específicos do Realm com suporte e exemplos de como as propriedades declaradas são mapeadas entre um esquema do Realm e um esquema do App Services.

Para obter mais informações sobre os tipos de dados específicos do domínio suportados pelo Kotlin SDK e como defini-los em seu Modelo de dados Realm, consulte Tipos de dados do Kotlin.

Tipo Específico do domínio
Objeto de Realm
appservices schema
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"
}
}
}

Voltar

Alterar um modelo de objeto