runTransaction<T> method

Future<T> runTransaction<T>(
  1. TransactionHandler<T> transactionHandler, {
  2. int maxAttempts = 5,
  3. Duration timeout = const Duration(seconds: 30),
})

Implementation

Future<T> runTransaction<T>(
  TransactionHandler<T> transactionHandler, {
  int maxAttempts = 5,
  Duration timeout = const Duration(seconds: 30),
}) async {
  if (maxAttempts <= 0) {
    return Future.error(
      FirebaseFirestoreAdminException(
        FirestoreClientErrorCode.failedPrecondition,
        'Transaction max attemps must be > 0.',
      ),
    );
  }
  return Future<T>(() async {
    var attempts = 1;
    while (true) {
      try {
        return await _runTransaction(transactionHandler);
      } on FirebaseFirestoreAdminException catch (firebaseError) {
        if (firebaseError.errorCode == FirestoreClientErrorCode.aborted ||
            firebaseError.errorCode == FirestoreClientErrorCode.unavailable ||
            firebaseError.errorCode == FirestoreClientErrorCode.internal) {
          if (attempts < maxAttempts) {
            attempts += 1;
          } else {
            return Future.error(
              FirebaseFirestoreAdminException(
                FirestoreClientErrorCode.failedPrecondition,
                'Transaction max atempts exceded.',
              ),
            );
          }
        } else {
          return Future.error(firebaseError);
        }
      } catch (e) {
        return Future.error(e);
      }
    }
  }).timeout(
    timeout,
    onTimeout: () => Future.error(
      FirebaseFirestoreAdminException(
        FirestoreClientErrorCode.deadlineExceeded,
        'Transaction timout.',
      ),
    ),
  );
}