Flexible Sync utiliza suscripciones y permisos para determinar qué datos sincronizar con tu aplicación.
Para usar Flexible Sync en una aplicación .NET:
Authenticate a user in your client project.
Abra el reino sincronizado con una configuración de sincronización flexible
You can add, update, and remove query subscriptions to determine which data syncs to the client device.
Nota
Requisitos previos de sincronización flexible
Habilitar Flexible Sync en su aplicación requiere un clúster Atlas no particionado que ejecute MongoDB 5.0 o superior
Nota
Realm .NET SDK Version Requirement
Además de los requisitos anteriores, debe utilizar Realm.NET versión 10.9.0 o superior para poder utilizar Flexible Sync en su aplicación cliente .NET.
Importante
Flexible Sync no es compatible con todos los operadores disponibles en Realm Query Language. Consulta Limitaciones de RQL en Flexible Sync para obtener detalles.
Manage Your Subscriptions
Al configurar la Sincronización Flexible en el backend, se especifican los campos que la aplicación cliente puede consultar. En la aplicación cliente, se utiliza la API de suscripciones para administrar un conjunto de suscripciones a consultas específicas en campos consultables.
Puede:
Obtenga una lista de todas las suscripciones
Add subscriptions
Comprobar el estado de la suscripción
Actualizar una suscripción con una nueva query
Remover suscripciones individuales o todas las suscripciones de un tipo
Cuando los datos coinciden con la suscripción y el usuario autenticado tiene los permisos adecuados, Atlas App Services sincroniza los datos del backend con la aplicación cliente.
You can specify a string name for your subscription. If you do not give your subscription a name, the name is set to null.
When you create a subscription, App Services looks for data matching a query on a specific object type. In your Flexible Sync subscriptions, you can have subscriptions on several different object types or several queries on the same object type.
No puede crear suscripciones para objetos asimétricos porque solo envían datos al backend de Servicios de aplicaciones.
Cambiado en la versión 11.6.1: Sincronización de dispositivos Atlas compatible con datos geoespaciales
In the Realm .NET version 11.6.1 and later, you can create subscriptions to geospatial queries. If you try to subscribe to a geospatial query with an older version of the SDK, you will receive a server error with a compensating write.
For more information, refer to Query Geospatial Data.
Add a Subscription
Debe tener al menos una suscripción para poder leer o escribir en el dominio. Debe crear una o más suscripciones iniciales al configurar la sincronización flexible, en lugar de agregarlas después de la inicialización.
Arranque el reino con suscripciones iniciales
You can bootstrap a realm with an initial subscription set when you open it with a FlexibleSyncConfiguration. Set the PopulateInitialSubscriptions parameter to a callback that is invoked when the realm is created. Add the queries you want to use to bootstrap the realm, as shown in the following example:
var config = new FlexibleSyncConfiguration(app.CurrentUser) { PopulateInitialSubscriptions = (realm) => { var myItems = realm.All<Item>().Where(n => n.OwnerId == myUserId); realm.Subscriptions.Add(myItems); } }; // The process will complete when all the user's items have been downloaded. var realm = await Realm.GetInstanceAsync(config);
Agregar una suscripción al conjunto de suscripciones existente
Debe inicializar un dominio con su SubscriptionSet. Luego, puede acceder al conjunto de suscripciones con la propiedad Realm.Subscriptions si necesita agregar consultas adicionales o actualizar suscripciones existentes.
Para agregar una suscripción a un conjunto de suscripciones existente, cree la consulta y luego llame a IQueryable.SubscribeAsync():
var query = realm.All<Team>().Where(t => t.Name == "MyTeam"); await query.SubscribeAsync(); // you can also pass a SubscriptionOptions object: var query2 = realm.All<Team>().Where(t => t.Name == "DevelopmentTeam"); await query2.SubscribeAsync( new SubscriptionOptions() { Name = "devTeamSubscription" });
La SubscribeAsync El método es una forma abreviada de usar SubscriptionSet.Update() para crear un bloque de actualización y luego llamar al método SubscriptionSet.Add() SubscriptionSeten.
Agrupación de múltiples suscripciones
While you can add a single query using SubscribeAsync, you can only batch multiple queries within a SubscriptionSet.Update block. Performing query updates is an expensive operation on the server. We strongly advise designing your application to minimize updates. You can do this by creating all subscriptions in a single update block the first time the user launches the app and batching any follow-up changes to the subscription set.
In the example below, we subscribe to three queries.
realm.Subscriptions.Update(() => { // Subscribe to all long running items, and name // the subscription "longRunningItems" var longRunningTasksQuery = realm.All<Item>() .Where(t => t.ProgressMinutes > 120); realm.Subscriptions.Add(longRunningTasksQuery, new SubscriptionOptions() { Name = "longRunningItems" }); // Subscribe to all of Ben's Items realm.Subscriptions.Add(realm.All<Item>() .Where(t => t.Owner == "Ben")); // Subscribe to all Teams, name the subscription // 'teamsSubscription', and throw an error if // this subscription name already exists. realm.Subscriptions.Add(realm.All<Team>(), new SubscriptionOptions() { Name = "teams", UpdateExisting = false }); });
Subscription Options
Note that both methods for adding a subscription provide an overload for passing in a SubscriptionOptions object. SubscriptionOptions contains configuration options for your subscription:
a
Namestring fieldun campo booleano
UpdateExisting.
If UpdateExisting is true, adding a subscription with an existing name will replace the existing query with the new query. This is the default behavior. However, if you set UpdateExisting to false, and try to replace a named subscription with a different query, Realm throws an exception.
Realm always ignores duplicate subscriptions, whether named or unnamed.
Importante
Subscribe to Linked Objects
You must add both an object and its linked object to the subscription set to see a linked object.
If your subscription results contain an object with a property that links to an object not contained in the results, the link appears to be nil. There is no way to distinguish whether that property's value is legitimately nil, or whether the object it links to exists but is out of view of the query subscription.
Update Subscriptions with a New Query
You can update a named subscription with a new query. To update a subscription's query, pass the new query and a subscription option with the name of the subscription that you want to update to the SubscriptionSet.Add() method. Like adding a new subscription, you must update a subscription within an update block by calling SubscriptionSet.Update() method.
Nota
No es posible actualizar una suscripción sin nombre. También puede eliminarla y crear una nueva con la consulta deseada.
In the following example, long running tasks are re-defined to be any tasks that have taken more than 130 minutes:
realm.Subscriptions.Update(() => { var updatedLongRunningTasksQuery = realm.All<Item>() .Where(t => t.Status == "completed" && t.ProgressMinutes > 130); realm.Subscriptions.Add(updatedLongRunningTasksQuery, new SubscriptionOptions() { Name = "longRunningTasks" }); });
Nota
Intentar actualizar una suscripción que tenga el campo SubscriptionOptions.UpdateExisting establecido en falso generará una excepción.
Eliminar suscripciones
To remove subscriptions from the subscription set, you can:
Eliminar una sola suscripción con la consulta indicada
Remove a single subscription with the given name
Remove a single subscription with the given subscription
Elimine todas las suscripciones de un tipo específico
Remove all subscriptions
When you remove a subscription query, the server also removes synced data from the client device.
Remove a Subscription by Query
Dentro de un bloque de actualización, puedes eliminar una suscripción específica mediante una consulta. Pasa la consulta al método Remove() SubscriptionSet en.
In the following example, the subscription to tasks with an owner named 'Ben' is removed from the subscriptions set.
realm.Subscriptions.Update(() => { // remove a subscription by it's query var query = realm.All<Item>().Where(i => i.Owner == "Ben"); realm.Subscriptions.Remove(query); });
Remove a Subscription by Name
Dentro de un bloque de actualización, puedes eliminar una suscripción específica por nombre. Pasa el nombre al método Remove() SubscriptionSet en.
realm.Subscriptions.Update(() => { // remove a named subscription var subscriptionName = "longRunningItemsSubscription"; realm.Subscriptions.Remove(subscriptionName); });
Remove All Subscriptions of a Class Name or Object Type
Dentro de un bloque de actualización, puede eliminar todas las suscripciones sin nombre de una clase pasando el nombre de la clase como una cadena al método RemoveAll("ClassName"). El RemoveAll() método tiene un segundo argumento opcional, un booleano,, removedName que también elimina las suscripciones con nombre si se establece true en. removedName se establece en falso por defecto.
Como alternativa, puede eliminar todas las suscripciones sin nombre de un tipo de objeto con RemoveAll(). El RemoveAll<Type>() método tiene un removedName argumento booleano opcional que también elimina las suscripciones con nombre si se establece true en. El removedName argumento se establece en falso por defecto.
realm.Subscriptions.Update(() => { // remove all subscriptions of the "Team" Class Name realm.Subscriptions.RemoveAll("Team"); // Alernatively, remove all subscriptions of the "Team" object type realm.Subscriptions.RemoveAll<Team>(); });
Remove All Subscriptions
Dentro de un bloque de actualización, puedes remover todas las suscripciones sin nombre del conjunto de suscripciones. Llama al método RemoveAll() en el SubscriptionSet. El método RemoveAll() tiene un argumento booleano opcional removedName, que también remueve las suscripciones con nombre si se establece en true. removedName está configurado en falso por defecto.
realm.Subscriptions.Update(() => { // remove all subscriptions, including named subscriptions realm.Subscriptions.RemoveAll(true); });
Espere a que los cambios de suscripción se sincronicen
Mutating the subscription set within an update block is only one part of changing a subscription. After the local subscription change, the realm synchronizes with the server to resolve any updates to the data due to the subscription change. This could mean adding or removing data from the synced realm.
Utiliza el método SubscriptionSet.WaitForSynchronizationAsync() para esperar a que el servidor reconozca este conjunto de suscripciones. Si el servidor rechaza el cambio, el SubscriptionSetState estará en un estado de error, y se lanzará una excepción.
Puede ocurrir una excepción si:
Se ha suscrito a una consulta no compatible. Suscribirse a una consulta no compatible pausará la sincronización. Para reanudarla, elimine la consulta no compatible.
Está realizando una acción no válida, como agregar un objeto que no coincide con una suscripción. Esto activa un reinicio del cliente: se borran los datos del dominio y se crea una nueva copia sin ninguna suscripción en el conjunto.
try { await realm.Subscriptions.WaitForSynchronizationAsync(); } catch (SubscriptionException ex) { // do something in response to the exception or log it Console.WriteLine($@"The subscription set's state is Error and synchronization is paused: {ex.Message}"); }
Estado de la suscripción
Utilice la propiedad SubscriptionSet.State para leer el estado actual del conjunto de suscripciones.
El estado Superseded es un SubscriptionSetState que puede ocurrir cuando otro hilo actualiza una suscripción en una instancia diferente del conjunto de suscripción. Si el estado se convierte en Superseded, debe obtener una nueva instancia del conjunto de suscripción antes de poder actualizarlo.
Nota
Estado de suscripción 'Completo'
The subscription set state "complete" does not mean "sync is done" or "all documents have been synced". "Complete" means the following two things have happened:
The subscription has become the active subscription set that is currently being synchronized with the server.
The documents that matched the subscription at the time the subscription was sent to the server are now on the local device. Note that this does not necessarily include all documents that currently match the subscription.
El SDK de Realm no proporciona una manera de verificar si todos los documentos que coinciden con una suscripción se han sincronizado con el dispositivo.
Requisitos y limitaciones de RQL de Flexible Sync
Requisitos de suscripción a campos consultables indexados
Adding an indexed queryable field to your App can improve performance for simple queries on data that is strongly partitioned. For example, an app where queries strongly map data to a device, store, or user, such as user_id == $0, “641374b03725038381d2e1fb”, is a good candidate for an indexed queryable field. However, an indexed queryable field has specific requirements for use in a query subscription:
The indexed queryable field must be used in every subscription query. It cannot be missing from the query.
The indexed queryable field must use an
==orINcomparison against a constant at least once in the subscription query. (El campo consultable debe utilizar una comparación o contra una constante al menos una vez en la consulta de suscripción.) For example,user_id == $0, "641374b03725038381d2e1fb"orstore_id IN $0, {1,2,3}. (Por ejemplo, o .)
Opcionalmente, puedes incluir una comparación de AND siempre que el campo indexado consultable se compare directamente con una constante usando == o IN al menos una vez. Por ejemplo, store_id IN {1,2,3} AND region=="Northeast" o store_id == 1 AND (active_promotions < 5 OR num_employees < 10).
Invalid Flexible Sync queries on an indexed queryable field include queries where:
The indexed queryable field does not use
ANDwith the rest of the query. For examplestore_id IN {1,2,3} OR region=="Northeast"is invalid because it usesORinstead ofAND. Similarly,store_id == 1 AND active_promotions < 5 OR num_employees < 10is invalid because theANDonly applies to the term next to it, not the entire query.El campo consultable indexado no se utiliza en un operador de igualdad. Por ejemplo,
store_id > 2 AND region=="Northeast"no es válido porque solo utiliza el operador>con el campo consultable indexado y no tiene una comparación de igualdad.The query is missing the indexed queryable field entirely. For example,
region=="Northeastortruepredicateare invalid because they do not contain the indexed queryable field.
Unsupported Query Operators in Flexible Sync
Flexible Sync has some limitations when using RQL operators. When you write the query subscription that determines which data to sync, the server does not support these query operators. However, you can still use the full range of RQL features to query the synced data set in the client application.
Tipo de operador | Operadores no compatibles |
|---|---|
Aggregate Operators |
|
Query Suffixes |
|
Las queries que no distinguen entre mayúsculas y minúsculas ([c]) no pueden usar índices de manera eficaz. Como resultado, no se recomiendan las queries que no distinguen entre mayúsculas y minúsculas, ya que podrían provocar problemas de rendimiento.
Flexible Sync only supports @count for array fields.
List Queries
Flexible Sync admite la consulta de listas usando el operador IN.
Puede consultar una lista de constantes para ver si contiene el valor de un campo consultable:
// Query a constant list for a queryable field value "priority IN { 1, 2, 3 }"
If a queryable field has an array value, you can query to see if it contains a constant value:
// Query an array-valued queryable field for a constant value "'comedy' IN genres"
Advertencia
You cannot compare two lists with each other in a Flexible Sync query. Note that this is valid Realm Query Language syntax outside of Flexible Sync queries.
// 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 incrustados o vinculados
Flexible Sync does not support querying on properties in Embedded Objects or links. For example, obj1.field == "foo".
Query Size Limit
The size limit for any given query subscription in your subscription set is 256 kB. Exceeding this limit results in a LimitsExceeded Error.