我的 Flutter 应用程序需要监听特定 Firestore 文档中的任何更改。
这个过程非常简单,可以在各种解决方案中找到:
这些都是使用 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>)
工厂构造函数users
的 uid
集合。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}
更多详情:
我的问题使用了类似的方法,但 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
。
我做错了吗?
答案 0 :(得分:0)
试试if (snapshot.hasData) { print("UserModel is null"); return UiLogin(); }
答案 1 :(得分:0)
这对我有用。也许缺少连接状态。
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');
},
),