【问题标题】:streaming and transforming a Firestore document snapshots() stream流式传输和转换 Firestore 文档快照()流
【发布时间】:2021-04-02 20:30:39
【问题描述】:

我正在尝试从 Firestore 获取文档流,以在我的存储库中提取其中一个字段并将该字段流式传输到我的 bloc。我为此使用return orderBriefDoc.snapshots().map((snapshot) {

但是,在第一次调用时,没有执行内部映射指令,而是收到类型不匹配 type '_MapStream<DocumentSnapshot, dynamic>' is not a subtype of type 'Stream<List<OrderBrief>>'。我不明白为什么.map() 方法的返回类型不依赖于我在它的return 语句中返回的内容以及为什么不执行这个内部代码。

首先,我使用了待办事项列表的Felix Angelov的Firebase认证蚂蚁的repository功能作为蓝图:

Stream<User> get user {
    return _firebaseAuth.authStateChanges().map((firebaseUser) {
      return firebaseUser == null ? User.empty : firebaseUser.toUser;
    });
}

Stream<List<Todo>> todos() {
  return todoCollection.snapshots().map((snapshot) {
    return snapshot.documents
        .map((doc) => Todo.fromEntity(TodoEntity.fromSnapshot(doc)))
        .toList();
  });
}

我的改编是这样的

@override
Stream<List<OrderBrief>> orderBriefs() {
  if (orderBriefDoc == null)
    getOrderCollection();
  return orderBriefDoc.snapshots().map((snapshot) {
    final tmp = snapshot;
    print ("2");
    final tmp2 = snapshot.data()['orderBriefs'];
    print("3");
    return snapshot.data()['orderBriefs'].map((orderBrief) {
      final tmp=orderBrief;
      final tmp2 = OrderBriefEntity.fromMap(orderBrief);
      final tmp3 = OrderBrief.fromEntity(tmp2);
      return tmp3;
    }).toList();
  });
}

由于某种原因,第一次调用时没有打印“2”和“3”,并且由于类型不匹配,应用程序执行失败。所以在我的函数orderBriefs() 中,我返回.map() 流的.map()。映射的值,因此再次映射单个文档snapshot 以提取orderBriefs 字段。这个字段是从一个存储实体类OrderBriefEntity转化为我的业务逻辑类OrderBrief。转换结果是最终的返回值。因此,我希望函数 orderBriefs() 返回此转换结果的列表流。但是,会返回 _MapStream&lt;DocumentSnapshot, dynamic&gt;。为什么?

PS:这里指的是我的question,只是角度略有不同

【问题讨论】:

    标签: flutter google-cloud-firestore stream repository


    【解决方案1】:

    所以,我终于找到了一种流式传输 Firestore 单个文档的方法。我终于有了查找 Stream 文档的想法,并在那里找到了一个工作示例。为什么它不能像 Felix 那样只使用 map 方法,不知道。话虽如此,我仍然按照他的模式将快照转换为“实体”,然后进一步转换为 bloc 和 ui 使用的数据结构。

    我最终需要对文档的单个字段(嵌套数组)进行流式传输并流式传输整个文档

    (1) 流式传输文档的字段。

      @override
      Stream<List<OrderBrief>> orderBriefs() async* {
        if (orderBriefDoc == null)
          getOrderCollection();
        Stream<DocumentSnapshot> source = orderBriefDoc.snapshots();
        await for (var snapshot in source) {
          final List<OrderBrief> returnVal = snapshot.data()['orderBriefs'].map<OrderBrief>((orderBrief) {
            return OrderBrief.fromEntity(OrderBriefEntity.fromMap(orderBrief));
          }).toList();
          yield returnVal;
        }
      }
    

    (2) 流式传输包含所有字段的文档

      @override
      Stream<Order> orderStream(String orderId) async* {
        Stream<DocumentSnapshot> source = orderBriefDoc.collection('orders').doc(orderId).snapshots();
        await for (var snapshot in source) {
          final Order returnVal = Order.fromEntity(OrderEntity.fromSnapshot(snapshot));
          yield returnVal;
        }
      }
    

    如何巧妙地将其与 bloc 中的侦听器集成,您可以在 bloclibrary 的 Firestore ToDos example 中找到

    【讨论】:

      猜你喜欢
      • 2021-09-02
      • 2020-09-26
      • 2013-11-28
      • 2019-05-17
      • 1970-01-01
      • 2019-09-03
      • 1970-01-01
      • 1970-01-01
      • 2020-05-02
      相关资源
      最近更新 更多