Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[cloud_firestore] Android cannot catch Error behavior of single transaction #1220

Closed
kroikie opened this issue Oct 13, 2019 · 2 comments
Closed
Labels
platform: android Issues / PRs which are specifically for Android. plugin: cloud_firestore type: bug Something isn't working

Comments

@kroikie
Copy link
Collaborator

kroikie commented Oct 13, 2019

Android and iOS have different behavior of single transaction.
I think Flutter for Android or cloud_firestore for Android can not handle the error correctly.

Steps to Reproduce

e.g.1

throw in transaction.
Of course, transaction will fail.

But Android had crash.

  1. test code
await _db.runTransaction((Transaction tx) async {
  print('Transaction start');
  throw 'err';
}).then((value) {
  print('ok');
}).catchError((err) {
  print(err);
});
}
  1. Result of Android Simulator
E/CloudFirestorePlugin(11258): java.lang.Exception: Do transaction failed.
E/CloudFirestorePlugin(11258): java.util.concurrent.ExecutionException: java.lang.Exception: Do transaction failed.
E/CloudFirestorePlugin(11258):  at com.google.android.gms.tasks.Tasks.zzb(Unknown Source:61)
E/CloudFirestorePlugin(11258):  at com.google.android.gms.tasks.Tasks.await(Unknown Source:33)
E/CloudFirestorePlugin(11258):  at io.flutter.plugins.firebase.cloudfirestore.CloudFirestorePlugin$4.apply(CloudFirestorePlugin.java:409)
E/CloudFirestorePlugin(11258):  at io.flutter.plugins.firebase.cloudfirestore.CloudFirestorePlugin$4.apply(CloudFirestorePlugin.java:361)
E/CloudFirestorePlugin(11258):  at com.google.firebase.firestore.FirebaseFirestore.lambda$runTransaction$1(com.google.firebase:firebase-firestore@@19.0.0:283)
E/CloudFirestorePlugin(11258):  at com.google.firebase.firestore.FirebaseFirestore$$Lambda$3.call(Unknown Source:6)
E/CloudFirestorePlugin(11258):  at com.google.android.gms.tasks.zzv.run(Unknown Source:2)
E/CloudFirestorePlugin(11258):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
E/CloudFirestorePlugin(11258):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
E/CloudFirestorePlugin(11258):  at java.lang.Thread.run(Thread.java:764)
E/CloudFirestorePlugin(11258): Caused by: java.lang.Exception: Do transaction failed.
E/CloudFirestorePlugin(11258):  at io.flutter.plugins.firebase.cloudfirestore.CloudFirestorePlugin$4$1$1.error(CloudFirestorePlugin.java:391)
E/CloudFirestorePlugin(11258):  at io.flutter.plugin.common.MethodChannel$IncomingResultHandler.reply(MethodChannel.java:181)
E/CloudFirestorePlugin(11258):  at io.flutter.embedding.engine.dart.DartMessenger.handlePlatformMessageResponse(DartMessenger.java:103)
E/CloudFirestorePlugin(11258):  at io.flutter.embedding.engine.FlutterJNI.handlePlatformMessageResponse(FlutterJNI.java:228)
E/CloudFirestorePlugin(11258):  at android.os.MessageQueue.nativePollOnce(Native Method)
E/CloudFirestorePlugin(11258):  at android.os.MessageQueue.next(MessageQueue.java:325)
E/CloudFirestorePlugin(11258):  at android.os.Looper.loop(Looper.java:142)
E/CloudFirestorePlugin(11258):  at android.app.ActivityThread.main(ActivityThread.java:6494)
E/CloudFirestorePlugin(11258):  at java.lang.reflect.Method.invoke(Native Method)
E/CloudFirestorePlugin(11258):  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
E/CloudFirestorePlugin(11258):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
I/flutter (11258): PlatformException(Error performing transaction, java.lang.Exception: Do transaction failed., null)
D/AndroidRuntime(11258): Shutting down VM
E/AndroidRuntime(11258): FATAL EXCEPTION: main
E/AndroidRuntime(11258): Process: com.example.flutter_firestore, PID: 11258
E/AndroidRuntime(11258): java.lang.IllegalStateException: Reply already submitted
E/AndroidRuntime(11258):    at io.flutter.embedding.engine.dart.DartMessenger$Reply.reply(DartMessenger.java:124)
E/AndroidRuntime(11258):    at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler$1.success(MethodChannel.java:204)
E/AndroidRuntime(11258):    at io.flutter.plugins.firebase.cloudfirestore.CloudFirestorePlugin$3.onComplete(CloudFirestorePlugin.java:425)
E/AndroidRuntime(11258):    at com.google.android.gms.tasks.zzj.run(Unknown Source:4)
E/AndroidRuntime(11258):    at android.os.Handler.handleCallback(Handler.java:790)
E/AndroidRuntime(11258):    at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(11258):    at android.os.Looper.loop(Looper.java:164)
E/AndroidRuntime(11258):    at android.app.ActivityThread.main(ActivityThread.java:6494)
E/AndroidRuntime(11258):    at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(11258):    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
E/AndroidRuntime(11258):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
  1. Result of iOS simulator
flutter: Transaction start
flutter: PlatformException(error, err, null)

e.g.2

At first, test code get 'book1' doc.
After that, test code don't write 'book1' doc.
So, transaction will fail.

But, Android could not detect failure.

  1. test code
final CollectionReference booksRef = _db.collection('/books');

await _db.runTransaction((Transaction tx) async {
  print('Transaction start');
  DocumentSnapshot book1Snapshot = await tx.get(booksRef.document('book1'));

  if (book1Snapshot.exists) {
    await tx.update(booksRef.document('book2'),
        <String, dynamic>{'title': book1Snapshot.data['title']});
  }
}).then((value) {
  print('ok');
}).catchError((err) {
  print(err);
});
  1. Result of Android
I/flutter (11258): Transaction start
I/flutter (11258): Transaction start
I/flutter (11258): ok
  1. Result of iOS
flutter: Transaction start
flutter: Transaction start
flutter: Transaction start
flutter: Transaction start
flutter: Transaction start
flutter: Transaction start
flutter: PlatformException(9, Transaction failed all retries.: Every document read in a transaction must also be written in that transaction., null)

My environment

dependencies:
  flutter:
    sdk: flutter
  firebase_core: ^0.4.0
  cloud_firestore: ^0.12.5+2
[✓] Flutter (Channel stable, v1.5.4-hotfix.2, on Mac OS X 10.14.5 18F132, locale ja-JP)
 
[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
[✓] iOS toolchain - develop for iOS devices (Xcode 10.2.1)
[✓] Android Studio (version 3.4)
[!] VS Code (version 1.35.0)
    ✗ Flutter extension not installed; install from
      https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter
[✓] Connected device (2 available)
@kroikie
Copy link
Collaborator Author

kroikie commented Oct 13, 2019

@hisurga

The issue at flutter/flutter#35529 has been closed and moved here. Future collaboration on this issue will be done here.

@janmoppel janmoppel changed the title Android cannot catch Error behavior of single transaction [cloud_firestore] Android cannot catch Error behavior of single transaction Oct 18, 2019
@janmoppel janmoppel added the type: bug Something isn't working label Oct 18, 2019
@helenaford helenaford added the platform: android Issues / PRs which are specifically for Android. label Apr 21, 2020
@helenaford
Copy link
Contributor

Let's consolidate this under #1223 - will close this one - thanks

@firebase firebase locked and limited conversation to collaborators Aug 9, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
platform: android Issues / PRs which are specifically for Android. plugin: cloud_firestore type: bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants