runTransaction method
Future<TransactionResult?> ?
runTransaction(
- TransactionHandler? transactionHandler, {
- Duration? timeout = const Duration(seconds: 5),
Performs an optimistic-concurrency transactional update to the data at this Firebase Database location.
Implementation
Future<TransactionResult> runTransaction(
TransactionHandler transactionHandler,
{Duration timeout = const Duration(seconds: 5)}) async {
assert(timeout.inMilliseconds > 0,
'Transaction timeout must be more than 0 milliseconds.');
final Completer<TransactionResult> completer =
Completer<TransactionResult>();
final int transactionKey = FirebaseDatabase._transactions.isEmpty
? 0
: FirebaseDatabase._transactions.keys.last + 1;
FirebaseDatabase._transactions[transactionKey] = transactionHandler;
TransactionResult toTransactionResult(Map<dynamic, dynamic> map) {
final DatabaseError databaseError =
map['error'] != null ? DatabaseError._(map['error']) : null;
final bool committed = map['committed'];
final DataSnapshot dataSnapshot =
map['snapshot'] != null ? DataSnapshot._(map['snapshot']) : null;
FirebaseDatabase._transactions.remove(transactionKey);
return TransactionResult._(databaseError, committed, dataSnapshot);
}
// TODO(rrousselGit) refactor to async/await
// TODO(rrousselGit) what if invokeMethod fails?
// ignore: unawaited_futures
_database._channel.invokeMethod<void>(
'DatabaseReference#runTransaction', <String, dynamic>{
'app': _database.app?.name,
'databaseURL': _database.databaseURL,
'path': path,
'transactionKey': transactionKey,
'transactionTimeout': timeout.inMilliseconds
}).then((dynamic response) {
completer.complete(toTransactionResult(response));
});
return completer.future;
}