Al desarrollar una aplicación que utiliza Sincronización de dispositivos: debe configurar un controlador de errores. Este controlador detectará y responderá a cualquier llamada a la API relacionada con la sincronización fallida.
Tip
For a list of common Device Sync errors and how to handle them, refer to Sync Errors in the App Services Device Sync documentation.
Manejar errores de sincronización
Establezca un controlador de errores mediante la propiedad SyncConfiguration.errorHandler al crear un dominio sincronizado. Cuando se produce un error, el SDK de Kotlin llama al controlador de errores con el objeto de error y la sesión de sincronización donde se produjo el error.
If you do not specify an error handler, the default behavior is to print the sync error to the console.
val syncErrorHandler = SyncSession.ErrorHandler { session, error -> Log.e("Error message" + error.message.toString()) } runBlocking { val user = app.login(credentials) val config = SyncConfiguration.Builder(user, setOf(Toad::class)) .initialSubscriptions { realm -> add(realm.query<Toad>(), "subscription name") } .errorHandler(syncErrorHandler) // Specify a sync error handler .build() // Proceed to open a realm... }
For information about setting a client log level or customizing the logger, refer to Set the Client Log Level - Kotlin SDK.
Excepciones de sincronizar
Una SyncException es una subclase de AppException. SyncException ocurre cuando falla la sincronización del dispositivo.
For more information on app exceptions, refer to Handle App Errors.
Unrecoverable Sync Errors
Una excepción de sincronización irrecuperable (UnrecoverableSyncException) ocurre cuando la sincronización del dispositivo falla gravemente. Esto suele indicar un error en el cliente o la aplicación conectada.
Cuando se produce un error de sincronización irrecuperable, debes informar del problema al usuario final. Infórmale que la sincronización del dispositivo no funcionará hasta que se resuelva el problema. Lo mejor es enviarte una alerta para que puedas revisar los registros de la aplicación y solucionar el problema lo antes posible.
Wrong Sync Type Errors
Una WrongSyncTypeException ocurre cuando el cliente y la aplicación usan protocolos de sincronización diferentes.
El SDK admite dos tipos de sincronización: sincronizaciónflexible y sincronización basada en particiones. Cuando un cliente se conecta a una aplicación con un tipo de sincronización que no coincide con el de la aplicación, se produce un error de tipo de sincronización incorrecto.
To recover from a wrong sync type error, update the client to use a sync type that matches the backend. This will most likely require the user to update to a new version of your app containing the fix.
Errores de Flexible Sync Query
A BadFlexibleSyncQueryException occurs when you try to subscribe to a flexible sync query that is not supported by the App backend. This can happen when you:
query un campo que no se especifique como un campo consultable en tu configuración flexible de sincronizar
crear una query de sincronización flexible utilizando operadores no compatibles con la sincronización flexible
Para resolver un error de una mala query de sincronizar flexible, actualiza tu cliente para utilizar una query de sincronizar compatible con la configuración de tu aplicación. Lo más probable es que esto requiera que el usuario actualice tu aplicación para incluir la corrección.
Manejar errores de restablecimiento del cliente
Al usar Device Sync, un restablecimiento del cliente es una tarea de recuperación de errores que la aplicación cliente debe realizar cuando el servidor de Device Sync ya no puede sincronizar con el realm del cliente. En este caso, el cliente debe restablecer su realm a un estado que coincida con el servidor para restaurar la capacidad de sincronización.
When this occurs, the unsyncable realm on the client may contain data that has not yet synced to the server. Realm SDKs can attempt to recover or discard that data during the client reset process.
Para obtener más información sobre qué puede causar un restablecimiento del cliente, consulta Restablecimientos de clientes en la documentación de App Services.
Client Reset Strategies
The Realm SDKs provide client reset strategies that automatically handle most client reset errors as well as a manual recovery strategy.
Automatic vs. Manual Client Resets
Automatic reset strategies restore your local realm file to a syncable state without closing the realm or missing notifications. The differences are based on how they handle changes on the device that have not yet synced to the backend. The following strategies implement the AutomaticClientResetStrategy interface and support automatic client resets:
Recuperar o descartar los cambios que no estén sincronizados (por defecto): el gestor de restablecimiento del cliente primero intenta recuperar los cambios no sincronizados. Si la recuperación falla, este gestor recurre a la estrategia de descartar los cambios no sincronizados, lo que borra permanentemente todos los cambios locales no sincronizados. Si la estrategia de descartar los cambios no sincronizados falla, el gestor recurre a la recuperación manual.
Recuperar cambios no sincronizados: El controlador de restablecimiento del cliente primero intenta recuperar los cambios no sincronizados. Si la recuperación falla, este controlador recurre a la recuperación manual.
Descartar cambios no sincronizados: Esta estrategia elimina permanentemente todos los cambios locales no sincronizados realizados desde la última sincronización exitosa. Si el descarte falla, este controlador recurre a la recuperación manual. Se recomienda este modo para gestionar cualquier recuperación manual de datos.
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 mediante la interfaz ManuallyRecoverUnsyncedChangesStrategy:
Recuperar manualmente los cambios no sincronizados: Le permite implementar su propia estrategia de recuperación manual. La recuperación manual es la única estrategia que no realiza un restablecimiento automático del cliente. Este modo le permite realizar una copia de seguridad únicamente de su dominio. Recomendamos usar la estrategia "descartar cambios no sincronizados" para gestionar la recuperación manual, si es posible.
Client Reset with Recovery
Client Recovery is a feature that is enabled by default when you configure Device Sync.
Para usar Client Recovery, configure su reino con la estrategia de recuperar cambios no sincronizados o recuperar o descartar cambios no sincronizados, y Realm administrará automáticamente el proceso de restablecimiento del cliente en la mayoría de los casos:
The client can recover unsynced changes when there are no schema changes or there are non-breaking schema changes.
La recuperación automática del cliente no puede ocurrir cuando tu aplicación realiza cambios de esquema importantes. Un cambio disruptivo es un cambio que se puede realizar en el esquema del servidor que requiere una acción adicional para manejarlo. En este caso, la recuperación del cliente recurre a un restablecimiento manual del cliente por fallo de 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.
Client Recovery Rules
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:
Objects created locally that were not synced before client reset are synced.
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.
If an object is deleted on the recovering client, but not the server, then the client applies the server's delete instruction.
En el caso de actualizaciones conflictivas en el mismo campo, se aplica la actualización del cliente.
Especifica una estrategia de reinicio del cliente
Puede especificar una estrategia de restablecimiento de cliente en su propiedad SyncConfiguration.syncClientResetStrategy al configurar un reino sincronizado.
// Specify your client reset strategy in the SyncConfiguration // If you don't specify, defaults to RecoverOrDiscardUnsyncedChangesStrategy val config = SyncConfiguration.Builder(user, setOf(Toad::class)) .initialSubscriptions { realm -> add(realm.query<Toad>(), "subscription name") } .syncClientResetStrategy(clientResetStrategy) // Set your client reset strategy .build()
Las siguientes secciones describen cómo utilizar estas estrategias de restablecimiento del cliente.
Recover or Discard Unsynced Changes
The recover or discard unsynced changes strategy attempts to recover all unsynced local changes automatically during a client reset. To recover unsynced changes, Client Recovery must be enabled in your App Services App (it is enabled by default).
If the automatic recovery process fails, it falls back to a discard unsynced changes strategy. If that process process fails, it falls back again to a manual reset strategy.
This strategy provides the most robust recovery process. It is the default client reset behavior if you do not specify a client reset strategy.
Importante
Do not use the recover or discard unsynced changes strategy if your application cannot lose any local data that has not yet synced to the backend.
To customize usage of recover or discard unsynced changes strategy, define a class implementing the RecoverOrDiscardUnsyncedChangesStrategy interface.
The interface provides the following callback methods:
onBeforeReset: Invoked prior to the client reset. Provides an instance of the realm before the reset. You can use this callback to notify the user before the client reset begins.
onAfterRecovery: Se invoca solo si el restablecimiento automático se completa correctamente. Proporciona una instancia anterior de solo lectura del dominio y una instancia mutable del dominio final. Puede usar esta devolución de llamada para notificar al usuario que el restablecimiento del cliente se ha completado.
onAfterDiscard: Se invoca solo si el restablecimiento automático del cliente falla y la estrategia local de descarte se ejecuta correctamente. Si la estrategia de descarte falla, esta devolución de llamada no se invoca. Proporciona una instancia anterior de solo lectura del dominio y una instancia mutable del dominio final. Puede usar esta devolución de llamada para notificar al usuario que el restablecimiento se ha completado.
onManualResetFallback: Invoked only if the automatic recovery and the discard strategy have failed. Discards the local changes and allows you to create backup of the local realm. Implement this callback to handle the reset failure, as explained in the Manual Recovery Fallback section.
The following example shows the RecoverOrDiscardUnsyncedChangesStrategy and each of its callbacks:
val clientResetStrategy = object : RecoverOrDiscardUnsyncedChangesStrategy { override fun onBeforeReset(realm: TypedRealm) { Log.i("Client reset: attempting to automatically recover unsynced changes") } // Executed before the client reset begins. // Can be used to notify the user that a reset will happen. override fun onAfterRecovery(before: TypedRealm, after: MutableRealm) { Log.i("Client reset: successfully recovered all unsynced changes") } // Executed if and only if the automatic recovery has succeeded. override fun onAfterDiscard(before: TypedRealm, after: MutableRealm) { Log.i("Client reset: recovery unsuccessful, attempting to manually recover any changes") // ... Try to manually recover any unsynced data manuallyRecoverUnsyncedData(before, after) } // Executed if the automatic recovery has failed, // but the discard unsynced changes fallback has completed successfully. override fun onManualResetFallback( session: SyncSession, exception: ClientResetRequiredException ) { Log.i("Client reset: manual reset required") // ... Handle the reset manually here } // Automatic reset failed. }
Recuperar cambios no sincronizados
La estrategia de recuperación de cambios no sincronizados intenta recuperar automáticamente todos los cambios locales no sincronizados durante el restablecimiento del cliente. Para ello, laRecuperación del Cliente debe estar habilitada en la aplicación de Servicios de Aplicaciones (está habilitada de forma predeterminada).
Sin embargo, a diferencia de la estrategia de recuperación y descarte de cambios que no han sido sincronizados, no vuelve a descartar los cambios locales si la recuperación automática falla. En su lugar, recurre a recuperar manualmente los cambios. Puedes elegir esta estrategia de restablecimiento del cliente si tu aplicación no puede perder datos no sincronizados.
Para utilizar la estrategia recuperar cambios no sincronizados, defina un handler que implemente la interfaz RecoverUnsyncedChangesStrategy.
The interface provides the following callback methods:
onBeforeReset: Invoked prior to the client reset. Provides an instance of the realm before the reset. You can use this callback to notify the user before the client reset begins.
onAfterReset: Se invoca solo si el restablecimiento automático se completa correctamente. Proporciona una instancia anterior de solo lectura del dominio y una instancia mutable del dominio final. Puede usar esta devolución de llamada para notificar al usuario que el restablecimiento del cliente se ha completado.
onManualResetFallback: Se invoca solo si la recuperación automática falla. Descarta los cambios locales y permite crear una copia de seguridad del dominio local. Implemente esta devolución de llamada para gestionar el error de restablecimiento, como se explica en la sección "Respaldo de recuperación manual".
The following example shows the RecoverUnsyncedChangesStrategy and each of its callbacks:
val clientResetStrategy = object : RecoverUnsyncedChangesStrategy { override fun onBeforeReset(realm: TypedRealm) { Log.i("Client reset: attempting to automatically recover unsynced changes") } // Executed before the client reset begins. // Can be used to notify the user that a reset will happen. override fun onAfterReset(before: TypedRealm, after: MutableRealm) { Log.i("Client reset: successfully recovered all unsynced changes") } // Executed after the client reset is complete. // Can be used to notify the user that the reset is done. override fun onManualResetFallback( session: SyncSession, exception: ClientResetRequiredException ) { Log.i("Client reset: manual reset required") // ... Handle the reset manually here } // Automatic reset failed. }
Descartar cambios no sincronizados
The discard unsynced changes strategy permanently deletes all local unsynced changes made since the last successful sync. This strategy restores your local realm file to a syncable state without closing the realm and while keeping notifications fully working. If this process fails, it falls back to a manual reset strategy.
This is the recommended strategy to handle any manual data recovery.
Es posible elegir esta estrategia cuando la aplicación requiere una lógica de recuperación de cliente que no es coherente con las reglas de recuperación de cliente de Device Sync o cuando no desea recuperar datos no sincronizados.
Importante
Do not use the discard unsynced changes strategy if your application cannot lose any local data that has not yet synced to the backend.
Para utilizar la estrategia de descartar cambios no sincronizados, defina un controlador que implemente la interfaz DiscardUnsyncedChangesStrategy.
The interface provides the following callback methods:
onBeforeReset: Invoked prior to the client reset. Provides an instance of the realm before the reset. You can use this callback to notify the user before the client reset begins.
onAfterReset: Invoked if and only if the reset completes. Provides a read-only before instance of the realm and a mutable instance of the final realm. You can use this callback to notify the user that the reset is complete.
onManualResetFallback: Invoked only if the automatic recovery and the discard strategy have failed. Discards the local changes and allows you to create backup of the local realm. Implement this callback to handle the reset failure, as explained in the Manual Recovery Fallback section.
The following example shows the DiscardUnsyncedChangesStrategy and each of its callbacks:
val clientResetStrategy = object : DiscardUnsyncedChangesStrategy { override fun onBeforeReset(realm: TypedRealm) { Log.i("Client reset: attempting to discard any unsynced changes") } // Executed before the client reset begins. // Can be used to notify the user that a reset will happen. override fun onAfterReset(before: TypedRealm, after: MutableRealm) { Log.i("Client reset: attempting to manually recover any unsynced changes") // ...Try to manually recover any unsynced data manuallyRecoverUnsyncedData(before, after) } // Executed after the client reset is complete. // Can be used to notify the user that the reset is done. override fun onManualResetFallback( session: SyncSession, exception: ClientResetRequiredException ) { Log.i("Client reset: manual reset required") // ... Handle the reset manually here } // Automatic reset failed. override fun onError( session: SyncSession, exception: ClientResetRequiredException ) { // No-op } // Deprecated. onManualResetFallback() used instead. }
Manual Recovery Fallback
If the client reset cannot complete automatically, such as when there are breaking schema changes, the client reset process falls through to a manual error handler.
This may occur in any of the automatic client reset strategies:
Recover unsynced changes
Recover or discard unsynced changes
Discard unsynced changes
Debes proporcionar una implementación manual de restablecimiento del cliente en la función de retorno onManualResetFallback del manejador de restablecimiento del cliente para estas estrategias.
The manual reset fallback discards the local changes and allows you to create backup of the local realm using the ClientResetRequiredException.executeClientReset method.
override fun onManualResetFallback( session: SyncSession, exception: ClientResetRequiredException ) { Log.i("Client reset: manual reset required") // You *MUST* close any open Realm instance closeAllRealmInstances(); // `executeClientReset()` creates a backup exception.executeClientReset(); // (Optional) Send backup for analysis handleBackup(recoveryFilePath); // ... Restore the App state by reopening the realm // or restarting the app }
Manually Recover Unsynced Changes
Use a estratégia de manualmente recuperar alterações não sincronizadas para os casos raros em que seja necessário personalizar o processo de recuperação de dados. Recomendamos usar a estratégia Descartar alterações não sincronizadas sempre que possível para gestionar a recuperação manual de dados. Solo deberías elegir la estrategia de recuperación manual para los cambios no sincronizados si la lógica de recuperación automática no es adecuada para la aplicación y no se pueden descartar los datos locales no sincronizados.
To use the manual recovery strategy, define your own client reset handler using the ManuallyRecoverUnsyncedChangesStrategy interface.
Before you use this method, you must close all instances of the realm that you are resetting. Any writes to the realm file made after the manual recovery callback and before the client reset being executed will not be synced. We also recommend that you create a backup of the file and report the exception.
Initiate a client reset using ClientResetRequiredException.executeClientReset().
If the client reset isn't executed manually, it will be automatically executed the next time all realm instances have been closed and re-opened (typically when the app is restarted).
Test Client Reset Handling
Puede probar manualmente el manejo de restablecimiento del cliente de su aplicación finalizando y volviendo a habilitar la sincronización del dispositivo.
When you terminate and re-enable Sync, clients that have previously connected with Sync are unable to connect until after they perform a client reset. Terminating Sync deletes the metadata from the server that allows the client to synchronize. The client must download a new copy of the realm from the server. The server sends a client reset error to these clients. So, when you terminate Sync, you trigger the client reset condition.
To test client reset handling:
Write data from a client application and wait for it to synchronize.
Termina y vuelve a habilitar Device Sync.
Ejecuta la aplicación cliente nuevamente. La aplicación debería obtener un error de restablecimiento del cliente cuando intente 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.