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
Visão geral
Flexible Sync usa assinaturas e permissões para determinar quais dados sincronizar com seu aplicativo.
Para usar o Flexible Sync no SDK:
Autenticar um usuário em seu projeto de cliente.
Abra o Realm sincronizado com uma configuração Flexible Sync
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.
Inscrever-se para campos de query
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() { 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() { 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() { 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() { 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.
Adicionar uma assinatura
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() { 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() { 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..
Aguarde as alterações na assinatura para sincronizar
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() { 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() { 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.
SubscriptionSet.State Enum
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.
Substituído
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.
Atualizar assinaturas com uma nova query
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() { 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() { 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" ) ) ) }
Remover subscrições
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.
Remover uma única assinatura
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() { 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) }
Remover todas as assinaturas de um tipo de objeto
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() { public void update(MutableSubscriptionSet subscriptions) { subscriptions.removeAll(Frog.class); } });
realm.subscriptions.update { subscriptions -> subscriptions.removeAll( Frog::class.java ) }
Remover todas as assinaturas
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() { public void update(MutableSubscriptionSet subscriptions) { subscriptions.removeAll(); } });
realm.subscriptions.update { subscriptions -> subscriptions.removeAll() }
Requisitos e limitações do Flexible Sync RQL
Requisitos de inscrição de campos de query indexados
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
==
ouIN
com uma constante pelo menos uma vez na query de inscrição. Por exemplo,user_id == $0, "641374b03725038381d2e1fb"
oustore_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 exemplostore_id IN {1,2,3} OR region=="Northeast"
é inválido porque usaOR
em vez deAND
. Da mesma forma,store_id == 1 AND active_promotions < 5 OR num_employees < 10
é inválido porque oAND
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
outruepredicate
são inválidos porque não contêm o campo de query indexado.
Operadores de consulta não suportados na sincronização flexível
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.
Listar queries
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"
Objetos incorporados ou vinculados
A Flexible Sync não oferece suporte à consulta de propriedades em objetos ou links embarcados. Por exemplo, obj1.field == "foo"
.
Limite de tamanho da query
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.