简体   繁体   English

如何听firebase实时变化成Reactjs?

[英]How to listen firebase real-time changes into Reactjs?

I am creating a real-time chat application using firebase and React js.我正在使用 firebase 和 React js 创建一个实时聊天应用程序。 I create a const functions = require('firebase-functions');我创建了一个 const functions = require('firebase-functions'); called " chats " inside the firebase.在 firebase 中称为“聊天”。 This collection contains unique room_ID (a combination of sender and receiver) and that document again contains subcollections called "messages".此集合包含唯一的room_ID (发送者和接收者的组合),并且该文档再次包含称为“消息”的子集合 Each collection inside the message has infomation like message, time, sender_id, and read status.消息中的每个集合都有消息、时间、sender_id 和读取状态等信息。

Now, every time, when I receive a new message into the chat list I have to update the conversation.现在,每次当我在聊天列表中收到新消息时,我都必须更新对话。 I use componentDidMount() method of Reactjs and write below code:我使用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());
    }
  });
});

You can see here that, It will only work for a single room(b7EuhNpdzXUlxhSgDkn2a6oReTl1_OZbrlH8FjmVFqSAtAc0A6TUHS3I3).您可以在此处看到,它仅适用于单个房间(b7EuhNpdzXUlxhSgDkn2a6oReTl1_OZbrlH8FjmVFqSAtAc0A6TUHS3I3)。 I want to write query in such a way that it will listen to the message for each contact.我想以这样一种方式编写查询,它会听取每个联系人的消息。 For that, I have to remove the restriction of specific doc.为此,我必须取消对特定文档的限制。

Please help me.请帮我。

Thank you in advance.先感谢您。

在此处输入图像描述

Here is the structure of Firebase database.这是Firebase数据库的结构。

在此处输入图像描述

在此处输入图像描述

I believe a few better approaches to fetch the data you want would be to either:我相信一些更好的方法来获取你想要的数据是:

  • Restructure your Firestore to have only a messages collection, like the following example structure:将您的 Firestore 重组为只有一个messages集合,如以下示例结构:

     messages collection uid receiverUserId senderUserId msg read time

With this approach you could filter the documents you are watching, for example documents received by the currently authenticated user from multiple users, by doing something like this:使用这种方法,您可以通过执行以下操作过滤您正在观看的文档,例如当前经过身份验证的用户从多个用户收到的文档:

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.创建多个侦听器,每个chats文档一个,以观察它的后续messages子集合。 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 }); }); }); });

Look into the documentation for CollectionGroups - set your listener to the.collectionGroup("messages") - you will have to process through the changes for all of the different "chats" documents.查看 CollectionGroups 的文档 - 将您的侦听器设置为 the.collectionGroup("messages") - 您将必须处理所有不同“聊天”文档的更改。 (HINT: each returned messages DocRef includes the refPath field - which you can trivially parse to find the path to the "parent" chat document) (提示:每个返回的消息 DocRef 都包含 refPath 字段 - 您可以轻松解析该字段以找到“父”聊天文档的路径)

To extend to @LeadDreamer answer, this worked for me to listen to changes in all documents in a collection using collectionGroup :要扩展到@LeadDreamer 答案,这对我来说可以使用collectionGroup收听集合中所有文档的更改:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM