syncUserData method

Future<void> syncUserData()

//////////// //////////// 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);
  }
}