Firestore 单文档快照流未更新
Posted
技术标签:
【中文标题】Firestore 单文档快照流未更新【英文标题】:Firestore single document snapshot stream not updating 【发布时间】:2021-09-02 12:20:37 【问题描述】:我的 Flutter 应用程序需要监听特定 Firestore 文档中的任何更改。
这个过程非常简单,可以在各种解决方案中找到:
-
***: flutter-firestore-how-to-listen-for-changes-to-one-document
***:can-i-listen-to-a-single-document-in-firestore-with-a-streambuilder
***:using-stream-building-with-a-specific-firestore-document
***: how-to-get-a-specific-firestore-document-with-a-streambuilder
中等: how-to-get-data-from-firestore-and-show-it-on-flutterbuilder-or-streambuilder-e05
这些都是使用Stream
和StreamBuilder
并监听任何变化的解决方案。
通常使用这种方法:
Stream<UserModel?> getFirestoreUser(String uid)
return FirebaseFirestore.instance.collection('users').doc(uid).snapshots().map((event) => event.data()).map((event) => event == null ? null : UserModel.fromJson(event));
地点:
UserModel
有一个 fromJson(Map<String, dynamic>)
工厂构造函数
并且存在文档 ID 为 uid
的 users
集合。
Stream 返回一个Stream<UserModel?>
,以后可以由Provider.of<UserModel?>(context)
或StreamBuider<UserModel?>
使用
问题:
TL;DR - 在更新 Firestore().getCurrentUser(uid)
流后(直接或手动使用 Firestore 模拟器并更改文档值),下面的 StreamBuilder<UserModel?>
不会更新。
在应用程序生命周期的所有时间点(无论是否经过身份验证),流始终返回 null(但是使用 .first
手动调用流会返回用户内容,但 .last
只是挂起)。有关详细信息,请参见下文。
链接到github project。
开始:
-
将您自己的
gooogle-services.json
文件放入android/app
文件夹中
将com.flutterprojects.myapp
的所有引用更改为$your google-services.json package name
使用本地模拟器更新 Firestore 更改
更多详情:
我的问题使用了类似的方法,但 Stream
没有返回任何内容。我的 Flutter 小部件 LoggedIn()
在 FirebaseAuth.instance.currentUser
有效(即不为空)时使用
class LoggedIn extends StatelessWidget
@override
Widget build(BuildContext context)
// TODO: implement build
return StreamBuilder<UserModel?>(
builder: (context, snapshot)
print("Checking UserModel from stream provider");
if (snapshot.data == null)
print("UserModel is null");
return UiLogin();
print("UserModel is NOT null");
return UiHome();
,
);
验证成功后,文本Checking UserModel from stream provider
会打印到控制台,然后是UserModel is null
。 UserModel is NOT null
绝不会显示。
成功验证后(即用户注册和文档更新),我有一个按钮,我手动调用流并获取第一项:
var currentUser = Firestore().getCurrentUser(FirebaseAuth.instance.currentUser!.uid);
var first = await currentUser.first;
print(first);
根据新增的用户信息返回UserModel
。
运行以下代码时,在.last
处停止执行,没有错误,没有崩溃,没有应用退出,只是停止执行。
var currentUser = Firestore().getCurrentUser(FirebaseAuth.instance.currentUser!.uid);
var last = await currentUser.last;
print(last);
但是
添加以下内容时,所有更改都会更新并打印到控制台
Firestore().getCurrentUser(currentUid).listen((data)
print("Firestore Data Changed");
print("Firestore change value: $data");
);
这意味着StreamBuilder<UserModel?>
无法正常工作,因为Stream<UserModel>
事件执行listen()
更改并确认这些更改,但StreamBuilder<UserModel?>
更改不会受到影响并始终返回null
。
我是不是做错了什么?
【问题讨论】:
您是否在 StreamBuilder 中添加了stream:
参数?
【参考方案1】:
试试if (snapshot.hasData) print("UserModel is null"); return UiLogin();
【讨论】:
snapshot.hasData
是一个美化的 snapshot.data != null
检查我已经在做的检查,请参阅 api.flutter.dev/flutter/widgets/AsyncSnapshot/hasData.html。这有什么帮助?【参考方案2】:
这对我有用。也许连接状态是缺失的。
StreamBuilder(
stream: FirebaseFirestore.instance
.collection('users')
.doc(widget.uid)
.collection('contacts')
.doc(widget.client)
.collection('messages')
.orderBy('timestamp', descending: true)
.snapshots(),
builder: (context, snapshot)
if (snapshot.hasError)
return Expanded(
child: Center(child: Text('Problem Getting Your Messages')),
);
switch (snapshot.connectionState)
case ConnectionState.none:
return Text('waiting');
case ConnectionState.waiting:
return Center(child: Text('Waiting'));
case ConnectionState.active:
var snap;
print('active');
if (snapshot.data != null)
snap = snapshot.data;
return Expanded(
child: ListView(
...
);
case ConnectionState.done:
print('done');
return Text('Lost Connection');
return Text('NOPE');
,
),
【讨论】:
以上是关于Firestore 单文档快照流未更新的主要内容,如果未能解决你的问题,请参考以下文章
添加新文档时,kotlin firestore 未更新我的 android 应用程序
Google Firestore 是缓存文档和集合还是总是请求新的?