upsertDocs method

  1. @protected
Future<TurboResponse<List<T>>> upsertDocs({
  1. Transaction? transaction,
  2. required List<String> ids,
  3. required UpsertDocDef<T> doc,
  4. bool doNotifyListeners = true,
})

Upserts (updates or inserts) multiple documents both locally and in Firestore.

This method will either update existing documents or create new ones if they don't exist. The doc function receives each current document (or null if it doesn't exist) and should return the new document state.

Performs optimistic upserts by updating the local state first, then syncing with Firestore. Uses a batch operation for multiple documents unless a transaction is provided.

Parameters:

  • transaction - Optional transaction for atomic operations
  • ids - The IDs of the documents to upsert
  • doc - The definition of how to upsert the documents
  • doNotifyListeners - Whether to notify listeners of the changes

Returns a TurboResponse with the list of upserted documents

Implementation

@protected
Future<TurboResponse<List<T>>> upsertDocs({
  Transaction? transaction,
  required List<String> ids,
  required UpsertDocDef<T> doc,
  bool doNotifyListeners = true,
}) async {
  try {
    log.debug('Upserting ${ids.length} docs');
    final pDocs = upsertLocalDocs(
      ids: ids,
      doc: doc,
      doNotifyListeners: doNotifyListeners,
    );
    if (transaction != null) {
      for (final pDoc in pDocs) {
        (await api.createDoc(
          writeable: pDoc,
          id: pDoc.id,
          transaction: transaction,
          merge: true,
        ))
            .throwWhenFail();
      }
      return TurboResponse.success(result: pDocs);
    } else {
      final batch = api.writeBatch;
      for (final pDoc in pDocs) {
        await api.createDocInBatch(
          id: pDoc.id,
          writeBatch: batch,
          writeable: pDoc,
          merge: true,
        );
      }
      final future = batch.commit();
      await future;
      return TurboResponse.success(result: pDocs);
    }
  } catch (error, stackTrace) {
    if (transaction != null) rethrow;
    log.error(
      '${error.runtimeType} caught while upserting docs',
      error: error,
      stackTrace: stackTrace,
    );
    return TurboResponse.fail(error: error);
  }
}