【问题标题】:Flutter StreamBuilder for multiple firebase documentsFlutter StreamBuilder 用于多个 firebase 文档
【发布时间】:2020-06-26 08:21:55
【问题描述】:

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 个独立文档组成的自定义对象/地图,或者是否有另一种方法适用于我的情况。

【问题讨论】:

    标签: firebase flutter dart


    【解决方案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*/;
            },
          ),
    

    【讨论】:

    • 我正在使用:cloud_firestore:^0.13.6。感谢您的帮助。
    猜你喜欢
    • 2023-01-12
    • 2021-10-22
    • 2021-10-15
    • 2021-09-30
    • 1970-01-01
    • 1970-01-01
    • 2020-12-14
    • 2021-09-13
    • 1970-01-01
    相关资源
    最近更新 更多