pulyaevskiy / firebase-functions-interop

Firebase Functions Interop Library for Dart.
BSD 3-Clause "New" or "Revised" License
191 stars 52 forks source link

TransactionResult doesn't allow abort on non dynamic data #71

Open natebot13 opened 3 years ago

natebot13 commented 3 years ago
await database.ref('queue').transaction<Map<String, dynamic>>(
  (currentData) {
    print(currentData);
    if (currentData.length.isOdd) {
      print('aborting!');
      return TransactionResult.abort;
    }
    print('hand waving done');
    return TransactionResult.success(currentData);
  },
);

I'm running into a compile issue with this code. The transaction.abort line gives an error saying: The return type 'TransactionResult<dynamic>' isn't a 'TransactionResult<Map<String, dynamic>>', as required by the closure's context.

Am I allowed to specify the transaction type?

pulyaevskiy commented 3 years ago

This looks like a bug in the admin interop package:

https://github.com/pulyaevskiy/firebase-admin-interop/blob/b958afb5cdf893ce76b2d71c67ee4b023e5087d4/lib/src/database.dart#L560-L568

class TransactionResult<T> {
  TransactionResult._(this.aborted, this.data);
  final bool aborted;
  final T data;

  static TransactionResult abort = new TransactionResult._(true, null);
  static TransactionResult<T> success<T>(T data) =>
      new TransactionResult._(false, data);
}

The abort field should really be closer to

static TransactionResult<T> abort = new TransactionResult<T>._(true, null);

Though I'm not sure if this is a valid use of generics. Might need to be changed into a static method the same way as success.