pushBatch method

  1. @override
Future<void> pushBatch({
  1. required String collection,
  2. required List<SyncChange> changes,
})
override

Pushes multiple changes to the remote backend in a single call.

Implementations should use a batch/transaction API where available to minimise round-trips and ensure atomicity.

Implementation

@override
Future<void> pushBatch({
  required String collection,
  required List<SyncChange> changes,
}) async {
  // Firestore batches are limited to 500 operations; split if needed.
  const batchLimit = 500;
  final batches = <WriteBatch>[];

  for (var i = 0; i < changes.length; i += batchLimit) {
    final chunk = changes.sublist(
      i,
      (i + batchLimit).clamp(0, changes.length),
    );
    final batch = _firestore.batch();

    for (final change in chunk) {
      final id = change.id;
      final doc = change.document;
      final userId = doc['userId'] as String?;
      final ref = _collectionRef(collection, userId: userId).doc(id);

      switch (change.operation) {
        case SyncOperation.create:
        case SyncOperation.update:
          batch.set(ref, _preparePayload(doc), SetOptions(merge: true));
        case SyncOperation.delete:
          final isDeleted = doc['isDeleted'] as bool? ?? false;
          if (isDeleted) {
            batch.set(ref, {
              'isDeleted': true,
              timestampField: FieldValue.serverTimestamp(),
            }, SetOptions(merge: true));
          } else {
            batch.delete(ref);
          }
      }
    }

    batches.add(batch);
  }

  await Future.wait(batches.map((b) => b.commit()));
}