syncUserData method
//////////// //////////// Syncs cached user data with Firestore when back online
Implementation
// II.G - Offline Support
///////////////
/// Syncs cached user data with Firestore when back online
Future<void> syncUserData() async {
if (!_isOnline || _pendingChanges.isEmpty) return;
final batch = _firestore.batch();
final creations = <String, Map<String, dynamic>>{};
final updates = <String, Map<String, dynamic>>{};
final arrayOps = <String, Map<String, dynamic>>{};
// Separate different types of operations
for (final uid in _pendingChanges.keys) {
final changes = _pendingChanges[uid]!;
// Handle create vs update operations
if (changes.containsKey('__create') && changes['__create'] == true) {
// This is a creation - need to use set
changes.remove('__create');
creations[uid] = changes;
} else {
// This is an update - separate regular fields from array operations
final regularUpdates = <String, dynamic>{};
final arrayOperations = <String, dynamic>{};
changes.forEach((key, value) {
if (value is FieldValue) {
arrayOperations[key] = value;
} else {
regularUpdates[key] = value;
}
});
if (regularUpdates.isNotEmpty) updates[uid] = regularUpdates;
if (arrayOperations.isNotEmpty) arrayOps[uid] = arrayOperations;
}
}
try {
// Process creations in batch
for (final uid in creations.keys) {
final userDocRef = _firestore.collection(_collectionPath).doc(uid);
batch.set(userDocRef, creations[uid]!, SetOptions(merge: true));
}
// Process updates in batch
for (final uid in updates.keys) {
final userDocRef = _firestore.collection(_collectionPath).doc(uid);
batch.update(userDocRef, updates[uid]!);
}
// Commit the batch
await batch.commit();
// Process array operations separately (not in batch because they need special handling)
for (final uid in arrayOps.keys) {
final userDocRef = _firestore.collection(_collectionPath).doc(uid);
await userDocRef.update(arrayOps[uid]!);
}
// Clear pending changes
_pendingChanges.clear();
} catch (e) {
print('Error syncing cached user data: $e');
// Only remove successfully synced changes
if (e is FirebaseException && e.code != 'unavailable') {
// Do partial cleanup - remove only the ones we successfully processed
_pendingChanges.removeWhere((uid, _) => !arrayOps.containsKey(uid));
}
throw RALIException('Failed to sync user data with server', cause: e);
}
}