[英]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.