Home > Software engineering >  Why changes made in database not updates in realtime?
Why changes made in database not updates in realtime?

Time:09-18

I am trying to learn firestore realtime functionality.

Here is my code where I fetch the data:

useEffect(() => {
  let temp = [];
  db.collection("users")
    .doc(userId)
    .onSnapshot((docs) => {
      for (let t in docs.data().contacts) {
        temp.push(docs.data().contacts[t]);
      }

      setContactArr(temp);
    });
}, []);

Here is my database structure: enter image description here

When I change the data in the database I am unable to see the change in realtime. I have to refresh the window to see the change.

Please guide me on what I am doing wrong.

CodePudding user response:

Few issues with your useEffect hook:

  1. You declared the temp array in the way that the array reference is persistent, setting data with setter function from useState requires the reference to be new in order to detect changes. So your temp array is updated (in a wrong way btw, you need to cleanup it due to now it will have duplicates) but React is not detectign changes due to the reference to array is not changed.

  2. You are missing userId in the dependency array of useEffect. If userId is changed - you will continue getting the values for old userId.

  3. onSnapshot returns the unsubscribe method, you have to call it on component unMount (or on deps array change) in order to stop this onSnapshot, or it will continue to work and it will be a leak.

useEffect(() => {
  // no need to continue if userId is undefined or null 
  // (or '0' but i guess it is a string in your case)
  if (!userId) return;

  const unsub = db
    .collection("users")
    .doc(userId)
    .onSnapshot((docs) => {
        const newItems = Object.entries(
          docs.data().contacts
        ).map(([key, values]) => ({ id: key, ...values }));

        setContactArr(newItems);
    });

  // cleanup function
  return () => {
    unsub(); // unsubscribe
    setContactArr([]); // clear contacts data (in case userId changed)
  };
}, [userId]); // added userId
  • Related