首页 > 解决方案 > Android 事务问题(Flutter 和 Firestore)

问题描述

cloud_firestore: ^0.13.7

在 iOS 上,事务按预期工作。

使用 Android 设备或模拟器,可以在没有任何干扰的情况下进行交易。但是当Transaction中间的相关Document有write(其他Device或Cloud Function)时,直接抛出异常。这不是预期的功能。

代码:

  Future<bool> singleTransaction({
    @required String path,
    @required bool logic(Map<String, dynamic> data),
    @required Map<String, dynamic> changes(Map<String, dynamic> data),
  }) async {
    print('start transaction');
    final DocumentReference reference = Firestore.instance.document(path);
    bool update;
    await Firestore.instance.runTransaction(
      (Transaction tx) async {
        print('new transaction run');
        update = false;
        DocumentSnapshot snapshot = await tx.get(reference);
        await Future.delayed(Duration(seconds: 4)); //only for debug
        if (snapshot.exists && (snapshot.data != null)) {
          update = logic(snapshot.data);
          if (update) {
            Map<String, dynamic> data = changes(snapshot.data);
            print('write: $path: $data');
            await tx.update(reference, data);
          }
        }
      },
    );
    print('end transaction');
    return update;
  }

错误:

E/AndroidRuntime(28663): FATAL EXCEPTION: AsyncTask #7
E/AndroidRuntime(28663): java.lang.RuntimeException: An error occurred while executing doInBackground()
E/AndroidRuntime(28663):    at android.os.AsyncTask$4.done(AsyncTask.java:399)
E/AndroidRuntime(28663):    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
E/AndroidRuntime(28663):    at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
E/AndroidRuntime(28663):    at java.util.concurrent.FutureTask.run(FutureTask.java:271)
E/AndroidRuntime(28663):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:289)
E/AndroidRuntime(28663):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
E/AndroidRuntime(28663):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
E/AndroidRuntime(28663):    at java.lang.Thread.run(Thread.java:919)
E/AndroidRuntime(28663): Caused by: java.lang.AssertionError: INTERNAL ASSERTION FAILED: A transaction object cannot be used after its update callback has been invoked.
E/AndroidRuntime(28663):    at com.google.firebase.firestore.util.Assert.fail(com.google.firebase:firebase-firestore@@21.3.0:46)
E/AndroidRuntime(28663):    at com.google.firebase.firestore.util.Assert.hardAssert(com.google.firebase:firebase-firestore@@21.3.0:31)
E/AndroidRuntime(28663):    at com.google.firebase.firestore.core.Transaction.ensureCommitNotCalled(com.google.firebase:firebase-firestore@@21.3.0:246)
E/AndroidRuntime(28663):    at com.google.firebase.firestore.core.Transaction.lookup(com.google.firebase:firebase-firestore@@21.3.0:81)
E/AndroidRuntime(28663):    at com.google.firebase.firestore.Transaction.getAsync(com.google.firebase:firebase-firestore@@21.3.0:191)
E/AndroidRuntime(28663):    at com.google.firebase.firestore.Transaction.get(com.google.firebase:firebase-firestore@@21.3.0:228)
E/AndroidRuntime(28663):    at io.flutter.plugins.firebase.cloudfirestore.CloudFirestorePlugin$6.doInBackground(CloudFirestorePlugin.java:627)
E/AndroidRuntime(28663):    at io.flutter.plugins.firebase.cloudfirestore.CloudFirestorePlugin$6.doInBackground(CloudFirestorePlugin.java:622)
E/AndroidRuntime(28663):    at android.os.AsyncTask$3.call(AsyncTask.java:378)
E/AndroidRuntime(28663):    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
E/AndroidRuntime(28663):    ... 4 more
I/Process (28663): Sending signal. PID: 28663 SIG: 9
Lost connection to device.

标签: androidfluttergoogle-cloud-firestoretransactions

解决方案


推荐阅读