Flutterfire: [cloud_firestore] Android Transaction not handling exception properly

Created on 10 Apr 2020  路  3Comments  路  Source: FirebaseExtended/flutterfire

I am trying to abort a transaction by throwing an exception throw ("Exception ==> Deliberate exit"); or by returning an error future return Future.error("Exception => Deliberate exit"); but the plugin spitting out another exception. The correct exception is reflected as a DoTransaction failed exception in java (see output below) but flutter throws the following exception PlatformException(Error performing transaction, Every document read in a transaction must also be written., null). I know flutter is throwing this exception because the remainder of the code is not executed where I would have written to the read document. Whether I have written to a read document should not matter after I have aborted. The transaction must fail and return my explicit exception/ or exception message.

Maybe I have missed something and this is not the proper way to abort a transaction (and return a message), I would be delighted to be shown the proper way. Thank you.

Code

try {
  String profileId =
      profilesCollectionRef(accountId: accountId).document().documentID;

  final res = await Firestore.instance.runTransaction((tx) async {
    DocumentSnapshot accountSnapshot =
        await accountDocumentRef(accountId: accountId).get();

    DocumentSnapshot userNameSnapshot =
        await tx.get(userNamesCollectionRef.document(params.username));

    if (accountSnapshot.exists) {

      throw ("Exception ==> Deliberate exit");

      //return Future.error("Exception => Deliberate exit");

      if (userNameSnapshot.exists) {
        throw ("Username now Taken");
      }

     ...

     await tx.set(
          userNamesCollectionRef.document(params.username),
          <String, dynamic>{
            "profileId": profileId,
            "dateCreated": FieldValue.serverTimestamp()
          });

  });
} catch (e,s) {
  print("$e === > $s");
  return Future.error(e,s);
}

Output

E/CloudFirestorePlugin(16362): java.lang.Exception: DoTransaction failed: Exception ==> Deliberate exit E/CloudFirestorePlugin(16362): java.util.concurrent.ExecutionException: java.lang.Exception: DoTransaction failed: Exception ==> Deliberate exit E/CloudFirestorePlugin(16362): at com.google.android.gms.tasks.Tasks.zzb(Unknown Source:61) E/CloudFirestorePlugin(16362): at com.google.android.gms.tasks.Tasks.await(Unknown Source:33) E/CloudFirestorePlugin(16362): at io.flutter.plugins.firebase.cloudfirestore.CloudFirestorePlugin$4.apply(CloudFirestorePlugin.java:527) E/CloudFirestorePlugin(16362): at io.flutter.plugins.firebase.cloudfirestore.CloudFirestorePlugin$4.apply(CloudFirestorePlugin.java:479) E/CloudFirestorePlugin(16362): at com.google.firebase.firestore.FirebaseFirestore.lambda$runTransaction$0(com.google.firebase:firebase-firestore@@21.3.0:301) E/CloudFirestorePlugin(16362): at com.google.firebase.firestore.FirebaseFirestore$$Lambda$5.call(Unknown Source:6) E/CloudFirestorePlugin(16362): at com.google.android.gms.tasks.zzv.run(Unknown Source:2) E/CloudFirestorePlugin(16362): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) E/CloudFirestorePlugin(16362): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) E/CloudFirestorePlugin(16362): at java.lang.Thread.run(Thread.java:764) E/CloudFirestorePlugin(16362): Caused by: java.lang.Exception: DoTransaction failed: Exception ==> Deliberate exit E/CloudFirestorePlugin(16362): at io.flutter.plugins.firebase.cloudfirestore.CloudFirestorePlugin$4$1$1.error(CloudFirestorePlugin.java:509) E/CloudFirestorePlugin(16362): at io.flutter.plugin.common.MethodChannel$IncomingResultHandler.reply(MethodChannel.java:205) E/CloudFirestorePlugin(16362): at io.flutter.embedding.engine.dart.DartMessenger.handlePlatformMessageResponse(DartMessenger.java:103) E/CloudFirestorePlugin(16362): at io.flutter.embedding.engine.FlutterJNI.handlePlatformMessageResponse(FlutterJNI.java:642) E/CloudFirestorePlugin(16362): at android.os.MessageQueue.nativePollOnce(Native Method) E/CloudFirestorePlugin(16362): at android.os.MessageQueue.next(MessageQueue.java:326) E/CloudFirestorePlugin(16362): at android.os.Looper.loop(Looper.java:181) E/CloudFirestorePlugin(16362): at android.app.ActivityThread.main(ActivityThread.java:7050) E/CloudFirestorePlugin(16362): at java.lang.reflect.Method.invoke(Native Method) E/CloudFirestorePlugin(16362): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494) E/CloudFirestorePlugin(16362): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965) I/flutter (16362): PlatformException(Error performing transaction, Every document read in a transaction must also be written., null) === > #0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:569:7) I/flutter (16362): #1 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:156:18) I/flutter (16362): <asynchronous suspension> I/flutter (16362): #2 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:329:12) I/flutter (16362): #3 MethodChannel.invokeMapMethod (package:flutter/src/services/platform_channel.dart:356:48) I/flutter (16362): #4 MethodChannelFirestore.runTransaction (package:cloud_firestore_platform_interface/src/method_channel/method_channel_firestore.dart:123:10) I/flutter (16362): #5 Firestore.runTransaction (package:cloud_firestore/src/firestore.dart:85:22) I/flutter (16362): #6 ProfileRepo.createProfile (package:tsigira_app/data/repository/v1/profile_repo.dart:33:44) I/flutter (16362): #7 CreateProfileUseCase._createAdditionalProfile (package:tsigira_app/domain/usecases/profile/create_profile_usecase.dart:54:25) I/flutter (16362): #8 CreateProfileUse

customer-response bug

Most helpful comment

This is fixed as part of #2582 (when it lands):

image

Required an overhaul of the transaction flow so it can't be backwards patched easily.

All 3 comments

Hi @tapsey
can you please provide your flutter doctor -v and flutter run --verbose?
Also, to better address the issue, would be helpful if you could post a minimal code sample to reproduce the problem
Thank you

This is fixed as part of #2582 (when it lands):

image

Required an overhaul of the transaction flow so it can't be backwards patched easily.

Hey this has been fixed as part of #2582 / #2913 - pending release.

Was this page helpful?
0 / 5 - 0 ratings