Cuando usas Atlas Device Sync en tu aplicación Realm, puedes encontrar una nueva clase de errores: errores de sincronización
El SDK de Realm para Node.js puede ayudarte a detectar y gestionar errores de sincronización. Por ejemplo, puedes crear tu propio gestor de errores de sincronización para responder a errores específicos. También puedes definir cómo tu aplicación cliente gestiona los restablecimientos de clientes.
Controlador de errores de sincronización
Debe configurar un controlador de errores para las aplicaciones que usan Atlas Device Sync. Un controlador de errores genérico detectará y responderá a las llamadas a la API relacionadas con la sincronización fallida en su backend de Atlas.
Agregar un controlador de errores de sincronización genérico
Establezca un controlador de errores registrando una función de devolución de llamada de error como parte de SyncConfiguration.
const handleSyncError = async (session, error) => { // ... handle the error using session and error information. console.log(session); console.log(error); }; const config = { schema: [DogSchema], sync: { flexible: true, user: app.currentUser, onError: handleSyncError, }, }; // Open realm with config that contains error handler. const realm = await Realm.open(config);
const handleSyncError = ( session: Realm.App.Sync.Session, error: Realm.SyncError | Realm.ClientResetError ) => { // ... handle the error using session and error information. console.log(session); console.log(error); }; const config: Realm.Configuration = { schema: [DogSchema], sync: { flexible: true, user: app.currentUser!, onError: handleSyncError, }, }; // Open realm with config that contains error handler. const realm = await Realm.open(config);
Tip
Para obtener una lista de errores comunes de sincronización de dispositivos y cómo solucionarlos, consulte Errores de sincronización en la documentación de sincronización de dispositivos de App Services.
Manejar errores de escritura compensatorios
Quizás quieras que tu controlador de errores de sincronización aborde específicamente los errores de escritura compensatorios de forma que sean coherentes con tu aplicación. La clase CompensatingWriteError puede ayudarte a identificar y reaccionar ante los errores de escritura compensatorios en tu controlador de errores personalizado.
const errorCallback = (session, error) => { // Check if error type matches CompensatingWriteError. if (error instanceof CompensatingWriteError) { // Handle the compensating write error as needed. console.debug({ name: error.name, code: error.code, message: error.message, atlasLogUrl: error.logUrl, }); const compensatingWrites = error.writes.sort((a, b) => a.primaryKey.toString().localeCompare(b.primaryKey.toString()) ); console.debug(compensatingWrites); } }; const app = new Realm.App({ id: APP_ID, }); const credentials = Credentials.anonymous(); await app.logIn(credentials); const realm = await Realm.open({ schema: [Person, Turtle], sync: { flexible: true, user: app.currentUser, onError: errorCallback, }, });
const errorCallback: ErrorCallback = (session, error) => { // Check if error type matches CompensatingWriteError. if (error instanceof CompensatingWriteError) { // Handle the compensating write error as needed. console.debug({ name: error.name, code: error.code, message: error.message, atlasLogUrl: error.logUrl, }); const compensatingWrites = error.writes.sort((a, b) => (a.primaryKey as BSON.ObjectId) .toString() .localeCompare((b.primaryKey as BSON.ObjectId).toString()) ); console.debug(compensatingWrites); } }; const app = new Realm.App({ id: APP_ID, }); const credentials = Credentials.anonymous(); await app.logIn(credentials); const realm = await Realm.open({ schema: [Person, Turtle], sync: { flexible: true, user: app.currentUser!, onError: errorCallback, }, });
Manejar errores de restablecimiento del cliente
Un error de restablecimiento de cliente es un escenario en el que un dominio de cliente no puede sincronizar datos con el backend de Atlas App Services. Los clientes en este estado pueden seguir ejecutándose y guardando datos localmente, pero no pueden enviar ni recibir conjuntos de cambios de sincronización hasta que realicen un restablecimiento de cliente.
Para obtener más información sobre las causas y los modos de manejo de los restablecimientos de clientes, consulte Restablecimientos de clientes de sincronización de dispositivos en la documentación de Servicios de aplicaciones.
Modos de reinicio del cliente
Puede especificar qué modo de restablecimiento de cliente debe usar su aplicación para restaurar el reino a un estado sincronizable:
Modo de recuperación de cambios no sincronizados: Al seleccionar este modo, el cliente intenta recuperar los cambios no sincronizados. Elija este modo si no desea descartar los cambios no sincronizados.
Modo de recuperación o descarte de cambios no sincronizados: El cliente primero intenta recuperar los cambios que aún no se han sincronizado. Si no puede recuperar los datos no sincronizados, no descarta los cambios no sincronizados, pero continúa reiniciando el cliente automáticamente. Seleccione este modo si desea habilitar la recuperación automática del cliente para descartar los cambios no sincronizados.
Modo descartar cambios no sincronizados: restaura el reino a un estado sincronizable descartando los cambios realizados desde la última sincronización.
Modo de recuperación manual: Descarga una nueva copia del dominio y mueve el dominio no sincronizable a una copia de seguridad. Migra los datos no sincronizados de la copia de seguridad del dominio a la nueva copia sincronizable.
Reinicio automático vs. manual del cliente
Los SDK de Realm proporcionan modos de restablecimiento de cliente que manejan automáticamente la mayoría de los errores de restablecimiento de cliente.
Los modos de restablecimiento automático del cliente restauran el archivo de dominio local a un estado sincronizable sin cerrar el dominio ni perder notificaciones. Los siguientes modos de restablecimiento del cliente admiten restablecimientos automáticos:
Recuperar el modo de cambios no sincronizados
Recuperar o descartar el modo de cambios no sincronizados
Descartar el modo de cambios no sincronizados
Las diferencias entre estos modos se basan en cómo gestionan los cambios en el dispositivo que aún no se han sincronizado con el backend. Solo el modo de recuperación manual no realiza un restablecimiento automático del cliente.
Seleccione el modo de recuperación de cambios no sincronizados para gestionar automáticamente la mayoría de los casos de restablecimiento del cliente. Este modo intenta recuperar los cambios no sincronizados al restablecer el cliente.
Si su aplicación requiere una lógica de reinicio de cliente específica que no se puede manejar automáticamente, es posible que desee o necesite agregar un controlador de reinicio de cliente manual al modo de reinicio de cliente automático.
Restablecimiento del cliente con recuperación
Nuevo en la versión 10.23.0.
La Recuperación de Cliente es una función que se habilita de forma predeterminada al configurar la Sincronización de Dispositivos. Cuando está habilitada, Realm gestiona automáticamente el proceso de restablecimiento del cliente en la mayoría de los casos. El cliente puede recuperar cambios no sincronizados cuando no hay cambios de esquema o cambios de esquema permanentes.
Para utilizar la recuperación de cliente, configure su reino con uno de los siguientes modos de restablecimiento de cliente:
Recuperar el modo de cambios no sincronizados
Recuperar o descartar cambios no sincronizados
Cuando la Recuperación de Cliente está habilitada, estas reglas determinan cómo se integran los objetos, incluyendo la resolución de conflictos cuando tanto el backend como el cliente realizan cambios en el mismo objeto:
Se sincronizan los objetos creados localmente que no se sincronizaron antes del reinicio del cliente.
Si se elimina un objeto en el servidor, pero se modifica en el cliente en recuperación, la eliminación tiene prioridad y el cliente descarta la actualización.
Si se elimina un objeto en el cliente en recuperación, pero no en el servidor, el cliente aplica la instrucción de eliminación del servidor.
En el caso de actualizaciones conflictivas en el mismo campo, se aplica la actualización del cliente.
Para obtener más información sobre cómo configurar la Recuperación de cliente, consulte Recuperación de cliente en la documentación de Servicios de aplicaciones.
La recuperación del cliente no puede realizarse correctamente si la aplicación realiza cambios importantes en el esquema. Un cambio importante es un cambio que se puede realizar en el esquema del servidor y que requiere una acción adicional para su gestión. En este caso, el restablecimiento del cliente recurre a un restablecimiento manual por error.
Para obtener información sobre cambios de esquema disruptivos y no disruptivos, consulte Referencia rápida sobre cambios disruptivos y no disruptivos en la documentación de App Services.
Modo Recuperar cambios no sincronizados
Al seleccionar el modo de recuperación de cambios no sincronizados, el cliente intenta recuperarlos con la Recuperación de Cliente. Elija este modo si no desea descartar los cambios no sincronizados.
Para manejar los restablecimientos del cliente con el modo de recuperación de cambios no sincronizados, pase un ClientResetConfig al clientReset Campo de su SyncConfiguration. Incluya estas propiedades ClientResetConfiguration en:
mode:Establecer en"recoverUnsyncedChanges".onBefore: Opcional. Función de devolución de llamada que se invoca antes de que el SDK ejecute este modo cuando recibe un error de restablecimiento del cliente desde el backend. Proporciona una copia del dominio.onAfter: Opcional. Función de devolución de llamada que se invoca después de que el SDK ejecute correctamente este modo. Proporciona instancias del dominio antes y después del reinicio del cliente.onFallback: Opcional. Función de devolución de llamada que el SDK invoca solo si falla la recuperación automática. Para más información, consulte la sección "Restablecimiento manual del cliente".
El siguiente ejemplo implementa el modo de recuperar cambios no sincronizados:
const config = { schema: [DogSchema], sync: { user: app.currentUser, flexible: true, clientReset: { mode: "recoverUnsyncedChanges", onBefore: (realm) => { // This block could be used for custom recovery, reporting, debugging etc. }, onAfter: (beforeRealm, afterRealm) => { // This block could be used for custom recovery, reporting, debugging etc. }, onFallback: (session, path) => { // See below "Manual Client Reset Fallback" section for example }, }, }, };
Modo Recuperar o Descartar Cambios No Sincronizados
En el modo de recuperación o descarte de cambios no sincronizados, el cliente primero intenta recuperar los cambios que aún no se han sincronizado. Si no puede recuperar los datos no sincronizados, no descarta los cambios no sincronizados, pero continúa reiniciando el cliente automáticamente. Seleccione este modo si desea habilitar la recuperación automática del cliente para descartar los cambios no sincronizados.
No utilice el modo de recuperación o descartar cambios no sincronizados si su aplicación no puede perder datos locales que aún no se han sincronizado con el backend.
Para gestionar los restablecimientos de clientes con el modo de recuperación o descarte de cambios no sincronizados, pase un ClientResetConfig al clientReset campo de su SyncConfiguration. Incluya estas propiedades ClientResetConfiguration en:
mode:Establecer en"recoverOrDiscardUnsyncedChanges".onBefore: Opcional. Función de devolución de llamada que se invoca antes de que el SDK ejecute este modo cuando recibe un error de restablecimiento del cliente desde el backend. Proporciona una copia del dominio.onAfter: Opcional. Función de devolución de llamada que se invoca después de que el SDK ejecute correctamente este modo. Proporciona instancias del dominio antes y después del reinicio del cliente.onFallback: Opcional. Función de retorno que el SDK invoca solo si tanto la recuperación automática como el descarte de cambios fallan. Para obtener más información, consulte la sección Manual restablecimiento del cliente Fallback.
El siguiente ejemplo implementa el modo de recuperar cambios no sincronizados:
const config = { schema: [DogSchema], sync: { user: app.currentUser, flexible: true, clientReset: { mode: "recoverOrDiscardUnsyncedChanges", onBefore: (realm) => { // This block could be used for custom recovery, reporting, debugging etc. }, onAfter: (beforeRealm, afterRealm) => { // This block could be used for custom recovery, reporting, debugging etc. }, onFallback: (session, path) => { // See below "Manual Client Reset Fallback" section for example }, }, }, };
Restablecimiento manual del cliente
Si el restablecimiento del cliente con recuperación no se puede completar automáticamente, como cuando hay cambios de esquema importantes, el proceso de restablecimiento se redirige a un gestor de errores manual. Esto puede ocurrir en cualquiera de los modos de restablecimiento del cliente con recuperación: recuperar cambios no sincronizados, y recuperar o descartar cambios no sincronizados.
Debes proporcionar una implementación manual de restablecimiento del cliente en la función de retorno SyncConfiguration.onFallback(). onFallback() toma dos argumentos:
session:Objeto desesión que representa el estado de la sesión de sincronización del dispositivo.path:Cadena con la ruta al archivo del reino actual.
El siguiente ejemplo demuestra cómo puedes manejar manualmente este caso de error descartando todos los cambios no sincronizados:
// Must define `realm` at higher scope than `config` so it's accessible // from the `onFallback` callback let realm; const config = { schema: [DogSchema], sync: { user: app.currentUser, flexible: true, clientReset: { mode: "recoverOrDiscardUnsyncedChanges", // or "recoverUnsyncedChanges" // can also include `onBefore` and `onAfter` callbacks onFallback: (_session, path) => { try { // Prompt user to perform a client reset immediately. If they don't, // they won't receive any data from the server until they restart the app // and all changes they make will be discarded when the app restarts. const didUserConfirmReset = showUserAConfirmationDialog(); if (didUserConfirmReset) { // Close and delete old realm from device realm.close(); Realm.deleteFile(path); // Perform client reset Realm.App.Sync.initiateClientReset(app, path); // Navigate the user back to the main page or reopen the // the Realm and reinitialize the current page } } catch (err) { // Reset failed. Notify user that they'll need to // update the app } }, }, }, }; realm = await Realm.open(config);
Modo Descartar cambios no sincronizados
Nuevo en la versión 10.11.0.
Cambiado en la versión 10.23.0: El modo pasó a llamarse de "discardLocal" a "discardUnsyncedChanges". Actualmente, ambos funcionan, pero, en una versión futura, se eliminará "discardLocal". Las funciones de retorno "clientResetBefore" y "clientResetAfter" se cambiaron a "onBefore" y "onAfter", respectivamente.
El modo Descartar cambios no sincronizados borra permanentemente todos los cambios locales no sincronizados realizados desde la última sincronización exitosa. Puedes usar esta moda cuando tu aplicación requiera una lógica de recuperación de cliente que no sea coherente con Recuperación automática del cliente, o cuando no quieras recuperar datos no sincronizados.
No utilice el modo de descartar cambios no sincronizados si su aplicación no puede perder datos locales que aún no se han sincronizado con el backend.
Para gestionar los restablecimientos de clientes con el modo de descartar cambios no sincronizados, pase un ClientResetConfig al clientReset campo de su SyncConfiguration. Incluya estas propiedades en ClientResetConfiguration el:
mode:Establecer en"discardUnsyncedChanges".onBefore: Opcional. Función de devolución de llamada que se invoca antes de que el SDK ejecute este modo cuando recibe un error de restablecimiento del cliente desde el backend. Proporciona una copia del dominio.onAfter: Opcional. Función de devolución de llamada que se invoca después de que el SDK ejecute correctamente este modo. Proporciona instancias del dominio antes y después del reinicio del cliente.
El siguiente ejemplo implementa el modo de descartar cambios no sincronizados:
const config = { schema: [DogSchema], sync: { user: app.currentUser, flexible: true, clientReset: { mode: "discardUnsyncedChanges", onBefore: (realm) => { console.log("Beginning client reset for ", realm.path); }, onAfter: (beforeRealm, afterRealm) => { console.log("Finished client reset for", beforeRealm.path); console.log("New realm path", afterRealm.path); }, }, }, };
Descartar cambios no sincronizados después de interrumpir los cambios de esquema
Si su aplicación experimenta un cambio de esquema importante, el modo de descartar cambios no sincronizados no puede gestionar automáticamente el restablecimiento del cliente resultante. En su lugar, debe proporcionar una implementación de restablecimiento manual del cliente en la devolución de llamada SyncConfiguration error(). El siguiente ejemplo muestra cómo gestionar manualmente este error descartando todos los cambios no sincronizados:
// Once you have opened your Realm, you will have to keep a reference to it. // In the error handler, this reference is called `realm` async function handleSyncError(session, syncError) { if (syncError.name == "ClientReset") { console.log(syncError); try { console.log("error type is ClientReset...."); const path = realm.path; // realm.path will not be accessible after realm.close() realm.close(); Realm.App.Sync.initiateClientReset(app, path); // Download Realm from the server. // Ensure that the backend state is fully downloaded before proceeding, // which is the default behavior. realm = await Realm.open(config); realm.close(); } catch (err) { console.error(err); } } else { // ...handle other error types } } const config = { schema: [DogSchema], sync: { user: app.currentUser, flexible: true, clientReset: { mode: "discardUnsyncedChanges", onBefore: (realm) => { // NOT used with destructive schema changes console.log("Beginning client reset for ", realm.path); }, onAfter: (beforeRealm, afterRealm) => { // Destructive schema changes do not hit this function. // Instead, they go through the error handler. console.log("Finished client reset for", beforeRealm.path); console.log("New realm path", afterRealm.path); }, }, onError: handleSyncError, // invoked with destructive schema changes }, };
Nota
Descartar con recuperación
Si desea intentar recuperar cambios no sincronizados, pero descartar cualquier cambio que no se pueda recuperar, consulte la sección del modo recuperar o descartar cambios no sincronizados.
Modo manual
Cambiado en la versión 10.23.0: se añadió la función de retorno onManual
En el modo manual, defines tu propio controlador de restablecimiento de cliente. Te recomendamos usar un controlador de restablecimiento de cliente manual si la lógica de recuperación automática no funciona en tu aplicación y no puedes descartar los datos locales no sincronizados.
Para gestionar los restablecimientos de clientes en modo manual, pase un ClientResetConfig al clientReset campo de su SyncConfiguration. Incluya estas propiedades en ClientResetConfiguration el:
mode:Establecer en"manual".onManual: Opcional. Función de devolución de llamada que se invoca al reiniciar el cliente. Proporciona información sobre la sesión de sincronización y la ruta al dominio actual. Si no se configura el controlador de erroresonManual, el error de reinicio del cliente se revierte al controlador de errores de sincronización general.
const config = { schema: [DogSchema], sync: { user: app.currentUser, flexible: true, clientReset: { mode: "manual", onManual: (session, path) => { // handle manual client reset here }, }, }, };
Recuperación manual de datos
Recuperar datos de un restablecimiento manual de cliente requiere una gran cantidad de código, concesiones de esquema y una lógica de resolución de conflictos personalizada. Si necesita implementar su propia lógica de restablecimiento de cliente, consulte la Guía avanzada para la recuperación de datos tras un restablecimiento manual de cliente.
Manejo del restablecimiento del cliente de prueba
Puede probar manualmente el manejo de restablecimiento del cliente de su aplicación finalizando y volviendo a habilitar la sincronización del dispositivo.
Al finalizar y reactivar Sync, los clientes que se conectaron previamente con Sync no podrán hacerlo hasta que restablezcan el cliente. Al finalizar Sync, se eliminan los metadatos del servidor que permiten la sincronización. El cliente debe descargar una nueva copia del dominio desde el servidor. El servidor envía un error de restablecimiento de cliente a estos clientes. Por lo tanto, al finalizar Sync, se activa la condición de restablecimiento de cliente.
Para probar el manejo del restablecimiento del cliente:
Escriba datos desde una aplicación cliente y espere a que se sincronicen.
Termina y vuelve a habilitar Device Sync.
Ejecute la aplicación cliente nuevamente. La aplicación debería mostrar un error de restablecimiento de cliente al intentar conectarse al servidor.
Advertencia
Mientras itera sobre la gestión del restablecimiento de clientes en su aplicación cliente, es posible que tenga que finalizar y volver a habilitar la sincronización repetidamente. Esto impide que todos los clientes existentes puedan sincronizar hasta después de completar un restablecimiento. Para evitar esto en producción, pruebe la gestión del restablecimiento de clientes en un entorno de desarrollo.