简体   繁体   中英

How to listen firebase real-time changes into Reactjs?

I am creating a real-time chat application using firebase and React js. I create a const functions = require('firebase-functions'); called " chats " inside the firebase. This collection contains unique room_ID (a combination of sender and receiver) and that document again contains subcollections called "messages". Each collection inside the message has infomation like message, time, sender_id, and read status.

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:

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). 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.

在此处输入图像描述

在此处输入图像描述

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:

     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. 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. (HINT: each returned messages DocRef includes the refPath field - which you can trivially parse to find the path to the "parent" chat document)

To extend to @LeadDreamer answer, this worked for me to listen to changes in all documents in a collection using collectionGroup :

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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