简体   繁体   中英

Data from firestore doesn't get fetched in realtime in useEffect

I am currently coding a chatting app with React Native and Expo, but at the point at receiving the messages in RealTime (If Message gets updated, delted or edited), but it doesn't do it in realtime, it fetches the data if i open the page for the chat, but after that it doesn't update anymore

Receiving messages:

const [Messages, setMessages] = useState([]);
var TmpMessages = [];

useEffect(() => {
    const messages = () => { 
      firebase.firestore().collection('Users').doc(`${user.uid}`).collection('Friends')
      .doc(`${data.Friend.FriendId}`).collection('Messages').orderBy('Index').onSnapshot(ss => {
        var changes = ss.docChanges();

        // Parsing the messages
        for (var i = 0; i < changes.length; i++) {
            const message = changes[i].doc.data();
            if (changes[i].type == 'added') {
              if (i == 0) message.BeforeAt = 'first message';
              if (message.Sender == user.uid) {
                if (i > 0) {
                  var beforeMessage = changes[i - 1].doc.data();
                  message.BeforeAt = beforeMessage.SendAt;
                  if (beforeMessage.Sender == user.uid) {
                    message.Type = 'SenderBottom';
                  } else {
                    message.Type = 'Sender';
                  }
                } else {
                  message.Type = 'Sender';
                }
              } else {
                if (i > 0) {
                  var beforeMessage = changes[i - 1].doc.data();
                  message.BeforeAt = beforeMessage.SendAt;
                  if (beforeMessage.Sender == data.Friend.FriendId) {
                    message.Type = 'ReceiverBottom';
                  } else {
                    message.Type = 'Receiver';
                  }
                } else {
                  message.Type = 'Receiver';
                }
              }
              TmpMessages.push(message);
            } else if (changes[i].type == 'removed') {
              for (var k = 0; k < TmpMessages.length; k++) {
                if (TmpMessages[k].Id == message.Id) {
                  console.log(message.Id + ' got deleted')
                  TmpMessages.splice(k, 1);
                }
              }
            } else if (changes[i].type == 'updated') {
              for (var k = 0; k < TmpMessages.length; k++) {
                if (TmpMessages[k].Id == message.Id) {
                  console.log(message.Id + ' got updated')
                  TmpMessages[k].Message = message.Message;
                }
              }
            }
          }
          
          setMessages(TmpMessages);
      });
    }

    // Unsubscribe from events when no longer in use
      return () => messages();
  }, []);

And this is my FlatList:

<FlatList
   style={{ marginBottom: 60, }}
   renderItem={({ item }) => {
      return (
         <ChatItem MessageData={{
            content: item.Message,
            beforeSendAt: item.BeforeAt,
            sendAt: item.SendAt,
         }} MsgType={item.Type} />
      );
   }}
   data={Messages}
   extraData={Messages}
   keyExtractor={(item, index) => index.toString()}
/>

Edit: If I don't put my Firebase event listener in an useEffect, then it does an infinite loop an eventually crashes.

Edit 2: Don't blame me for my unifficient code for parsing the messages, right now it is only prove of concept

I would recommend to use the whole result each time something changes. Like here:

db.collection("cities").where("state", "==", "CA")
    .onSnapshot((querySnapshot) => {
        var cities = [];
        querySnapshot.forEach((doc) => {
            cities.push(doc.data().name);
        });
        console.log("Current cities in CA: ", cities.join(", "));
    });

instead of ss.docChanges() . Just loop over all messages. You add them anyway as a whiole to the state with setMessages(TmpMessages); . That way you don't need to bother with all the changes. With .data() you just get all of them if anything changes.

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