如何在Reactjs中监听Firebase实时更改?

5
我正在使用Firebase和React js创建实时聊天应用程序。我在Firebase中创建了一个名为“chats”的const函数,该集合包含唯一的room_ID(发送者和接收者的组合),该文档再次包含名为“messages”的子集合。消息内的每个集合都包含诸如消息、时间、sender_id和已读状态等信息。
现在,每当我收到聊天列表中的新消息时,我都必须更新对话。我使用ReactjscomponentDidMount()方法,并编写以下代码:
firestore.collection('chats').doc("b7EuhNpdzXUlxhSgDkn2a6oReTl1_OZbrlH8FjmVFqSAtAc0A6TUHS3I3").collection("messages")
.onSnapshot(querySnapshot => {
  console.log("querySnapshot", querySnapshot)
  querySnapshot.docChanges().forEach(change => {
    console.log("change", change)
    if (change.type === 'added') {
      this.setState({messages : [...this.state.messages, change.doc.data()]});
      console.log('New city: ', change.doc.data());
    }
    if (change.type === 'modified') {
      console.log('Modified city: ', change.doc.data());
    }
    if (change.type === 'removed') {
      console.log('Removed city: ', change.doc.data());
    }
  });
});

你可以看到,它只适用于单个房间(b7EuhNpdzXUlxhSgDkn2a6oReTl1_OZbrlH8FjmVFqSAtAc0A6TUHS3I3)。我希望以这样的方式编写查询,使其能够监听每个联系人的消息。为此,我必须删除特定文档的限制。
请帮帮我。
提前致谢。

enter image description here

这是Firebase数据库的结构。

enter image description here

enter image description here


我发现你描述的 Firebase 结构有点令人困惑,能否分享一个截图或树形结构的表示方式来更好地展示它是什么样子的?另外,从我的理解来看,你想要监视房间子集合中每个文档的变化,这是正确的吗? - Ralemos
@ralemos 是的,你说得对。 - Shivani Sonagara
好的,那你能分享一下你的Firestore结构的截图或树形表示吗?这样我们才能帮你创建一个合适的监听器。 - Ralemos
我已经添加了我的Firebase结构的截图。 - Shivani Sonagara
3个回答

2

查看CollectionGroups的文档 - 将监听器设置为.collectionGroup("messages") - 您将需要处理所有不同的“chats”文档的更改。 (提示:每个返回的messages DocRef包括refPath字段 - 您可以轻松解析以找到“parent” chat文档的路径)


谢谢您的回复。我还有一个问题。目前,我的Firebase监听器每次我重新加载页面以获取之前添加的数据时都会被调用。我能否对其设置时间限制,以便在我重新加载页面时接收实时更新? - Shivani Sonagara
1
你现在所询问的并不是监听器 - 你只是想要每次重新加载页面时检索文档。这与监听器毫无关系 - 监听器是一种异步事件,它会在每次更改时向您发送查询结果 - 所以您不必重新加载页面 - LeadDreamer

2

我相信获取所需数据的几种更好的方法是:

  • Restructure your Firestore to have only a messages collection, like the following example structure:

    messages collection
        uid
        receiverUserId
        senderUserId
        msg
        read
        time
    

使用这种方法,您可以过滤您正在观看的文档,例如从多个用户接收到的当前认证用户的文档,可以执行以下操作:

firestore.collection("messages")
  .where("receiverUserId", "==", authUid)
  .onSnapshot(function(querySnapshot) {
     //do whatever
});
  • Create multiple listeners, one for each chats document, to watch it's subsequent messages subcollection. So you could do something like this untested code:

    firestore.collection('chats').get().then(function(querySnapshot) {
      querySnapshot.forEach(function(doc) {
          var eachChatRef = firestore.collection('chats').doc(doc.documentID)
          var messagesRef = eachChatRef.collection("messages");
          messagesRef.onSnapshot(function(snapshot) {
              snapshot.docChanges().forEach(function(messageDoc) {
                  // Do whatever
              });
          });
      });
    });
    

抱歉,但正如我之前所说 - 是的,您可以使用“CollectionGroups”查询所有同名子集合,就好像它们是单个顶级集合一样 - LeadDreamer
我认为由于某些原因,集合组在这种情况下不适用,我会调整我的答案,感谢您指出。 - Ralemos

0

为了扩展@LeadDreamer的答案,这对我来说是有效的,可以使用collectionGroup来监听集合中所有文档的更改:

const unsub = () =>
  onSnapshot(collectionGroup(db, "reservations"), (doc) => {
    doc.docs.forEach((d) => {
      console.log(d.data());
    });
  });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接