firebase - Flutter StreamBuilder 用于多个 firebase 文档
问题描述
usersCollection.document(user.uid)
当对firebase 文档进行更改时,我正在尝试更新我的 Flutter 应用程序。
当用户文档更新时,我想从这个文档中检索数据,也从另一个 firebase 文档中检索数据,facilitiesCollection.document(...)
.
我当前的代码
Future<Map> _getCheckedInFacilityData() async {
Map<String, dynamic> result = {};
try {
DocumentSnapshot userDoc =
await _db.usersCollection.document(user.uid).get();
if (userDoc.data['checkedIn']) {
// User is checked in
DocumentSnapshot facDoc = await _db.facilitiesCollection
.document(userDoc.data['activeFacilityID'].toString())
.get();
result['facilityID'] = userDoc.data['activeFacilityID'];
result['sessionID'] = userDoc.data['activeSessionID'];
result['facilityActiveUsers'] = facDoc.data['activeUsers'].length;
result['facilityName'] = facDoc.data['name'];
return result;
}
} catch (er) {
debugPrint(er.toString());
}
return null;
}
FutureBuilder<Map>(
future: _getCheckedInFacilityData(),
builder: (context, map) {
switch (map.connectionState) {
case ConnectionState.waiting:
return Center(child: CircularProgressIndicator());
...
这目前正在运行,但是当对用户文档进行更改时,页面不会更新。我很久没有使用 Flutter/Dart,所以欢迎任何想法。
是否可以返回一个自定义对象/地图,该对象/地图由 2 个单独的文档组成StreamBuilder
,或者是否有另一种方法适用于我的情况。
解决方案
当然,您可以使用 Streams asyncMap() 来完成,然后在 StreamBuilder 中收听
基本算法
获取第一个数据类型的流,然后获取 asyncMap 以等待第二个数据类型并将它们都返回
stream.asyncMap(
(v1) async {
final v2 = await Future.delayed(Duration(seconds: 1), () => 4);
return v1 * v2;
},
);
更接近您的代码
Stream<Map<String, dynamic>> _getCheckedInFacilityData() {
return _db.usersCollection.document(user.uid).snapshots()
.asyncMap(
(userDoc) async {
final DocumentSnapshot facDoc =
await _db.facilitiesCollection
.document(userDoc.data['activeFacilityID'].toString())
.get();
final Map<String, dynamic> userMap = userDoc.data;
final Map<String, dynamic> facMap = facDoc.data;
return userMap..addAll(facMap);
},
);
}
在这个函数中,我合并了两个映射 - 如果两个映射具有相同的键映射将只保留最后一个在我们的例子中添加的键addAll(facMap)
最后一步是在屏幕上显示流数据 - 使用StreamBuilder
StreamBuilder<Map>(
stream: _getCheckedInFacilityData(),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Text('${snapshot.error}');
} else if (snapshot.connectionState == ConnectionState.waiting) {
return LinearProgressIndicator();
}
return /* some widget that shows your data*/;
},
),
推荐阅读
- algorithm - 如果输入数组中的每个项目最多有 10 个位置错位,那么插入排序的运行时间是多少?
- okta - Okta SAML - 停顿会话
- javascript - 在路径 Javascript 中使用变量
- c# - 简单的 .net 核心应用程序不会在 linux 上构建
- google-apps-script - 我的 MailApp 不会发送任何电子邮件 GoogleScript
- makefile - 目标依赖:Makefile no rule to make target 错误
- c++ - 如果相同的数字重复,如何比较流中的数字
- python-3.x - 删除嵌套列表python中特定项目之后的所有项目
- php - php7.4、php7.4-fpm、http2、Apache、nginx,我一头雾水
- sql - 检索值中两个句点之间的文本