Docs Menu
Docs Home
/ /
Sincronizar datos

Administrar suscripciones de sincronización flexible - SDK .NET

Flexible Sync utiliza suscripciones y permisos para determinar qué datos sincronizar con su aplicación.

Para utilizar Flexible Sync en una aplicación .NET:

  • Configurar sincronización flexible en el backend.

  • Inicializar la aplicación

  • Autenticar un usuario en su proyecto cliente.

  • Abra el reino sincronizado con una configuración de sincronización flexible

  • Agrega suscripciones a la aplicación cliente

Puede agregar, actualizar y eliminar suscripciones de consultas para determinar qué datos se sincronizan con el dispositivo cliente.

Nota

Requisitos previos de sincronización flexible

Para habilitar la sincronización flexible en su aplicación, se requiere un clúster Atlas no fragmentado que ejecute MongoDB 5.0 o superior

Nota

Requisitos de versión del SDK de Realm .NET

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 admite todos los operadores disponibles en el lenguaje de consulta Realm. Consulte las limitaciones de Flexible Sync RQL para obtener más información.

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

  • Añadir suscripciones

  • Comprobar el estado de la suscripción

  • Actualizar una suscripción con una nueva query

  • Eliminar 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.

Puede especificar un nombre de cadena para su suscripción. Si no le asigna un nombre, este se establece como nulo.

Al crear una suscripción, App Services busca datos que coincidan con una consulta sobre un tipo de objeto específico. En tus suscripciones de Sincronización Flexible, puedes tener suscripciones sobre varios tipos de objeto diferentes o varias consultas sobre el mismo tipo de objeto.

No puedes crear suscripciones para objetos asimétricos porque solo envían datos al backend de App Services.

Cambiado en la versión 11.6.1: Sincronización de dispositivos Atlas compatible con datos geoespaciales

En la versión 11.6.1 y posteriores de Realm .NET, puede crear suscripciones a consultas geoespaciales. Si intenta suscribirse a una consulta geoespacial con una versión anterior del SDK, recibirá un error de servidor con una escritura compensatoria.

Para obtener más información, consulte Consulta de datos geoespaciales.

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.

Puede iniciar un dominio con un conjunto de suscripciones iniciales al abrirlo con FlexibleSyncConfiguration. Configure el parámetro PopulateInitialSubscriptions con una devolución de llamada que se invoque al crear el dominio. Agregue las consultas que desee usar para iniciar el dominio, como se muestra en el siguiente ejemplo:

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);

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" });

El 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.

Aunque puede agregar una sola consulta usando SubscribeAsync, solo puede procesar varias consultas en lotes dentro de un bloque SubscriptionSet.Update. Actualizar consultas es una operación costosa para el servidor. Le recomendamos encarecidamente que diseñe su aplicación para minimizar las actualizaciones. Puede lograrlo creando todas las suscripciones en un solo bloque de actualización la primera vez que el usuario inicia la aplicación y procesando por lotes los cambios posteriores en el conjunto de suscripciones.

En el siguiente ejemplo, nos suscribimos a tres consultas.

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 });
});

Tenga en cuenta que ambos métodos para agregar una suscripción proporcionan una sobrecarga para pasar un objeto SubscriptionOptions. SubscriptionOptions contiene opciones de configuración para su suscripción:

  • un campo de cadena Name

  • un campo booleano UpdateExisting.

Si UpdateExisting es verdadero, al agregar una suscripción con un nombre existente, se reemplazará la consulta existente por la nueva. Este es el comportamiento predeterminado. Sin embargo, si se establece UpdateExisting como falso e intenta reemplazar una suscripción con nombre por una consulta diferente, Realm genera una excepción.

Realm siempre ignora las suscripciones duplicadas, ya sean con nombre o sin nombre.

Importante

Suscribirse a objetos vinculados

Debe agregar un objeto y su objeto vinculado al conjunto de suscripciones para ver un objeto vinculado.

Si los resultados de su suscripción contienen un objeto con una propiedad que enlaza a un objeto no incluido en los resultados, el enlace aparecerá como nulo. No hay forma de distinguir si el valor de esa propiedad es legítimamente nulo o si el objeto al que enlaza existe, pero no está visible para la suscripción de consulta.

Puede actualizar una suscripción con nombre mediante una nueva consulta. Para actualizar la consulta de una suscripción, pase la nueva consulta y una opción de suscripción con el nombre de la suscripción que desea actualizar al método SubscriptionSet.Add(). Al igual que al añadir una nueva suscripción, debe actualizarla dentro de un bloque de actualización llamando al método SubscriptionSet.Update().

Nota

No es posible actualizar una suscripción sin nombre. También puede eliminarla y crear una nueva con la consulta deseada.

En el siguiente ejemplo, las tareas de ejecución prolongada se redefinen como cualquier tarea que haya tomado más de 130 minutos:

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.

Para eliminar suscripciones del conjunto de suscripciones, puede:

  • Eliminar una sola suscripción con la consulta indicada

  • Eliminar una sola suscripción con el nombre especificado

  • Eliminar una sola suscripción con la suscripción indicada

  • Eliminar todas las suscripciones de un tipo específico

  • Eliminar todas las suscripciones

Cuando elimina una consulta de suscripción, el servidor también elimina los datos sincronizados del dispositivo cliente.

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.

En el siguiente ejemplo, la suscripción a las tareas con un propietario llamado "Ben" se elimina del conjunto de suscripciones.

realm.Subscriptions.Update(() =>
{
// remove a subscription by it's query
var query = realm.All<Item>().Where(i => i.Owner == "Ben");
realm.Subscriptions.Remove(query);
});

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);
});

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>();
});

Dentro de un bloque de actualización, puede eliminar todas las suscripciones sin nombre del conjunto de suscripciones. Llame al método RemoveAll() SubscriptionSet en. El RemoveAll() método tiene un removedName argumento booleano opcional que también elimina las suscripciones con nombre si se establece true en. removedName se establece en falso por defecto.

realm.Subscriptions.Update(() =>
{
// remove all subscriptions, including named subscriptions
realm.Subscriptions.RemoveAll(true);
});

Modificar el conjunto de suscripciones dentro de un bloque de actualización es solo una parte del proceso de cambio de una suscripción. Tras el cambio de suscripción local, el dominio se sincroniza con el servidor para resolver cualquier actualización de datos debida al cambio de suscripción. Esto podría implicar añadir o eliminar datos del dominio sincronizado.

Utilice el método SubscriptionSet.WaitForSynchronizationAsync() para esperar a que el servidor confirme este conjunto de suscripciones. Si el servidor rechaza el cambio, SubscriptionSetState mostrará un estado de error y se generará 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}");
}

Utilice la propiedad SubscriptionSet.State para leer el estado actual del conjunto de suscripciones.

El Superseded estado es un SubscriptionSetState que puede ocurrir cuando otro subproceso actualiza una suscripción en una instancia diferente del conjunto de suscripciones. Si el estado cambia Superseded a, debe obtener una nueva instancia del conjunto de suscripciones para poder actualizarlo.

Nota

Estado de suscripción "Completado"

El estado "Completado" del conjunto de suscripción no significa que la sincronización esté completa ni que todos los documentos se hayan sincronizado. "Completado" significa que han ocurrido las dos cosas siguientes:

  • La suscripción se ha convertido en el conjunto de suscripciones activas que actualmente se está sincronizando con el servidor.

  • Los documentos que coincidían con la suscripción en el momento de enviarla al servidor se encuentran ahora en el dispositivo local. Tenga en cuenta que esto no incluye necesariamente todos los documentos que coinciden actualmente con la suscripción.

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.

Añadir un campo consultable indexado a tu aplicación puede mejorar el rendimiento de consultas simples sobre datos con particiones estrictas. Por ejemplo, una aplicación donde las consultas asignan datos de forma estricta a un dispositivo, tienda o usuario,user_id == $0, “641374b03725038381d2e1fb” como, es una buena candidata para un campo consultable indexado. Sin embargo, un campo consultable indexado tiene requisitos específicos para su uso en una suscripción de consultas:

  • El campo consultable indexado debe usarse en todas las consultas de suscripción. No puede faltar en la consulta.

  • El campo consultable indexado debe usar una comparación == o IN con una constante al menos una vez en la consulta de suscripción. Por ejemplo, user_id == $0, "641374b03725038381d2e1fb" o store_id IN $0, {1,2,3}.

Opcionalmente, puede incluir una comparación AND siempre que el campo consultable indexado 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).

Las consultas de sincronización flexibleno válidas en un campo consultable indexado incluyen consultas donde:

  • El campo consultable indexado no usa AND con el resto de la consulta. Por ejemplo, store_id IN {1,2,3} OR region=="Northeast" no es válido porque usa OR en lugar de AND. De igual manera, store_id == 1 AND active_promotions < 5 OR num_employees < 10 no es válido porque AND solo se aplica al término contiguo, no a toda la consulta.

  • 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.

  • A la consulta le falta por completo el campo consultable indexado. Por ejemplo, region=="Northeast o truepredicate no son válidos porque no contienen dicho campo.

La sincronización flexible presenta algunas limitaciones al usar operadores RQL. Al escribir la suscripción de consulta que determina qué datos sincronizar, el servidor no admite estos operadores. Sin embargo, aún puede usar todas las funciones de RQL para consultar el conjunto de datos sincronizados en la aplicación cliente.

Tipo de operador
Operadores no compatibles

Operadores agregados

@avg, @count, @max, @min, @sum

Sufijos de consulta

DISTINCT, SORT, LIMIT

Las consultas que no distinguen entre mayúsculas y minúsculas ([c]) no pueden usar índices eficazmente. Por lo tanto, no se recomiendan, ya que podrían causar problemas de rendimiento.

Flexible Sync solo admite @count para campos de matriz.

Flexible Sync admite la consulta de listas mediante 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 }"

Si un campo consultable tiene un valor de matriz, puedes consultar para ver si contiene un valor constante:

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

Advertencia

No se pueden comparar dos listas en una consulta de sincronización flexible. Tenga en cuenta que esta sintaxis del lenguaje de consulta de dominio es válida fuera de las consultas de sincronización flexible.

// 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"

La sincronización flexible no admite consultas sobre propiedades en objetos incrustados ni enlaces. Por ejemplo, obj1.field == "foo".

El límite de tamaño para cualquier suscripción de consulta en su conjunto de suscripciones es de kB. Superar este límite genera 256 un error "LimitsExceeded".

Volver

Escribir en un dominio sincronizado - SDK .NET