簡體   English   中英

Flutter / cloud-firestore“任務已經完成”例外

[英]Flutter/cloud-firestore “Task is already complete” Exception

我正在使用Flutter編寫應用程序,我必須使用Firestore.instance.runTransaction(Transaction tx)方法進行Firestore.instance.runTransaction(Transaction tx) 在我的Transaction對象(或方法)中,我必須使用文檔引用更新一些數據。

_firestore.runTransaction((Transaction x) async {
  await x.update(Aref, {'data': itemA - y});
  await x.update(Bref, {'data': itemB + y});
})

代碼運行時拋出異常(這里是控制台日志):

E / MethodChannel#plugins.flutter.io / cloud_firestore(32612):無法處理方法調用結果E / MethodChannel#plugins.flutter.io / cloud_firestore(32612):java.lang.IllegalStateException:任務已完成E / MethodChannel# plugins.flutter.io/cloud_firestore(32612):at com.google.android.gms.common.internal.Preconditions.checkState(Unknown來源:8)E / MethodChannel#plugins.flutter.io / cloud_firestore(32612):at com .google.android.gms.tasks.zzu.zzdr(未知來源:8)E / MethodChannel#plugins.flutter.io / cloud_firestore(32612):at com.google.android.gms.tasks.zzu.setResult(Unknown Source :3)E / MethodChannel#plugins.flutter.io / cloud_firestore(32612):at com.google.android.gms.tasks.TaskCompletionSource.setResult(Unknown來源:2)E / MethodChannel#plugins.flutter.io / cloud_firestore( 32612):at io.flutter.plugins.firebase.cloudfirestore.CloudFirestorePlugin $ 3 $ 1.success(CloudFirestorePlugin.java:283)E / MethodChannel#plugins.flutter.io / cloud_firestore(32612):at io.flutter.plugin.common。 MethodC hannel $ IncomingResultHandler.reply(MethodChannel.java:169)E / MethodChannel#plugins.flutter.io / cloud_firestore(32612):at io.flutter.view.FlutterNativeView.handlePlatformMessageResponse(FlutterNativeView.java:187)E / MethodChannel#plugins。 flutter.io/cloud_firestore(32612):在android.os.MessageQueue.nativePollOnce(Native Method)E / MethodChannel#plugins.flutter.io / cloud_firestore(32612):at android.os.MessageQueue.next(MessageQueue.java:325 )E / MethodChannel#plugins.flutter.io / cloud_firestore(32612):at android.os.Looper.loop(Looper.java:142)

當同時多次調用firestore api時會發生錯誤,你必須將每個函數嵌套在前一個函數的“whenComplete((){}”方法中。這是錯誤的代碼:

g.f.runTransaction((transaction) async {
      DocumentSnapshot snap =
          await transaction.get(/my code);

      await transaction.update(/my code).whenComplete(() {});
    });


g.f.runTransaction((transaction) async {
      DocumentSnapshot freshSnap =
              await transaction.get(/my code));

      await transaction.update(/my code).whenComplete(() {});
});  //here is the problem!! I'have to nest this inside "whenComplete(() {})

這是錯誤:

E / MethodChannel#plugins.flutter.io / cloud_firestore(5337):無法處理方法調用結果E / MethodChannel#plugins.flutter.io / cloud_firestore(5337):java.lang.IllegalStateException:任務已完成

這是正確的代碼

g.f.runTransaction((transaction) async {
  DocumentSnapshot snap =
      await transaction.get(/my code);

  await transaction.update(/my code).whenComplete(() {
    g.f.runTransaction((transaction) async {
      DocumentSnapshot freshSnap =
          await transaction.get(/my code);

      await transaction.update(/my code);
    }).whenComplete(() {});
  });
});

我有同樣的問題。 試試這個。 希望它有助於FIrestore事務處理程序

公司的FireStore-事務處理程序

這是一個子程序,用於在cloud_firestore pub中為Flutter使用runTransaction函數時幫助處理失敗的事務問題

問題

對於以下錯誤,此代碼是針對Flutter的cloud_firestore包的錯誤的解決方案1. PlatformException(Error performing Transaction#get, Transaction has already completed., null) DoTransaction failed: Document version changed between two reads.

根據我的經驗,我意識到當我嘗試更新剛剛創建的記錄時會出現問題。 出於某種原因, tx.get() (請參閱https://pub.dev/packages/cloud_firestore中的 runTransaction示例)無法獲取剛剛創建的記錄,並且更新操作失敗。 我發現如果我們等一下再試一次,我們就能得到記錄並更新它。 為了簡單起見,我創建了一個為您執行更新和運行事務的函數。

解決方案

這是一個例子:

     await fcmTransactionHandler(
      postRef: postRef, //  This is your DocumentReference that you want to update
      key: 'myfield', // This is the field that you want to update
      validationFunction: updateMyField, // This is a function that allows you to check 
      // some condition in the record you 'get' before updating
 );

validationFunction需要一個動態值(您想更新字段的值)作為輸入,並給出了{}值,您將在記錄更新。 例如,如果我想更新字段myfield如果它是true ,那么我將創建一個函數updateMyField ,如下所示

Map<String, dynamic> updateMyField({dynamic value}) {
    return  value ? <String, dynamic>{'myfield': true} : <String, dynamic>{'myfield': value};
  }

然后將此函數傳遞給validationFunction 為什么這樣設計? 如您所見,我們試圖在一段時間后獲取記錄然后更新它。 如果記錄已經被其他人更新了怎么辦? 在這種情況下,我們必須驗證記錄可用時獲得的數據,以防止任何不正確的更新。 validationFunction幫助我們做到這一點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM