将子集合添加到Firestore

时间:2020-10-31 11:27:33

标签: javascript google-cloud-firestore

我有一个简单的网络聊天应用,Firestore的架构如下所示

- chats (collection)
   - username
      - chats (collection)
         - ohterUsername
            - lastMessage: "hey"
            - lastUpdated: timestamp
            - username: otherUsername

            - messages (collection)
               - createdAt: timestamp
               - message: "hey"
               - from: username
               - to: otherUsername

我添加了两个字段lastUpdated, lastMessage来跟踪活动,以便为用户相应地订购聊天室。

            await firebase
            .firestore()
            .collection("chats")
            .doc(user.displayName)
            .collection("chats")
            .orderBy("lastUpdated", "desc")
            .limit(1)
            .get()
            .then(function (snapshot) {
              console.log(snapshot.docs);
              if (snapshot.docs.length > 0) {
                snapshot.docs.forEach(doc => {
                    const data = doc.data();
                    // get the user object who last messaged
                    console.log(data); 

                    // check if messages subcollection exists for this user,
                    // if yes, then retrieve the messages  
                    // if not, create it as empty collection so that it will be populated 
                    // when users exchange messages
                    firebase
                    .firestore()
                    .collection("chats")
                    .doc(user.displayName)
                    .collection("chats")
                    .doc(doc.data().username)
                    .collection("messages")
                    .orderBy("createdAt")
                    .get()
                    .then((snapshot) => {
                      snapshot.docs.forEach(doc => {
                        const data = doc.data();
                        console.log(data);
                      });
                    });
                });
            } else {
              console.log("nothing");
            }

对于该用户,没有messages子集合,我的问题是如何将其添加为空集合,以便在用户发送消息后填充它。

2 个答案:

答案 0 :(得分:1)

您不想创建一个空的子集合,这是一种反模式。

相反,当发送新消息时,请执行

await firestore
  .collection('chats')
  .doc(user.displayName)
  .collection('chats')
  .doc(recipient.displayName)
  .colleciton('messages')
  .add(messageData) // presuming message data contains document data for message

您可以在add method上查看文档。

这将创建一个新集合并同时生成它的第一个文档。这也有助于查询,您可以立即检查集合是否存在。


这也不在问题/答案的范围之内。但是我不建议您以这种方式保存邮件,因为

  1. Storage更适合保存用户生成的内容,尤其是如果您打算允许用户在不久的将来发送除纯文本消息之外的其他任何内容。

  2. 如果您决定坚持使用Firestore,则三个嵌套的子集合似乎非常多余,尤其是chats -> {userId} -> chats -> {recipientId} -> messages -> {messageId}。相反,您可以根据收件人ID将数据构造为单独的文档,即

    - chats/{userId}
       - messages/{recipientId}: {
           ...messageData
         }
    

    仅当用户可以与同一用户打开多个聊天室时,您建议的数据结构才有意义。

答案 1 :(得分:1)

集合/子集合不是Cloud Firestore中的具体资源,而只是组织文档和为这些文档创建的索引的隐式方法。换句话说,没有诸如空集合或子集合之类的东西。您必须创建一个“样本”或“虚拟”文档以使该集合存在。

您可以使用占位符文档创建子集合,然后在前端过滤掉该文档,因为它是第一个docs[0]

了解更多https://groups.google.com/g/google-cloud-firestore-discuss/c/o3tUFJpPYKc?pli=1