簡體   English   中英

來自 firestore 的數據不會在 useEffect 中實時獲取

[英]Data from firestore doesn't get fetched in realtime in useEffect

我目前正在使用 React Native 和 Expo 編寫一個聊天應用程序,但是在實時接收消息時(如果消息被更新、刪除或編輯),但它不是實時執行的,如果我打開聊天頁面,但之后它不再更新

接收消息:

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();
  }, []);

這是我的 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()}
/>

編輯:如果我不將我的 Firebase 事件偵聽器放在 useEffect 中,那么它會無限循環並最終崩潰。

編輯 2:不要因為我解析消息的代碼效率低而責怪我,現在它只是概念的證明

我建議每次發生變化時都使用整個結果。 像這兒:

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(", "));
    });

而不是ss.docChanges() 只需循環所有消息。 您無論如何都可以使用setMessages(TmpMessages);將它們添加到狀態中setMessages(TmpMessages); . 這樣你就不需要為所有的變化而煩惱了。 使用.data()如果有任何變化,你就可以得到所有這些。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM