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

Gerenciar assinaturas de Flexible Sync - SDK Java

Nesta página

  • Visão geral
  • Inscrever-se para campos de query
  • Adicionar uma assinatura
  • Aguarde as alterações na assinatura para sincronizar
  • Atualizar assinaturas com uma nova query
  • Remover subscrições
  • Requisitos e limitações do Flexible Sync RQL
  • Requisitos de inscrição de campos de query indexados
  • Operadores de consulta não suportados na sincronização flexível
  • Listar queries
  • Objetos incorporados ou vinculados
  • Limite de tamanho da query

Flexible Sync usa assinaturas e permissões para determinar quais dados sincronizar com seu aplicativo.

Para usar o Flexible Sync no SDK:

  • Configurar o Flexible Sync no backend

  • Inicialize o aplicativo

  • Autenticar um usuário em seu projeto de cliente.

  • Abra o Realm sincronizado com uma configuração Flexible Sync

  • Adicione assinaturas ao aplicativo cliente

Você pode adicionar, atualizar e remover assinaturas de query para determinar quais dados são sincronizados com o dispositivo cliente.

Dica

Veja também:

Esta página detalha como managed assinaturas para Flexible Sync.

Para informações gerais sobre o uso do Atlas Device Sync com o SDK, como Realm Mobile Sync alterações em segundo plano ou pausar uma sessão de sincronização, consulte Sincronizar alterações entre dispositivos.

Para obter informações sobre a configuração de permissões para o Flexible Sync, consulte Regras e permissões do Flexible Sync.

Ao configurar o Flexible Sync no backend, você especifica quais campos seu aplicativo cliente pode executar uma query. Na aplicação cliente, use a API do subscriptions para managed um conjunto de assinaturas para query específicas em campo de query. Você pode construir query com a interface fluente do Java SDK ou RealmQL.

Importante

Flexible Sync não é compatível com todos os operadores disponíveis no RQL. Consulte LimitaçõesFlexible Sync RQL de sincronização para obter detalhes.

Você pode:

  • Adicionar subscrições

  • Reagir ao estado da assinatura

  • Atualizar assinaturas com novas queries

  • Remover assinaturas individuais ou todas as assinaturas de um tipo de objeto

Os dados correspondentes à assinatura, nos quais o usuário tem as permissões apropriadas, são sincronizados entre os clientes e o aplicativo de backend.

Você pode especificar um nome de string opcional para sua assinatura.

Dica

Sempre especificar um nome de assinatura

Sempre especifique um nome de assinatura se seu aplicativo usar várias assinaturas. Isso torna mais fácil procurar, atualizar e excluir suas assinaturas em outro lugar do seu aplicativo.

Quando você cria uma assinatura, o Realm procura dados correspondentes a uma query em um tipo de objeto específico. Você pode ter vários conjuntos de assinaturas em diferentes tipos de objetos. Você também pode ter várias queries no mesmo tipo de objeto.

Você pode criar uma assinatura com um nome explícito. Em seguida, você pode pesquisar essa assinatura por nome para atualizá-la ou removê-la.

SyncConfiguration config = new SyncConfiguration.Builder(app.currentUser())
.initialSubscriptions(new SyncConfiguration.InitialFlexibleSyncSubscriptions() {
@Override
public void configure(Realm realm, MutableSubscriptionSet subscriptions) {
// add a subscription with a name
subscriptions.add(Subscription.create("frogSubscription",
realm.where(Frog.class)
.equalTo("species", "spring peeper")));
}
})
.build();
Realm.getInstanceAsync(config, new Realm.Callback() {
@Override
public void onSuccess(Realm realm) {
Log.v("EXAMPLE", "Successfully opened a realm.");
// later, you can look up this subscription by name
Subscription subscription = realm.getSubscriptions().find("frogSubscription");
}
});
val config = SyncConfiguration.Builder(app.currentUser())
.initialSubscriptions { realm, subscriptions ->
// add a subscription with a name
subscriptions.add(
Subscription.create(
"frogSubscription",
realm.where(Frog::class.java)
.equalTo("species", "spring peeper")
)
)
}
.build()
Realm.getInstanceAsync(config, object : Realm.Callback() {
override fun onSuccess(realm: Realm) {
Log.v("EXAMPLE", "Successfully opened a realm.")
// later, you can look up this subscription by name
val subscription =
realm.subscriptions.find("frogSubscription")
}
})

Você também pode pesquisar assinaturas por query. Se você omitir o nome ao criar uma assinatura, essa será a única maneira de procurar sua assinatura.

SyncConfiguration config = new SyncConfiguration.Builder(app.currentUser())
.initialSubscriptions(new SyncConfiguration.InitialFlexibleSyncSubscriptions() {
@Override
public void configure(Realm realm, MutableSubscriptionSet subscriptions) {
// add a subscription without assigning a name
subscriptions.add(Subscription.create(
realm.where(Frog.class)
.equalTo("species", "spring peeper")));
}
})
.build();
Realm.getInstanceAsync(config, new Realm.Callback() {
@Override
public void onSuccess(Realm realm) {
Log.v("EXAMPLE", "Successfully opened a realm.");
// later, you can look up this subscription by query
Subscription subscription = realm.getSubscriptions().find(realm.where(Frog.class)
.equalTo("species", "spring peeper"));
}
});
val config = SyncConfiguration.Builder(app.currentUser())
.initialSubscriptions { realm, subscriptions ->
// add a subscription without assigning a name
subscriptions.add(
Subscription.create(
realm.where(Frog::class.java)
.equalTo("species", "spring peeper")
)
)
}
.build()
Realm.getInstanceAsync(config, object : Realm.Callback() {
override fun onSuccess(realm: Realm) {
Log.v("EXAMPLE", "Successfully opened a realm.")
// later, you can look up this subscription by query
val subscription =
realm.subscriptions.find(
realm.where(
Frog::class.java
).equalTo("species", "spring peeper")
)
}
})

Observação

Subscrições duplicadas

Os nomes das assinaturas devem ser exclusivos. Adicionar uma assinatura com o mesmo nome de uma assinatura existente exibe um erro.

Se você não nomear explicitamente uma assinatura e, em vez disso, assinar a mesma query sem nome mais de uma vez, o Realm não persistirá queries duplicadas ao conjunto de assinaturas.

Se você assinar a mesma query mais de uma vez com nomes diferentes, a Realm manterá as duas assinaturas no conjunto de assinaturas.

Adicione uma assinatura em um bloco de gravação de assinaturas. Você anexa cada nova assinatura às assinaturas do Realm do cliente.

SyncConfiguration config = new SyncConfiguration.Builder(app.currentUser())
.initialSubscriptions(new SyncConfiguration.InitialFlexibleSyncSubscriptions() {
@Override
public void configure(Realm realm, MutableSubscriptionSet subscriptions) {
subscriptions.add(Subscription.create("subscriptionName",
realm.where(Frog.class)
.equalTo("species", "spring peeper")));
}
})
.build();
// instantiate a realm instance with the flexible sync configuration
Realm.getInstanceAsync(config, new Realm.Callback() {
@Override
public void onSuccess(Realm realm) {
Log.v("EXAMPLE", "Successfully opened a realm.");
}
});
val config = SyncConfiguration.Builder(app.currentUser())
.initialSubscriptions { realm, subscriptions ->
subscriptions.add(
Subscription.create(
"subscriptionName",
realm.where(Frog::class.java)
.equalTo("species", "spring peeper")
)
)
}
.build()
// instantiate a realm instance with the flexible sync configuration
Realm.getInstanceAsync(config, object : Realm.Callback() {
override fun onSuccess(realm: Realm) {
Log.v("EXAMPLE", "Successfully opened a realm.")
}
})

Observação

Links de objetos

Você deve adicionar um objeto e seu objeto vinculado ao conjunto de assinaturas para ver um objeto vinculado.

Se os resultados de sua assinatura contiverem um objeto com uma propriedade vinculada a um objeto não contido nos resultados, o link parecerá nulo. Não há como distinguir se o valor dessa propriedade é legitimamente nulo ou se o objeto ao qual ela se vincula existe, mas está fora da exibição da assinatura de query..

Escrever uma atualização para o conjunto de assinatura localmente é apenas um componente da alteração de uma assinatura. Após a alteração da assinatura local, o cliente sincroniza com o servidor para resolver quaisquer atualizações nos dados devido à alteração da assinatura . Isso pode média adicionar ou remover dados do Realm sincronizado. Use o método de construtor waitForInitialRemoteData() para forçar seu aplicação a bloquear até que os dados de assinatura do cliente sejam sincronizados com o backend antes de abrir o Realm:

SyncConfiguration config = new SyncConfiguration.Builder(app.currentUser())
.initialSubscriptions(new SyncConfiguration.InitialFlexibleSyncSubscriptions() {
@Override
public void configure(Realm realm, MutableSubscriptionSet subscriptions) {
subscriptions.add(Subscription.create("my subscription",
realm.where(Frog.class)
.equalTo("species", "poison dart")));
}
})
.waitForInitialRemoteData(2112, TimeUnit.MILLISECONDS)
.build();
Realm.getInstanceAsync(config, new Realm.Callback() {
@Override
public void onSuccess(Realm realm) {
Log.v("EXAMPLE", "Successfully opened a realm.");
}
});
val config = SyncConfiguration.Builder(app.currentUser())
.initialSubscriptions { realm, subscriptions ->
subscriptions.add(
Subscription.create(
"my subscription",
realm.where(Frog::class.java)
.equalTo("species", "poison dart")
)
)
}
.waitForInitialRemoteData(
2112,
TimeUnit.MILLISECONDS
)
.build()
Realm.getInstanceAsync(config, object : Realm.Callback() {
override fun onSuccess(realm: Realm) {
Log.v("EXAMPLE", "Successfully opened a realm.")
}
})

Você também pode usar SubscriptionSet.waitForSynchronization() ou SubscriptionSet.waitForSynchronizationAsync() para atrasar a execução até que a sincronização da assinatura seja concluída após instanciar uma conexão de sincronização.

Além disso, você pode observar o estado do conjunto de assinaturas com o enum SubscriptionSet.State . Você pode usar o estado da assinatura para:

  • Mostrar um indicador de progresso enquanto os dados estão sendo baixados

  • Descubra quando um conjunto de assinaturas é substituído

Você pode acessar o estado do conjunto de assinaturas do seu aplicativo usando SubscriptionSet.getState().

Observação

Estado da assinatura "Concluído"

O estado do conjunto de assinaturas "complete" não significa que a sincronização "está concluída" ou "todos os documentos foram sincronizados". "Completo" significa que as duas coisas a seguir aconteceram:

  • A assinatura se tornou o conjunto de assinaturas ativo que está sendo atualmente sincronizado com o servidor.

  • Os documentos que correspondiam à assinatura no momento em que a assinatura foi enviada ao servidor agora estão no dispositivo local. Observe que isso não inclui necessariamente todos os documentos que atualmente correspondem à assinatura.

O SDK do Realm não fornece uma maneira de verificar se todos os documentos que correspondem a uma assinatura foram sincronizados com o dispositivo.

SUPERSEDED é um SubscriptionSet.State que pode ocorrer quando outro thread grava uma assinatura em uma instância diferente do conjunto de assinaturas. Se o estado se tornar SUPERSEDED, você deverá obter uma nova instância do conjunto de assinaturas antes de poder gravar nele.

Você pode atualizar assinaturas usando SubscriptionSet.update(). Neste exemplo, usamos MutableSubscriptionSet.addOrUpdate() para atualizar a query para a assinatura chamada "minha assinatura de Frog":

realm.getSubscriptions().update(new SubscriptionSet.UpdateCallback() {
@Override
public void update(MutableSubscriptionSet subscriptions) {
// to update a named subscription, create a replacement with
// the same name and add it to the subscription set
subscriptions.addOrUpdate(
Subscription.create("my frog subscription",
realm.where(Frog.class)
.equalTo("name",
"Benedict Cumberburger")));
}
});
realm.subscriptions.update { subscriptions ->
// to update a named subscription, create a replacement with
// the same name and add it to the subscription set
subscriptions.addOrUpdate(
Subscription.create(
"my frog subscription",
realm.where(Frog::class.java)
.equalTo(
"name",
"Benedict Cumberburger"
)
)
)
}

Você não pode atualizar assinaturas criadas sem um nome. No entanto, você pode procurar assinaturas não nomeadas por query, removê-las do conjunto de assinaturas e adicionar uma nova assinatura com uma query atualizada:

realm.getSubscriptions().update(new SubscriptionSet.UpdateCallback() {
@Override
public void update(MutableSubscriptionSet subscriptions) {
// to update an unnamed subscription, remove it from the
// subscription set, then add your new query to the set
Subscription mySubscription = subscriptions.find(realm.where(Frog.class)
.equalTo("species",
"cane toad"));
subscriptions.remove(mySubscription);
subscriptions.addOrUpdate(
Subscription.create(
realm.where(Frog.class)
.equalTo("species",
"albino cane toad")));
}
});
realm.subscriptions.update { subscriptions ->
// to update an unnamed subscription, remove it from the
// subscription set, then add your new query to the set
val mySubscription =
subscriptions.find(
realm.where(
Frog::class.java
).equalTo(
"species",
"cane toad"
)
)
subscriptions.remove(mySubscription)
subscriptions.addOrUpdate(
Subscription.create(
realm.where(Frog::class.java)
.equalTo(
"species",
"albino cane toad"
)
)
)
}

Para remover assinaturas, você pode:

  • Remover uma query de assinatura única

  • Remover todas as assinaturas de um tipo de objeto específico

  • Remover todas as assinaturas

Quando você remove uma query de assinatura, o Realm remove assíncronamente os dados sincronizados que corresponderam à query do dispositivo cliente.

Você pode remover uma query de assinatura específica usando MutableSubscriptionSet.remove(). Você pode procurar a assinatura por nome e, em seguida, passar a assinatura retornada para remove() ou passar o nome da assinatura diretamente para remove():

realm.getSubscriptions().update(new SubscriptionSet.UpdateCallback() {
@Override
public void update(MutableSubscriptionSet subscriptions) {
Subscription mySubscription = subscriptions.find("mySubscription");
subscriptions.remove(mySubscription);
}
});
realm.subscriptions.update { subscriptions ->
val mySubscription =
subscriptions.find("mySubscription")
subscriptions.remove(mySubscription)
}

Se você quiser remover todas as assinaturas de um tipo de objeto específico, passe uma classe para o método removeAll() :

realm.getSubscriptions().update(new SubscriptionSet.UpdateCallback() {
@Override
public void update(MutableSubscriptionSet subscriptions) {
subscriptions.removeAll(Frog.class);
}
});
realm.subscriptions.update { subscriptions ->
subscriptions.removeAll(
Frog::class.java
)
}

Para remover todas as assinatura do conjunto de assinaturas, use removeAll() sem argumentos:

Aviso

Se você remover todas as assinaturas e não adicionar uma nova, receberá um erro. Um domínio aberto com uma configuração de Flexible Sync precisa de pelo menos uma assinatura para sincronizar com o servidor.

realm.getSubscriptions().update(new SubscriptionSet.UpdateCallback() {
@Override
public void update(MutableSubscriptionSet subscriptions) {
subscriptions.removeAll();
}
});
realm.subscriptions.update { subscriptions -> subscriptions.removeAll() }

Adicionar um campo de query indexado à sua aplicação pode melhorar o desempenho de queries simples em dados fortemente particionados. Por exemplo, uma aplicação onde as queries mapeiam fortemente os dados para um dispositivo, armazém ou usuário, como user_id == $0, “641374b03725038381d2e1fb”, é uma boa candidata para um campo de query indexado. No entanto, um campo de query indexado tem requisitos específicos para uso em uma inscrição de query:

  • O campo de query indexado deve ser usado em todas as inscrições de query. Não pode estar faltando na query.

  • O campo de query indexado deve usar uma comparação == ou IN com uma constante pelo menos uma vez na query de inscrição. Por exemplo, user_id == $0, "641374b03725038381d2e1fb" ou store_id IN $0, {1,2,3}.

Opcionalmente, você pode incluir uma comparação AND, desde que o campo consultável indexado seja comparado diretamente com uma constante usando == ou IN pelo menos uma vez. Por exemplo, store_id IN {1,2,3} AND region=="Northeast" ou store_id == 1 AND (active_promotions < 5 OR num_employees < 10).

As consultas inválidas do Flexible Sync em um campo indexado que pode ser consultado incluem consultas em que:

  • O campo de consulta indexado não utiliza AND com o resto da consulta. Por exemplo store_id IN {1,2,3} OR region=="Northeast" é inválido porque usa OR em vez de AND. Da mesma forma, store_id == 1 AND active_promotions < 5 OR num_employees < 10 é inválido porque o AND só se aplica ao termo ao lado, não à consulta inteira.

  • O campo de consulta indexado não é utilizado em um operador de igualdade. Por exemplo store_id > 2 AND region=="Northeast" é inválido porque utiliza apenas o operador > com o campo de consulta indexado e não tem uma comparação de igualdade.

  • A query está totalmente ausente do campo de query indexado. Por exemplo, region=="Northeast ou truepredicate são inválidos porque não contêm o campo de query indexado.

A Flexible Sync tem algumas limitações ao usar operadores RQL. Quando você escreve a assinatura de consulta que determina quais dados sincronizar, o servidor não oferece suporte a esses operadores de consulta. No entanto, você ainda pode usar toda a gama de recursos de RQL para consultar o conjunto de dados sincronizado no aplicativo cliente.

Tipo de operador
Operadores não suportados
Operadores agregados
@avg, @count, @max, @min, @sum
Sufixos de query
DISTINCT, SORT , LIMIT

Queries que não diferenciam maiúsculas de minúsculas ([c]) não podem usar índices de forma eficaz. Sendo assim, queries que não diferenciam maiúsculas de minúsculas não são recomendadas, pois podem causar problemas de desempenho.

A sincronização flexível suporta apenas @count para campos de array.

A sincronização flexível oferece suporte às listas de query usando o operador IN .

Você pode consultar uma lista de constantes para ver se ela contém o valor de um campo de consulta:

// Query a constant list for a queryable field value
"priority IN { 1, 2, 3 }"

Se um campo de query tiver um valor de array, você poderá consultar para ver se ele contém um valor constante:

// Query an array-valued queryable field for a constant value
"'comedy' IN genres"

Aviso

Não é possível comparar duas listas entre si em uma consulta de sincronização flexível. Observe que esta é uma sintaxe válida do Realm Query Language fora das consultas do Flexible Sync.

// Invalid Flexible Sync query. Do not do this!
"{'comedy', 'horror', 'suspense'} IN genres"
// Another invalid Flexible Sync query. Do not do this!
"ANY {'comedy', 'horror', 'suspense'} != ANY genres"

A Flexible Sync não oferece suporte à consulta de propriedades em objetos ou links embarcados. Por exemplo, obj1.field == "foo".

O limite de tamanho para qualquer assinatura de query em seu conjunto de assinatura é de 256 kB. Exceder esse limite resulta em um erro de LimitsExceeded.

Voltar

Configurar e abrir um domínio sincronizado