Lidar com erros de sincronização - Flutter SDK
Nesta página
- Compensação de erros de gravação
- Reinício do cliente
- Modos de reinício do cliente
- reinício do cliente automático versus manual
- Redefinição do cliente com recuperação
- Recuperar ou descartar modo de alterações não sincronizadas
- Modo Recuperar alterações não sincronizadas
- Modo de descartar alterações não sincronizadas
- fallback de recuperação manual
- Modo de recuperação manual
- Tratamento de reinício do cliente de teste
Ao desenvolver um aplicação que usa o Device Sync, você deve definir um manipulador de erros. Esse manipulador de erros detectará e responderá a qualquer chamada de API relacionada à sincronização com falha.
Adicione um syncErrorHandler propriedade para a FlexibleSyncConfiguration ao criar um Realm sincronizado . syncErrorHandler
é um SyncErrorHandler na função de chamada de resposta deSyncErrorHandler
resposta. aceita um SyncError como parâmetro. Sempre que um SyncError
ocorre no Realm, a função de chamada de resposta de resposta é invocada com o SyncError
como argumento.
final config = Configuration.flexibleSync(currentUser, [Car.schema], syncErrorHandler: (SyncError error) { print("Error message${error.message}"); }); final realm = Realm(config);
Se você não especificar um syncErrorHandler
, o comportamento padrão será imprimir o SyncError
no console.
Dica
Para obter uma lista de erros comuns do Device Sync e como gerenciá-los, consulte Erros de sincronização na documentação do Atlas App Services Device Sync .
Compensação de erros de gravação
A partir do Realm Flutter SDK v1.3, você pode obter informações detalhadas sobre a compensação de erros de gravação.
void handleCompensatingWrite( CompensatingWriteError compensatingWriteError) { final writeReason = compensatingWriteError.compensatingWrites!.first; print("Error message: ${writeReason.reason}"); // ... handle compensating write error as needed. } final config = Configuration.flexibleSync(currentUser, [Car.schema], syncErrorHandler: (syncError) { if (syncError is CompensatingWriteError) { handleCompensatingWrite(syncError); } }); final realm = Realm(config);
Para obter mais detalhes, consulte a classe CompensatingWriteError documentação de referência.
Reinício do cliente
Ao usar o Realm Mobile Sync, um reinício do cliente é uma tarefa de recuperação de erros que seu aplicativo cliente deve executar quando o servidor do Realm Mobile Sync não puder mais sincronizar com o Realm do cliente.
Clientes neste estado podem continuar executando e salvando dados localmente, mas não podem enviar ou receber conjuntos de alterações de sincronização até fazerem um reinício do cliente. O cliente deve redefinir seu Realm para um estado que corresponda ao servidor para restaurar a capacidade de sincronização. O Realm não sincronizável no cliente pode conter dados que ainda não foram sincronizados com o servidor.
O Realm SDK pode tentar recuperar ou descartar esses dados durante o processo de reinício do cliente. O Realm SDK oferece métodos para gerenciar o reinício do cliente automaticamente.
Para obter mais informações sobre o que pode causar a ocorrência de um reinício do cliente, Go Redefinições do cliente na documentação do Atlas App Services .
Modos de reinício do cliente
Para gerenciar o processo de reinício do cliente , você pode especificar um modo de reinício do cliente em seu FlexibleSyncConfiguration.clientResetHandler propriedade ao configurar um Realm. Você pode usar os seguintes modos de reinício do cliente :
Recuperar ou descartar o modo de alterações não sincronizadas (padrão): nesse modo de reinício do cliente, o manipulador de redefinição do cliente primeiro tenta recuperar as alterações não sincronizadas. Se a recuperação falhar, esse manipulador voltará para o modo de descarte de alterações não sincronizadas, que exclui todas as alterações locais não sincronizadas. Se o modo de descartar alterações não sincronizadas falhar, o manipulador voltará ao modo de recuperação manual.
Modo de recuperação de alterações não modo: neste modo de reinício do cliente , o manipulador de reinício do cliente de cliente primeiro tenta recuperar as alterações não sincronizadas. Se a recuperação falhar, esse manipulador voltará ao modo de recuperação manual.
Modo de descartar alterações não modo: esse modo de reinício do cliente exclui permanentemente todas as alterações não sincronizadas locais feitas desde a última sincronização bem-sucedida. Se a recuperação falhar, esse manipulador voltará ao modo de recuperação manual.
modo de recuperação manual: esse modo de reinício do cliente oferece uma maneira de implementar sua própria estratégia de recuperação.
As seções a seguir descrevem como usar esses modos de redefinição de cliente.
reinício do cliente automático versus manual
Os SDKs do Realm oferecem modos de reinício do cliente que lidam automaticamente com a maioria dos erros de reinício do cliente.
Os modos automáticos de redefinição do cliente restauram seu arquivo de domínio local para um estado sincronizável sem fechar o domínio ou perder notificações. Os seguintes modos de reinício do cliente são compatíveis com o reinício do cliente automático:
Recuperar modo de alterações não sincronizadas
Recuperar ou descartar o modo de alterações não sincronizadas
Descartar modo de alterações não sincronizadas
As diferenças entre esses modos são baseadas em como eles lidam com alterações no dispositivo que ainda não foram sincronizadas com o backend. Somente o modo de recuperação manual não executa um reinício automático do cliente.
Escolha o modo recuperar alterações não sincronizadas para lidar com a maioria dos cenários de redefinição de cliente automaticamente. Isso tenta recuperar alterações não sincronizadas quando ocorre uma redefinição de cliente.
Se o seu aplicativo exigir uma lógica de reinício do cliente específica que não possa ser tratada automaticamente, convém ou precise adicionar um manipulador manual de reinício do cliente de cliente ao modo de reinício do cliente .
Redefinição do cliente com recuperação
A recuperação do cliente é um recurso habilitado por padrão quando você configura o Realm Mobile Sync. Quando a Recuperação de Cliente está habilitada, o Realm managed automaticamente o reinício do cliente na maioria dos casos. Quando você faz alterações no esquema, o cliente pode recuperar alterações não sincronizadas quando não há alterações no esquema ou alterações no esquema não significativas.
Para usar a Recuperação de Cliente, configure seu Realm com os modos de reinício do cliente recuperar alterações não sincronizadas ou recuperar ou descartar alterações não sincronizadas.
Quando a Recuperação de Cliente está habilitada, essas regras determinam como os objetos são integrados, incluindo como os conflitos são resolvidos quando o backend e o cliente fazem alterações no mesmo objeto:
Objetos criados localmente que não foram sincronizados antes da redefinição do cliente são sincronizados.
Se um objeto for excluído no servidor, mas for modificado no cliente de recuperação, a exclusão terá precedência e o cliente descartará a atualização.
Se um objeto for excluído no cliente em recuperação, mas não no servidor, o cliente aplicará a instrução de exclusão do servidor.
No caso de atualizações conflitantes no mesmo campo, a atualização do cliente é aplicada.
Para obter mais informações sobre como configurar a Recuperação de Cliente, consulte Recuperação de Cliente na documentação do Atlas App Services .
A Recuperação do Cliente não pode ocorrer quando o aplicativo faz alterações significativas no esquema. Uma alteração significativa é uma alteração que você pode fazer no esquema do lado do servidor que requer uma ação adicional com a qual lidar. Nesse cenário, a redefinição do cliente com fallback para um fallback de redefinição do cliente com erro manual.
Para obter informações sobre alterações de esquema significativas e não significativas, consulte Referência rápida de alterações significativas e não significativas na documentação do Atlas App Services .
Recuperar ou descartar modo de alterações não sincronizadas
O modo Recuperar ou descartar alterações não sincronizadas tenta recuperar automaticamente todas as alterações locais não sincronizadas durante um reinício do cliente. Se você não especificar um modo de reinício do cliente, o comportamento de reinício do cliente terá como padrão recuperar ou descartar alterações não sincronizadas. Se o processo de recuperação automática falhar, ele voltará para o modo de descartar alterações não sincronizadas. Se esse processo falhar, ele voltará novamente para o modo de reinício manual.
O modo Recuperar ou descartar alterações não sincronizadas fornece o processo de recuperação mais robusto. No entanto, não use o modo recuperar ou descartar alterações não sincronizadas se o aplicativo não puder perder dados locais que ainda não foram sincronizados com o backend.
Para personalizar o uso do modo de recuperação ou descarte de alterações não sincronizadas , passe um RecoverOrDiscardUnsyncedChangesHandler chamada de resposta de resposta para o Configure.clientResetHandler
. Adicione os seguintes métodos de chamada de resposta de resposta opcionais para estender a funcionalidade do manipulador:
onBeforeReset, que o SDK invoca antes da reinício do cliente. Você pode usar esse chamada de resposta de chamada para notificar o usuário antes que a reinício do cliente comece.
onAfterRecovery, que o SDK invoca se e somente se o reinício automático for concluído com êxito. Você pode usá-lo para notificar o usuário de que a reinício do cliente foi concluída.
onAfterDiscard, que o SDK invoca somente se o reinício do cliente automático falhar e a estratégia local de descarte for bem-sucedida. Se a estratégia de descarte falhar, este chamada de resposta de chamada não será invocado.
onManualResetFallback, que o SDK invoca somente se a recuperação automática e a estratégia de descarte tiverem falhado. Implemente esse chamada de resposta de chamada para lidar com a falha de redefinição, conforme explicado na seção Recuo de recuperação manual.
O exemplo seguinte mostra utilizando o RecoverOrDiscardUnsyncedChangesHandler
e cada uma das suas chamadas de resposta:
final config = Configuration.flexibleSync(currentUser, schema, clientResetHandler: RecoverOrDiscardUnsyncedChangesHandler( // All the following callbacks are optional onBeforeReset: (beforeResetRealm) { // Executed before the client reset begins. // Can be used to notify the user that a reset is going // to happen. }, onAfterRecovery: (beforeResetRealm, afterResetRealm) { // Executed if and only if the automatic recovery has succeeded. }, onAfterDiscard: (beforeResetRealm, afterResetRealm) { // Executed if the automatic recovery has failed // but the discard unsynced changes fallback has completed // successfully. }, onManualResetFallback: (clientResetError) { // Automatic reset failed. Handle the reset manually here. // Refer to the "Manual Client Reset Fallback" documentation // for more information on what you can include here. }, ));
Modo Recuperar alterações não sincronizadas
O modo Recuperar alterações não sincronizadas tenta recuperar automaticamente todas as alterações locais não sincronizadas durante um reinício do cliente. No entanto, ao contrário do modo de recuperar ou descartar alterações não sincronizadas, esse modo não volta a descartar alterações locais se a recuperação automática falhar. Em vez disso, ele volta para recuperar manualmente as alterações.
Para usar o modo de recuperação de alterações não sincronizadas, passe um RecoverUnsyncedChangesHandler chamada de resposta para o Configure.clientResetHandler
. Este manipulador fornece os seguintes métodos de chamada de resposta:
onBeforeReset, que o SDK invoca antes da redefinição do cliente. Você pode usar esse retorno de chamada para notificar o usuário antes que a redefinição comece.
onAfterReset, que o SDK invoca se e somente se o reinício automático for concluído com êxito. Você pode usar esse retorno de chamada para notificar o usuário quando a redefinição for concluída com êxito.
onManualResetFallback, que o SDK invoca somente se a recuperação automática e a estratégia de descarte tiverem falhado. Você implementa esse retorno de chamada para lidar com a falha de redefinição, conforme explicado na seção Recuo de recuperação manual.
O exemplo seguinte mostra utilizando o RecoverUnsyncedChangesHandler
e cada uma das suas chamadas de resposta:
final config = Configuration.flexibleSync(currentUser, schema, clientResetHandler: RecoverUnsyncedChangesHandler( // All the following callbacks are optional onBeforeReset: (beforeResetRealm) { // Executed before the client reset begins. // Can be used to notify the user that a reset is going // to happen. }, onAfterReset: (beforeResetRealm, afterResetRealm) { // Executed after the client reset is complete. // Can be used to notify the user that the reset is done. }, onManualResetFallback: (clientResetError) { // Automatic reset failed. Handle the reset manually here. // Refer to the "Manual Client Reset Fallback" documentation // for more information on what you can include here. }, ));
Modo de descartar alterações não sincronizadas
O modo de descartar alterações não sincronizadas exclui permanentemente todas as alterações locais não sincronizadas feitas desde a última sincronização bem-sucedida. Se você optar por usar esse modo de reinício do cliente, o SDK restaurará seu arquivo de domínio local para um estado sincronizável sem fechar o domínio e, ao mesmo tempo, manter as notificações em funcionamento total. Se esse processo falhar, ele voltará para o modo de recuperação manual.
Não use o modo recuperar ou descartar alterações não sincronizadas se o aplicativo não puder perder dados locais que ainda não foram sincronizados com o backend.
Para usar o modo de descarte de alterações não sincronizadas, passe um DiscardUnsyncedChangesHandler chamada de resposta de resposta para o Configure.clientResetHandler
. Este manipulador fornece os seguintes métodos de chamada de resposta de resposta:
onBeforeReset, que o SDK invoca antes da redefinição do cliente. Você pode usar esse retorno de chamada para notificar o usuário antes que a redefinição comece.
onAfterReset, que o SDK invoca se e somente se a redefinição for concluída com êxito. Você pode usá-lo para notificar o usuário quando a redefinição for concluída.
onManualResetFallback, que o SDK invoca somente se a recuperação automática e a estratégia de descarte tiverem falhado. Implemente esse chamada de resposta de chamada para lidar com a falha de redefinição, conforme explicado na seção Recuperação manual .
O exemplo seguinte mostra utilizando o DiscardUnsyncedChangesHandler
e cada uma das suas chamadas de resposta:
final config = Configuration.flexibleSync(currentUser, schema, clientResetHandler: DiscardUnsyncedChangesHandler( onBeforeReset: (beforeResetRealm) { // Executed before the client reset begins. // Can be used to notify the user that a reset is going // to happen. }, onAfterReset: (beforeResetRealm, afterResetRealm) { // Executed after the client reset is complete. // Can be used to notify the user that the reset is done. }, onManualResetFallback: (clientResetError) { // Automatic reset failed. Handle the reset manually here. // Refer to the "Manual Client Reset Fallback" documentation // for more information on what you can include here. }, ));
fallback de recuperação manual
Se o reinício do cliente com recuperação não puder ser concluído automaticamente, como quando há alterações significativas no esquema, o processo de reinício do cliente passará para um manipulador de erros manual. Isso pode ocorrer em qualquer um dos modos de reinício do cliente automático:
Recuperar modo de alterações não sincronizadas
Recuperar ou descartar o modo de alterações não sincronizadas
Descartar modo de alterações não sincronizadas
Você deve fornecer uma implementação de reinício do cliente na chamada de resposta onManualResetFallback
do manipulador de reinício do cliente para esses modos.
Em onManualResetFallback
, inicie uma reinício do cliente usando o ClientResetError.resetRealm() do parâmetro ClientResetError
da chamada de resposta de resposta. ClientResetError.resetRealm()
executa um reinício do cliente excluindo o Realm no dispositivo e baixando os dados relevantes do servidor. Antes de usar esse método, você deve fechar todas as instâncias do Realm que está sendo redefinido.
O exemplo a seguir demonstra como você pode lidar manualmente com um caso de erro descartando todas as alterações não sincronizadas:
// Lazily initialize `realm` so that it can be used in the callback // before the realm has been opened. late Realm realm; final config = Configuration.flexibleSync(currentUser, schema, // This example uses the `RecoverOrDiscardUnsyncedChangesHandler`, // but the same logic could also be used with the `RecoverUnsyncedChangesHandler` // or the `DiscardUnsyncedChangesHandler`. clientResetHandler: RecoverOrDiscardUnsyncedChangesHandler( onManualResetFallback: (clientResetError) { // 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. var didUserConfirmReset = showUserAConfirmationDialog(); if (didUserConfirmReset) { // You must close the Realm before attempting the client reset. realm.close(); // Attempt the client reset. try { clientResetError.resetRealm(); // 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 } } }, ));
Modo de recuperação manual
Use o modo de recuperação manual para os casos raros em que você precisa personalizar o processo de recuperação de dados. Na maioria dos casos, você deve usar uma das outras estratégias para o reinício do cliente. Talvez você queira usar um manipulador de reinício do cliente se a lógica de recuperação automática não funcionar para seu aplicativo e você não puder descartar dados locais não sincronizados.
Para usar o modo de recuperação manual, passe um ManualRecoveryHandler chamada de resposta para o Configure.clientResetHandler
.
O manipulador fornece o onManualReset chamada de resposta de chamada , no qual você pode executar a reinício do cliente. Em onManualReset
, inicie uma reinício do cliente usando o ClientResetError.resetRealm() método do parâmetro ClientResetError
da chamada de resposta de resposta. ClientResetError.resetRealm()
executa um reinício do cliente excluindo o Realm no dispositivo e baixando os dados relevantes do servidor. Antes de usar esse método, você deve fechar todas as instâncias do Realm que está sendo redefinido.
// Lazily initialize `realm` so that it can be used in the callback // before the realm has been opened. late Realm realm; final config = Configuration.flexibleSync(currentUser, schema, clientResetHandler: ManualRecoveryHandler((clientResetError) { // You must close the Realm before attempting the client reset. realm.close(); // Handle manual client reset here... // Then perform the client reset. clientResetError.resetRealm(); }));
Tratamento de reinício do cliente de teste
Você pode testar manualmente o tratamento de redefinição do cliente do seu aplicativo encerrando e reativando o Device Sync.
Quando você encerra e reativa a sincronização, os clientes que se conectaram anteriormente à sincronização não conseguem se conectar até depois de fazerem um reinício do cliente. O encerramento da sincronização exclui os metadados do servidor que permitem ao cliente sincronizar. O cliente deve baixar uma nova cópia do Realm do servidor. O servidor envia um erro de reinício do cliente para esses clientes. Então, ao encerrar a sincronização, você trigger a condição de reinício do cliente.
Para testar o tratamento de reinício do cliente:
Escreva dados de um aplicativo cliente e aguarde a sincronização.
Encerre e reative o Realm Mobile Sync.
Run the client app again. O aplicativo deve receber um erro de reinício do cliente ao tentar se conectar ao servidor.
Aviso
Enquanto você itera sobre o tratamento de redefinição do cliente em seu aplicativo cliente, talvez seja necessário encerrar e reativar a sincronização repetidamente. Encerrar e reativar a sincronização impede que todos os clientes existentes sincronizem até depois de concluir a redefinição do cliente. Para evitar isso na produção, teste o tratamento de redefinição do cliente em um ambiente de desenvolvimento.