Home > Software design >  firebase data not being updated with use effect
firebase data not being updated with use effect

Time:04-27

hi i have to refresh my page to see the effect of the person adding an event to the calendar:

my code is

const handleDateClick = async (DateClickArg) => {
  if (DateClickArg) {
    const title = prompt("Enter title", DateClickArg.dateStr); // allows user to put a title in

    // making object
    const event = {
      title: title ? title : DateClickArg.dateStr,
      start: DateClickArg.date,
      allDay: true,
    };

    allEvents.push(event);

    const db = fire.firestore();
    let currentUserUID = fire.auth().currentUser.uid;
    const doc = await fire
      .firestore()
      .collection("userCalendar")
      .doc(currentUserUID)
      .get();

    db.collection("userCal/"   currentUserUID   "/activities").add({ event });
  }
};

and my getuserinfo is:

const getUserInfo = async () => {
  let currentUserUID = fire.auth().currentUser.uid;

  const qSnap = await fire
    .firestore()
    .collection("userCal")
    .doc(currentUserUID)
    .collection("activities")
    .get();

  const data = [];
  data = qSnap.docs.map((d) => ({
    id: d.id,
    title: d.data().event.title,
    start: d.data().event.start.toDate(),
    allDay: d.data().event.allDay,
    ...d.data(),
  }));

  //setData(data)
  console.log(data);
  setData([...data]);
};

useEffect(() => {
  let mounted = false;

  if (!mounted) {
    getUserInfo();
  }

  return () => {
    mounted = true;
  };
}, []);

where am i going wrong with my use effect? is there a way for the data to update in the browser once its added to firebase? i am using react full calendar

CodePudding user response:

Using get() only returns a point-in-time snapshot of your data. If you want to listen for realtime updates, use .onSnapshot() instead.

You'll also need to make sure you unsubscribe from updates when your component is cleaned up

useEffect(() => {
  const currentUserUID = fire.auth().currentUser.uid;

  return fire
    .firestore()
    .collection("userCal")
    .doc(currentUserUID)
    .collection("activities")
    .onSnapshot(({ docs }) => {
      setData(
        docs.map((doc) => {
          const data = doc.data();
          return {
            id: doc.id,
            title: data.event.title,
            start: data.event.start.toDate(),
            allDay: data.event.allDay,
            ...data,
          };
        })
      );
    });
}, []);

.onShapshot() returns an unsubscribe function so returning that from your effect hook will run it when your component is unmounted.

CodePudding user response:

Assuming your firebase call is ok, there is an error inside your useEffect call. You are setting the mounted variable wrong, it is supposed to be false when your component is destroyed and true after your component is rendered. Also, to avoid unexpected behaviors I highly recommend using the useRef hook to check that.

function Component() {
  const isMounted = useRef(false)

  useEffect(() => {
    isMounted.current = true;

    if (isMounted) {
      getUserInfo();
    }

    return () => { isMounted.current = false }
  }, []);

  ...
}

export default Component;
  • Related