Firebase Firestore事务不起作用

Firebase Firestore事务不起作用,firebase,dart,google-cloud-firestore,flutter,Firebase,Dart,Google Cloud Firestore,Flutter,我发现人们也无法完成交易,但它甚至不能提供解决方案 问题 突然,当使用事务时,我的 runTransaction( (Transaction transaction) async { await transaction.get(documentReference); // "Timed out waiting for Task" } PlatformException也没有真正帮助我,因为它在platform\u频道中崩溃 E/flutter (16297): [ERROR:t

我发现人们也无法完成交易,但它甚至不能提供解决方案

问题 突然,当使用
事务时,我的

runTransaction(
  (Transaction transaction) async {
    await transaction.get(documentReference); // "Timed out waiting for Task"
  }
PlatformException
也没有真正帮助我,因为它在
platform\u频道
中崩溃

E/flutter (16297): [ERROR:topaz/lib/tonic/logging/dart_error.cc(16)] Unhandled exception:
E/flutter (16297): PlatformException(Error performing transaction, Timed out waiting for Task, null)
E/flutter (16297): #0      StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:547:7)
E/flutter (16297): #1      MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:279:18)
E/flutter (16297): <asynchronous suspension>
E/flutter (16297): #2      Firestore.runTransaction (file:///G:/flutter/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.7.3/lib/src/firestore.dart:115:10)
// here comes another <asynchronous suspension> followed by my code
E/flatter(16297):[错误:topaz/lib/tonic/logging/dart_ERROR.cc(16)]未处理的异常:
E/flatter(16297):平台异常(执行事务时出错,等待任务超时,空)
E/flatter(16297):#0 StandardMethodCodec.decodeEnvelope(包:flatter/src/services/message_编解码器。dart:547:7)
E/flatter(16297):#1 MethodChannel.invokeMethod(包:flatter/src/services/platform_channel.dart:279:18)
E/颤振(16297):
E/flatter(16297):#2 Firestore.runTransaction(file:///G:/flutter/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.7.3/lib/src/firestore.dart:115:10)
//接下来是我的代码

这是安卓系统提供的。

这项功能没有任何问题:

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

Future<void> main() async {
  final FirebaseApp app = await FirebaseApp.configure(
    name: 'yourappname',
    options: const FirebaseOptions(
      googleAppID: 'yourgoogleid',
      gcmSenderID: 'yourgmssenderid',
      apiKey: 'yourapikey',
      projectID: 'yourprojectid',
    ),
  );
  final Firestore firestore = Firestore(app: app);
  await firestore.settings(
  timestampsInSnapshotsEnabled: true,
  persistenceEnabled: true,
  sslEnabled: true
  );

  runApp(MaterialApp(
      title: 'Firestore Example', home: MyHomePage(firestore: firestore)));
}

class MessageList extends StatelessWidget {
  MessageList({this.firestore});

  final Firestore firestore;

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<QuerySnapshot>(
      stream: firestore.collection('messages').snapshots(),
      builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
        if (!snapshot.hasData) return const Text('Loading...');
        final int messageCount = snapshot.data.documents.length;
        return ListView.builder(
          itemCount: messageCount,
          itemBuilder: (_, int index) {
            final DocumentSnapshot document = snapshot.data.documents[index];
            return ListTile(
              title: Text(document['message'] ?? '<No message retrieved>'),
              subtitle: Text('Message ${index + 1} of $messageCount'),
            );
          },
        );
      },
    );
  }
}

class MyHomePage extends StatelessWidget {
  MyHomePage({this.firestore});
  final Firestore firestore;
  CollectionReference get messages => firestore.collection('messages');

  Future<void> _addMessage() async {
final DocumentReference postRef = firestore.document('posts/123');
firestore.runTransaction((Transaction tx) async {
  DocumentSnapshot postSnapshot = await tx.get(postRef);
  if (postSnapshot.exists) {
    await tx.update(postRef, <String, dynamic>{'likesCount': postSnapshot.data['likesCount'] + 1});
  }
});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Firestore Example'),
      ),
      body: MessageList(firestore: firestore),
      floatingActionButton: FloatingActionButton(
        onPressed: _addMessage,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}
导入'dart:async';
进口“包装:颤振/材料.省道”;
导入“包:firebase_core/firebase_core.dart”;
导入“包:cloud_firestore/cloud_firestore.dart”;
Future main()异步{
final FirebaseApp app=等待FirebaseApp.configure(
名称:“yourappname”,
选项:常量FirebaseOptions(
谷歌ID:“你的谷歌ID”,
gcmSenderID:“您的GMSSenderId”,
apiKey:“你的apiKey”,
projectID:“你的projectID”,
),
);
最终Firestore Firestore=Firestore(应用程序:应用程序);
等待firestore.settings(
SnapshotsEnabled的时间:对,
persistenceEnabled:true,
sslEnabled:对
);
runApp(材料应用程序)(
标题:“Firestore示例”,主页:MyHomePage(Firestore:Firestore));
}
类MessageList扩展了无状态小部件{
MessageList({this.firestore});
最终消防仓库消防仓库;
@凌驾
小部件构建(构建上下文){
返回流生成器(
流:firestore.collection('messages').snapshots(),
生成器:(BuildContext上下文,异步快照){
如果(!snapshot.hasData)返回常量文本('Loading…');
final int messageCount=snapshot.data.documents.length;
返回ListView.builder(
itemCount:messageCount,
itemBuilder:(\ux,int索引){
final DocumentSnapshot document=snapshot.data.documents[索引];
返回列表块(
标题:文本(文件[“消息”]??“,
字幕:文本($messageCount的Message${index+1}),
);
},
);
},
);
}
}
类MyHomePage扩展了无状态小部件{
我的主页({this.firestore});
最终消防仓库消防仓库;
CollectionReference获取消息=>firestore.collection('messages');
Future\u addMessage()异步{
最终文件参考postRef=firestore.document('posts/123');
firestore.runTransaction((事务发送)异步{
DocumentSnapshot postSnapshot=wait tx.get(postRef);
如果(postSnapshot.exists){
等待tx.update(postRef,{'likescont':postSnapshot.data['likescont']+1});
}
});
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
标题:常量文本(“Firestore示例”),
),
正文:消息列表(firestore:firestore),
浮动操作按钮:浮动操作按钮(
onPressed:\u addMessage,
工具提示:“增量”,
子:常量图标(Icons.add),
),
);
}
}

此错误有时会出现,因为:

  • 不要在事务运行时调试它,所以在它之前或之后将断点放在适当的行中

另一个错误是因为您没有:

  • 先完成所有的get呼叫,然后进行写入或更新

    正如Firestore文件所述:

    “读操作必须在写操作之前。”


我遇到的问题已经由
cloud\u firestore
团队解决

如果您仍然遇到类似的问题,您应该在这里询问StackOverflow或

注意:您还可以使用事务对数据进行原子更改。 虽然这对于增加投票总数来说有点过于严厉,但事实确实如此 应对更复杂变化的正确方法。这是一个多么有趣的故事啊 更新投票计数的事务可能如下所示

这是怎么回事?通过将读写操作包装在一个 事务,您告诉Cloud Firestore仅在以下情况下提交更改 基础数据没有外部更改,而 事务正在运行。如果两个用户没有同时投票 对于该特定名称,事务只运行一次。但是如果 transaction.get(…)和 transaction.update(…)调用,当前运行未提交,并且 将重试该事务。在5次失败的重试后,事务 失败了

来源

您是否试图获取不存在的文档?我曾经有过这个问题,因为我试图得到一个不存在的document@DavidHMoreno不,我的文件存在。
PlatformException
也会立即抛出,即不接触服务器。您也可以向上投票
onTap: () => Firestore.instance.runTransaction((transaction) async {

final freshSnapshot = await transaction.get(record.reference);

final fresh = Record.fromSnapshot(freshSnapshot);

await transaction

.update(record.reference, {'votes': fresh.votes + 1});

}),