Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

161
Views
React useState and Firebase onSnapshot

I want to automatically fetch new incoming messages from a firestore collection using onSnapshot. While I can set the state inside the callback, I cannot read it.

const [messages, setMessages] = useState(null);
const [chat, setChat] = useState(props.chatId);

useEffect(() => {
        const q = query(collection(db, "messages"), where("chat_id", "==", chat), orderBy("date","desc"), limit(5));
        // Create the DB listener
        const unsuscribe = onSnapshot(q, (querySnapshot) => {
            console.log(messages);
            if(messages === null){
                console.log("setting messages the first time");
                setMessages(querySnapshot.docs)
            }else{
                console.log("updating messages");
                setMessages([...querySnapshot.docs, ...messages])
            }
        });
        return () => {
            console.log("unsubscribe");
            unsuscribe();
        }
    }, [chat]);

Whenever onSnapshot fires, messages is always null but setMessages works since the messages are displayed. I tried so many approaches but I could not get it to work.

Help much appreciated.

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

So I managed to find a solution. The trick is to listen for state changes of messages with useEffect()

const [snapShot, setSnapshot] = useState(null);
const [messages, setMessages] = useState(null);
const [chat, setChat] = useState(props.chatId);

useEffect(() => {
        const q = query(collection(db, "messages"), where("chat_id", "==", chat), orderBy("date","desc"), limit(5));
       
        const unsuscribe = onSnapshot(q, (querySnapshot) => {
            setSnapShot(querySnapshot)
        });
        return () => {
            unsuscribe();
        }
    }, [chat]);

useEffect(() => {
  if(messages === null){
                console.log("setting messages the first time");
                setMessages(snapShot.docs)
            }else{
                console.log("updating messages");
                setMessages([...snapShot.docs, ...messages])
            }
    }, [snapShot]);
about 4 years ago · Juan Pablo Isaza Report

0

did you try this from the documentation

const q = query(collection(db, "cities"), where("state", "==", "CA"));
const unsubscribe = onSnapshot(q, (snapshot) => {
  snapshot.docChanges().forEach((change) => {
    if (change.type === "added") {
        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());
    }
  });
});

Also the question is a bit confusing on what you want to achieve

about 4 years ago · Juan Pablo Isaza Report

0

The querySnapshot you get from Firestore always contains all snapshots that match the query, not just the changed/new documents.

So your onSnapshot handler can be much simpler:

const unsubscribe = onSnapshot(q, (querySnapshot) => {
    setMessages(querySnapshot.docs)
});

So: every time you get notified by Firestore that the data in q has changed, you pass the data on to the state/UI for rendering.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!