EN VI

Firebase - Can not get onSnapshot to render once. It duplicates?

2024-03-12 12:00:06
Firebase - Can not get onSnapshot to render once. It duplicates

i'm working on a project with React and Firestore. I'm working on a page which will read through multiple images and certain fields of these images will be changed. Once changes are made, i just want the one image doc to update rather than everything on the page hence onSnapshot. The onSnapshot listener keeps adding on to the images that i have whenever changes are made. I understand that everytime useEffect is called it adds the same images but i don't know how to fix it. I have seen some solves here but they don't cater to the IDs array which i need to reference a document when making changes to it.

export default function Images({ user }) {
  const [images, setImages] = useState([]);
  const [ids, setIDs] = useState([]);

  useEffect(() => {
    const colRef = collection(db, "images");
    const q = query(colRef, where("user", "==", user));

    onSnapshot(q, (snapshot) => {
      snapshot.docs.forEach((doc) => {
        setImages((prev) => [...prev, doc.data()]);
        setIDs((prev) => [...prev, doc.id]);
      });
    });
  }, [user]);

  return (
    <>
      {images && (
        <div className="m-4 grid grid-cols-2 grid-flow-row">
          {images.map((image, index) => {
            const imageID = ids[index];
            return <Labels image={image} imageID={imageID} />;
          })}
        </div>
      )}
    </>
  );
}

Any insights will be appreciated.

Solution:

Have a look at the link you attached in your question: Why is onSnapshot duplicating my records in REACT? - The answer should be exactly what you want.

The issue here is that you're using [...prev, doc.data()] no? This will cause the array to keep adding up everytime snapshot changes. What you can do instead is to map through the snapshot.docs and then get the results and set it as your state as such:

  useEffect(() => {
    const colRef = collection(db, "images");
    const q = query(colRef, where("user", "==", user));

    onSnapshot(q, (snapshot) => {
      const docs = snapshot.docs;
      setIDs(docs.map(doc => doc.id);
      setImages(docs.map(doc => doc.data());
    });
  }, [user]);
Answer

Login


Forgot Your Password?

Create Account


Lost your password? Please enter your email address. You will receive a link to create a new password.

Reset Password

Back to login