As the title says. I'm using firestore for my chat service. I'm attempting to set up a way to filter out messages when the firestore updates
const users = useSelector((state) => state.assignUser);
const [messages, setMessages] = useState([]);
const chatID = 'KfM3GNxeVATi6sNFFUEG'
function getIDs(messageObj){
return messageObj.map(message => message._id)
}
useEffect(() => {
const messagesArray = []
db.collection('messages').doc(chatID).collection('messages').get().then(snapshot => {
snapshot.forEach(doc => messagesArray.push(doc.data()))
setMessages(messagesArray)
async function fetchMessages(){
const messageIDs = await getIDs(messages)
db.collection('messages').doc(chatID).collection('messages').onSnapshot(doc => {
doc.forEach((document) => {
if (messageIDs.indexOf(document.data()._id !== -1)) console.log('the is is ', messageIDs.indexOf(document.data()._id))
else console.log('notfoundssw')
})
})
}
fetchMessages()
})
}, [])
The await doesn't await the getIDs function and the log of messageIDs.indexOf(document.data()._id)
is -1 for every entry. I can't figure out why the async/await missbehaves
your messagesIDs
variable depends on messages state update, which does not happen sync. Based on your code structure you would have to break in 2 useEffects
. The first one that updates messages on mount and the second that listens to messages updates:
useEffect(() => {
const messagesArray = []
db.collection('messages').doc(chatID).collection('messages').get().then(snapshot => {
snapshot.forEach(doc => messagesArray.push(doc.data()))
setMessages(messagesArray)
})
}, [])
useEffect(() => {
// check if messages is not empty
if(!messages.length) return
const messageIDs = getIDs(messages) // your getIDs is not async, so no need to await
db.collection('messages').doc(chatID).collection('messages').onSnapshot(doc => {
doc.forEach((document) => {
if (messageIDs.indexOf(document.data()._id) !== -1) {
console.log('the is is ', messageIDs.indexOf(document.data()._id))
} else {
console.log('notfoundssw')
}
})
})
}, [messages])
Not sure I can fully understand how you're getting data, but setting state is actually asynchronous so you cannot guarantee all your state data is updated by the time you execute map
.
I would break up your useEffect
into two different ones.
The second one which will contain the fetchMessages
call should use 'messages' as part of its dependency array, ie it will execute once your 'messages' state has been updated.
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.