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});
}),