首页 > 解决方案 > 如何从 Firestore 中的多层文档中获取字段

问题描述

我正在通过 React 和 Firebase 创建一个类似 Reddit 的网站,这是我的数据结构:

组 - 随机 uid - 讨论 - 随机 uid - subdiscussion-first - random-uid - subdiscussion - 第二 - random-uid ......等等。

我已经编写了代码来创建这样的结构。

    try {
      await FirebasePack
        .firestore()
        .collection('groups')
        .where('name', '==', group)
        .get()
        .then((querySnapshot) => {
          querySnapshot.forEach((doc) => {
            doc.ref.collection('discussions').doc().set({
              title: title,
              content: content,
              creator: creator,
              rating: 0,
              subdiscussions: 0,
              created_time: firebase.firestore.FieldValue.serverTimestamp()
            });    
          });
        });
    } catch (error) {
      console.log(error);
    }
    setPageLoading(false);
  };

我的问题是,当我要展示这样的东西时:

在此处输入图像描述 我真的需要重复模式来获得第四层或更深的字段吗?如果没有,我怎样才能更容易地得到它们?

标签: javascriptreactjsfirebasegoogle-cloud-firestore

解决方案


为每个嵌套回复创建子集合可能不是最好的方法,因为您的最大深度限制为 100个子集合。您可以创建一个子集合"messages"并将所有消息存储在其中。结构将是这样的:

groups -> {groupId} -> messages -> {messageId}
(col)       (doc)       (col)        (doc)

每个文档(消息)的结构可以是这样的:

{
  id: "msgID",
  author: "msg_author_id",
  replyTo: "GROUP_or_msgID",
  ...otherFields
}

在这里,每条消息都有一个字段replyTo,可以是它正在回复的消息的 ID,也可以是“GROUP”。如果replyTo是“GROUP”,则表示它是组中的直接消息,如果是 ID,则表示回复。

如何对这些消息进行分页完全取决于您的应用程序流程,即在开始时加载一些消息,如果用户请求则加载更多消息。例如,如果用户想要加载对 ID 为 1234 的消息的回复,您可以运行以下查询:

const msgRef = firebase.firestore().collection("groups").doc(groupID).collection("messages")

const replies = await msgRef.where("replyTo", "==", "1234").get()

console.log(replies.docs.map(reply => ({id: reply.id, ...reply.data()})))

推荐阅读