[英]Firestore document is read multiple times after a single update in Firebase emulator
I am using Firestore to save users data.我正在使用 Firestore 来保存用户数据。 Each user in my app has a stream that listens to the user's document.我的应用程序中的每个用户都有一个 stream 来收听用户的文档。 I am running Firestore emulator and noticed that SOMETIMES after the user document is updated, document is read twice or more.我正在运行 Firestore 模拟器并注意到有时在更新用户文档后,文档被读取两次或更多次。 I have attached an image from the Firestore emulator that shows that.我附上了一张来自 Firestore 模拟器的图片来显示这一点。 Is there a reason why I am getting multiple reads after a single update.为什么我在一次更新后获得多次读取是有原因的。 I am not doing any read to the user document outside the stream.我没有对 stream 之外的用户文档进行任何读取。
I am using Flutter mobile app for watching the user document ".snapshots()".我正在使用 Flutter 移动应用程序观看用户文档“.snapshots()”。 The print statement in this code prints only one read.此代码中的 print 语句仅打印一次读取。 But if I am reading the user document only in the stream, then how do I end up with 2 reads in the emulator?但是,如果我只读取 stream 中的用户文档,那么我如何在模拟器中以 2 次读取结束?
Stream<MyProfile?> watchMyProfile() {
return _firestore
.doc(PathService.user(uid))
.withConverter<MyProfile>(
fromFirestore: (snapshot, _) {
return MyProfile.fromJson(snapshot.data()!);
},
toFirestore: (myProfile, _) => myProfile.toJson(),
)
.snapshots()
.map((doc) => doc.data())
.map(
(myProfile) {
// THIS ONLY PRINTS ONCE.
debugPrint('watchMyProfile - read my profile');
return myProfile;
},
);
}
UPDATE 1: To make sure that I am not reading any user document after update in firestore.rules file, I used something like this:更新 1:为了确保在更新 firestore.rules 文件后我没有阅读任何用户文档,我使用了如下内容:
allow update: if true;
allow get: if true;
allow list: if true;
Unfortunately, I am still seeing lots of reads after an update to the user document.不幸的是,在更新用户文档后,我仍然看到很多阅读。
I have reproduced the issue at my end and found the same behavior.我在最后重现了这个问题并发现了相同的行为。 As you can see in the image provided, reads have increased significantly.正如您在提供的图像中看到的那样,读取量显着增加。
This is due to constructing the stream inside a stream. It will get re-created on each call to build(), up to 60 times per second if there's an animation on the page.这是由于在 stream 中构建了 stream。如果页面上有 animation,它将在每次调用 build() 时重新创建,每秒最多 60 次。
I recommend you to construct the stream in a private variable then use it in the stream so it will not get re-created on each build method and will be called only once.我建议您在私有变量中构造 stream,然后在 stream 中使用它,这样它就不会在每个构建方法上重新创建,并且只会被调用一次。
Something like this像这样的东西
class SomeClass extends State<Some_State>{
final Stream<MyProfile> _usersStream =
FirebaseFirestore.instance.collection('users').doc('ABC123').snapshots();
@override
Widget build(BuildContext context) {
return StreamBuilder<MyProfile>(
stream: _usersStream,
builder: (context, snapshot) {
//…
}
}
For reference, Real time updates on a document is done by StreamBuilder as shown in here作为参考,文档的实时更新由 StreamBuilder 完成,如此处所示
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.