Docs Menu
Docs Home
/ /
Sincronizar datos

Recuperación de datos tras el restablecimiento manual del cliente - SDK de Node.js

Esta página explica cómo recuperar manualmente datos de reino no sincronizados después de un reinicio de cliente usando el modo de reinicio de cliente Recuperación manual.

La recuperación manual requiere una cantidad considerable de código, concesiones de esquema y una lógica de resolución de conflictos personalizada. Solo debe realizar una recuperación manual de datos de dominio no sincronizados si no puede recuperarlos y los demás métodos de restablecimiento automático del cliente no se ajustan a su caso práctico.

Para obtener más información sobre otros modos de restablecimiento de cliente disponibles, consulte Restablecer un reino de cliente.

Los detalles de la recuperación manual dependen en gran medida de la aplicación y el esquema. Sin embargo, existen algunas técnicas que pueden ayudar con las recuperaciones manuales. La sección Seguimiento de cambios por estrategia de objeto demuestra un método para recuperar cambios no sincronizados durante un reinicio del cliente.

Advertencia

Evite realizar cambios disruptivos en el esquema en producción

No espere recuperar todos los datos no sincronizados tras un cambio de esquema disruptivo. La mejor manera de preservar los datos del usuario es no realizar nunca un cambio de esquema disruptivo.

Importante

Los cambios importantes en el esquema requieren una actualización del esquema de la aplicación

Después de un cambio de esquema importante:

  • Todos los clientes deben realizar un reinicio del cliente.

  • Debe actualizar los modelos de cliente afectados por el cambio de esquema importante.

La estrategia de recuperación de datos de restablecimiento del cliente manual rastrear cambios por objeto permite recuperar datos ya escritos en el archivo Realm del cliente, pero que aún no han sido sincronizados con el backend.

En esta estrategia, se agrega una "Hora de última actualización" a cada modelo de objeto para registrar cuándo cambió por última vez cada objeto. Observaremos esto para determinar cuándo el dominio cargó su estado por última vez al backend.

Cuando el backend invoca un restablecimiento de cliente, busca los objetos eliminados, creados o actualizados desde la última sincronización con el backend. Luego, copia esos datos del dominio de respaldo al nuevo dominio.

Los siguientes pasos demuestran la implementación del proceso a un alto nivel:

  1. Error de restablecimiento de cliente: su aplicación recibe un código de error de restablecimiento de cliente desde el backend.

  2. Implementación de la estrategia: el SDK la denomina implementación de su estrategia.

  3. Cerrar todas las instancias del dominio: Cierre todas las instancias abiertas del dominio que experimenta el reinicio del cliente. Si la arquitectura de su aplicación lo dificulta (por ejemplo, si utiliza varias instancias del dominio simultáneamente en escuchas de toda la aplicación), puede ser más sencillo reiniciar la aplicación. Puede hacerlo mediante programación o mediante una solicitud directa al usuario en un diálogo.

  4. Mover el dominio a un archivo de respaldo: Llamar al método estático Realm.App.Sync.initiateClientReset(). Este método mueve la copia actual del archivo del dominio del cliente a un archivo de respaldo.

  5. Abrir una nueva instancia del dominio: Abra una nueva instancia del dominio con su configuración de sincronización habitual. Si su aplicación utiliza varios dominios, puede identificar el dominio que experimenta un restablecimiento de cliente a partir del nombre del archivo de copia de seguridad.

  6. Descargar todos los datos del dominio desde el backend: Descargue todo el conjunto de datos del dominio antes de continuar. Este es el comportamiento predeterminado del objeto SyncConfiguration.

  7. Abra la copia de seguridad del reino: utilice el error.config objeto pasado como argumento a la función de devolución de llamada SyncConfiguration.error.

  8. Migrar cambios no sincronizados: Consultar el dominio de respaldo para obtener datos que se recuperarán. Insertar, eliminar o actualizar datos en el nuevo dominio según corresponda.

Este ejemplo demuestra cómo implementar la estrategia de recuperación de datos de restablecimiento manual del cliente mediante seguimiento de cambios de objetos.

Nota

Limitaciones de este ejemplo

  • Este ejemplo solo aplica a una aplicación con un único dominio que contiene un único tipo de objeto de dominio. Para cada tipo de objeto adicional, deberá agregar otro detector de sincronización, como se describe en la sección "Seguimiento de la sincronización en dominios separados".

  • Este ejemplo registra la última actualización de cada objeto. Como resultado, la operación de recuperación sobrescribe todo el objeto en el nuevo dominio si algún campo se actualizó después de la última sincronización correcta del dominio de respaldo. Esto podría sobrescribir los campos actualizados por otros clientes con datos antiguos de este cliente. Si los objetos de su dominio contienen varios campos con datos importantes, considere registrar la última actualización de cada campo y recuperar cada campo individualmente.

Para obtener más información sobre otras formas de realizar un restablecimiento manual del cliente con recuperación de datos, consulte la sección Estrategias alternativas.

1

Agrega una nueva propiedad a tu esquema de objetos Realm para rastrear la última vez que se actualizó. Siempre que crees o actualices un objeto Realm con el esquema, incluye una marca de tiempo con la hora de la actualización.

Normalmente, no es posible detectar cuándo se modificó por última vez un objeto de Realm. Esto dificulta determinar qué cambios se sincronizaron con el backend. Al agregar una marca de tiempo lastUpdated a los modelos de objetos de Realm y actualizarla a la hora actual cada vez que se produce un cambio, puede realizar un seguimiento de cuándo se modificaron los objetos.

const DogSchema = {
name: "Dog",
properties: {
name: "string",
age: "int?",
lastUpdated: "int",
},
};
2

En la configuración de sincronización del dominio, configure el clientReset campo en modo manual e incluya una error función de devolución de llamada. Definirá la función de devolución de llamada de error en la sección "Crear devolución de llamada para gestionar el restablecimiento del cliente".

const config = {
schema: [DogSchema],
sync: {
user: app.currentUser,
partitionValue: "MyPartitionValue",
clientReset: {
mode: "manual",
},
error: handleSyncError, // callback function defined later
},
};
3

Saber cuándo se modificaron los objetos no es suficiente para recuperar datos durante el restablecimiento de un cliente. También es necesario saber cuándo el dominio completó una sincronización correctamente por última vez. Esta implementación de ejemplo utiliza un objeto singleton en un dominio independiente llamado LastSynced, emparejado con un detector de cambios para registrar cuándo un dominio termina de sincronizarse correctamente.

Define tu LastSynced Realm para rastrear la última hora en que tu reino se sincroniza.

const LastSyncedSchema = {
name: "LastSynced",
properties: {
realmTracked: "string",
timestamp: "int?",
},
primaryKey: "realmTracked",
};
const lastSyncedConfig = { schema: [LastSyncedSchema] };
const lastSyncedRealm = await Realm.open(lastSyncedConfig);
lastSyncedRealm.write(() => {
lastSyncedRealm.create("LastSynced", {
realmTracked: "Dog",
});
});

Registra un detector de cambios para suscribirse a los cambios en la colección Dog. Actualice el objeto LastSynced solo si la sesión de sincronización está conectada y todos los cambios locales se han sincronizado con el servidor.

// Listens for changes to the Dogs collection
realm.objects("Dog").addListener(async () => {
// only update LastSynced if sync session is connected
// and all local changes are synced
if (realm.syncSession.isConnected()) {
await realm.syncSession.uploadAllLocalChanges();
lastSyncedRealm.write(() => {
lastSyncedRealm.create("LastSynced", {
realmTracked: "Dog",
timestamp: Date.now(),
});
});
}
});
4

Ahora que ha registrado las horas de actualización de todos los objetos de su aplicación, así como la última vez que se realizó una sincronización, es hora de implementar el proceso de recuperación manual. Este ejemplo gestiona dos operaciones de recuperación principales:

  • Restaurar inserciones y actualizaciones no sincronizadas desde el ámbito de respaldo

  • Eliminar objetos del nuevo reino que se eliminaron previamente del reino de respaldo

Puede seguir la implementación de estas operaciones en los ejemplos de código a continuación.

async function handleSyncError(_session, error) {
if (error.name === "ClientReset") {
const realmPath = realm.path; // realm.path will not be accessible after realm.close()
realm.close(); // you must close all realms before proceeding
// pass your realm app instance and realm path to initiateClientReset()
Realm.App.Sync.initiateClientReset(app, realmPath);
// Redownload the realm
realm = await Realm.open(config);
const oldRealm = await Realm.open(error.config);
const lastSyncedTime = lastSyncedRealm.objectForPrimaryKey(
"LastSynced",
"Dog"
).timestamp;
const unsyncedDogs = oldRealm
.objects("Dog")
.filtered(`lastUpdated > ${lastSyncedTime}`);
// add unsynced dogs to synced realm
realm.write(() => {
unsyncedDogs.forEach((dog) => {
realm.create("Dog", dog, "modified");
});
});
// delete dogs from synced realm that were deleted locally
const syncedDogs = realm
.objects("Dog")
.filtered(`lastUpdated <= ${lastSyncedTime}`);
realm.write(() => {
syncedDogs.forEach((dog) => {
if (!oldRealm.objectForPrimaryKey("Dog", dog._id)) {
realm.delete(dog);
}
});
});
// make sure everything syncs and close old realm
await realm.syncSession.uploadAllLocalChanges();
oldRealm.close();
} else {
console.log(`Received error ${error.message}`);
}
}

Las posibles implementaciones alternativas incluyen:

  • Sobrescribir todo el backend con el estado de la copia de seguridad: Sin "última actualización" ni "última sincronización", insertar todos los objetos del dominio de copia de seguridad en el nuevo dominio. Con este enfoque, no es posible recuperar las eliminaciones no sincronizadas. Este enfoque sobrescribe todos los datos escritos en el backend por otros clientes desde la última sincronización. Recomendado para aplicaciones donde solo un usuario escribe en cada dominio.

  • Rastrear cambios por campo: en lugar de rastrear la 'última vez de actualización' para cada objeto, rastrear la 'última vez de actualización' para cada campo. Actualizar los campos individualmente utilizando esta lógica para evitar sobrescribir los guardados de campos de otros clientes con datos antiguos. Recomendado para aplicaciones con muchos campos por objeto donde los conflictos deben resolverse a nivel de campo.

  • Rastrear las actualizaciones por separado de los objetos: En lugar de rastrear la "última hora de actualización" en el esquema de cada objeto, cree otro modelo en su esquema Updates llamado. Cada vez que se actualice un campo de cualquier objeto (excepto),Updates registre la clave principal, el campo y la hora de la actualización. Durante el reinicio de un cliente, reescriba todos los Update eventos ocurridos después de la "última hora de sincronización" utilizando el último valor de ese campo en el dominio de respaldo. Este enfoque debería replicar todos los cambios locales no sincronizados en el nuevo dominio sin sobrescribir ningún campo con datos obsoletos. Sin embargo, almacenar la colección de actualizaciones podría resultar costoso si su aplicación escribe con frecuencia. Se recomienda para aplicaciones donde no se desea agregar campos "lastUpdated" a los modelos de objetos.

Volver

Manejar errores de sincronización

En esta página