Firestore 事务不起作用



我发现了一些问题线程,人们也无法完成交易,但它甚至没有提供解决方案

问题

突然,我的交易在使用transaction.get时崩溃了。

runTransaction(
(Transaction transaction) async {
await transaction.get(documentReference); // "Timed out waiting for Task"
}

PlatformException也没有真正帮助我,因为它在platform_channel崩溃了......

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

这来自安卓

此错误有时是因为:

  • 不要在事务运行时对其进行调试,因此请在事务之前或之后将断点放在适当的行中。

另一个错误来了,因为你没有:

  • 先接听电话,然后你的写入或更新来了。

    正如Firestore文档所说:

    ">读取操作必须先于写入操作。">

https://firebase.google.com/docs/firestore/manage-data/transactions#transactions

我遇到的问题已经由cloud_firestore团队修复。

如果您仍然遇到类似的问题,您应该在StackOverflow上提出问题或创建一个问题。

注意:您还可以使用事务对数据进行原子更改。 虽然这对于增加投票总数来说有点沉重,但它是 适用于更复杂的更改的正确方法。这是 更新投票计数的事务可能如下所示。

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

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

来源https://codelabs.developers.google.com/codelabs/flutter-firebase/index.html#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),
),
);
}
}

最新更新