当前位置: 首页 > 知识库问答 >
问题:

从FireStore中嵌套在文档中的集合中获取数据的最佳方法是什么?

邬宏扬
2023-03-14

他们推荐这种结构,但我看不出他们在哪里讨论有效地获取所有数据。

每个聊天文档都有属性、成员集合和消息集合:

    null
    null

Firestore查询很肤浅,有时可能很棒。我的理解是,没有一种根深蒂固的方法来查询深度和获取嵌套集合。那么,什么是最好的实践和最省事的方法来做到这一点呢?

目前,我正在检索快照并将其映射到带有ID的对象,并通过附加的查询和映射将嵌套的集合数据添加到父文档数据上,我对我的方法不满意,即使使用非规范化的Firebase结构也可以更快地完成这一过程。

这个代码示例只是在成员上进行映射,在消息中添加回来是另一回事...

getChatsFromFirestore() {
    this.chats = this.dataSvc.getChatsFromFirestore().snapshotChanges()
      .map(chatSnaps => {
        return chatSnaps.map(chat => {
          const chatData = chat.payload.doc.data();
          const chatId = chat.payload.doc.id;
          return this.dataSvc.getMembersForChat(chatId)
            .snapshotChanges()
            .map(memberSnaps => {
              return memberSnaps.map(member => {
                const data = member.payload.doc.data();
                const id = member.payload.doc.id;
                return { id, ...data }
              });
            })
            .map(members => {
              return { chatId, ...chatData, members: members };
            });
        })
      })
      .flatMap(chats => Observable.combineLatest(chats));
  }
getChatsFromFirestore() {
  return this.fsd.collection<any>('chats');
}
getChatFromFirestoreById(id: string) {
  return this.fsd.doc(`chats/${id}`);
}
getMembersForChat(chatId) {
  return this.getChatFromFirestoreById(chatId).collection('members');
}

共有1个答案

桓瀚
2023-03-14

您发布的方法似乎是可行的,对于一个大型聊天应用程序,您可能不想跟踪每个聊天室中发生的每一个事件,因为这可能是大量的数据。相反,最好只订阅需要的内容,并使用云函数和云消息处理定期更新。

通过使用helper函数observecollection以及小型代码重组,它将清理服务并为每个聊天室创建可观察项,这些可观察项在被订阅之前是不活动的。

class Service {
    // db is plan firestore / no angularfire
    db: firebase.firestore.Firestore;

    loadChatrooms() {
        const chatsRef = this.db.collection('chats');
        return observeCollection(chatsRef)
            .pipe(
                map(chats => {
                    return chats.map(chat => {
                        return {
                            chat,
                            members$: this.observeCollection(chat.ref.collection('members')),
                            messages$: this.observeCollection(chat.ref.collection('messages')),
                        };
                    })
                }),
            );
    }

    // Takes a reference and returns an array of documents
    // with the id and reference
    private observeCollection(ref) {
        return Observable.create((observer) => {
            const unsubscribeFn = ref.onSnapshot(
                snapshot => {
                    observer.next(snapshot.docs.map(doc => {
                        const data = doc.data();
                        return { 
                            ...doc.data(),
                            id: doc.id,
                            ref: doc.ref
                        };
                    }));
                },
                error => observer.error(error),
            );

            return unsubscribeFn;
        });
    }
}

在应用程序中,您只能观察当前选择的聊天室成员和消息,这将保存数据。由于这篇文章是用角标记的,异步管道将有助于通过自动、方便的订阅来进行切换。

this.currentChat$ = combineLatest(
  service.loadChatrooms(),
  currentlySelectedRoomId
).pipe(
    map(([chats, selectedRoomId]) => {
        return chats.first(chat => chat.id === selectedRoomId)
    })
);
<div *ngIf="currentChat$ as currentChat">
    {{ currentChat.name }}

    <div *ngIf="currentChat.members$ as members">
        <div *ngIf="let member of members">
          {{ member.name }}
        </div> 
    </div> 

    <div *ngIf="currentChat.messages$ as messages">
        <div *ngIf="let message of messages">
          {{ message.content }}
        </div> 
    </div> 
</div>
 类似资料:
  • 嗨,我从javascript和react-native开始,我花了几个小时试图解决这个问题。有人能告诉我如何从firestore收集处获得所有文件吗? 我一直在尝试这个: 日志1打印所有对象(一个接一个),但日志2没有定义,为什么?

  • 我如何删除一个特定的文档中的一个集合在fiRecovery使用反应? 我在这里和谷歌上看了看,但我没有发现任何内在相关的东西。 我只是设法从我的集合中删除索引[0]的文档。 这状态idDoc接收所有id文档。 如果我只是传递. doc(idDoc),我会得到以下错误: Firebase Error: Function Collection Reference.doc()要求它的第一个参数是非空字符

  • 问题内容: 我想从Firebase Firestore数据库获取数据。我有一个名为user的集合,每个用户都有一些相同类型的对象(My Java自定义对象)的集合。我想在创建我的活动时用这些对象填充ArrayList。 在onCreate()中: 调用以获取项目列表的方法: 问题答案: 该操作返回a ,这意味着它是一个 异步操作 。调用仅启动操作,它不等待操作完成,因此您必须添加成功和失败侦听器。

  • 在第一个屏幕截图中,集合用户中有许多文档。每个文档都包含进一步的集合jobPost,该集合包含进一步的文档及其元数据。 我在这里想要的是去收集用户的每个文档和进一步的子收集jobPost并获取所有文档。假设首先它应该转到集合用户中的文档1,在文档1中它应该获取子集合jobPost中的所有文档,然后它应该转到集合用户的第二个文档,然后获取子集合jobPost中的所有文档,等等。

  • 我试图设置一个聊天应用程序,在其中你可以搜索随机的用户交谈。现在,firestore中的数据库结构如下: 集合“users”-文档“userid”-集合“conversations”-文档“conversationid”-字段“partner”,“lastmessage” 其次,我有一个集合“conversations”,其中包含对话中的所有消息。 我现在尝试做的是,当你按下一个按钮时,应用程序将

  • 如何使用Spring FirestoreReactiveRepository从子集合中获取文档? 问题是:如何动态地将子集合名称或路径指定给@Document annotation? 我的firestore系列:(城市是一级系列,公寓是本系列的子系列) 波乔市 POJO公寓是: 从城市收集中获取数据的CityRepository 调用findById(nyc)时,公寓返回空值。我想在城市对象中填充