对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了,所以欢迎提出任何想法。
是否可以从StreamBuilder
返回由2个单独的文档组成的自定义对象/地图,或者有其他方法可以在我的情况下使用。
答案 0 :(得分:1)
您当然可以使用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*/;
},
),