0

So I'm trying to use React Query with Firestore and usually this works pretty fine but recently I have been unable to make a function that returns a value.

const fetchProduct = async () => {
  const querySnapshot = await getDocs(collection(db, "notes"));
  const arr = [];
  querySnapshot.forEach((doc) => {
      setNotes(doc.data())


  }).catch((error) => {
      console.log(error);
      return null;
  });

  return notes
}

I'm later trying to use this function with React Query like this -

const { isLoading, isError, data, error } = useQuery(['todos'], fetchProduct)

However the value of the {data} always return to undefined but however once the fetchProduct() function is called manually it all works.

Is there anything I'm missing or doing wrong?

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Kentrell Jr
  • 197
  • 1
  • 15

2 Answers2

0

Setting the state is an asynchronous operation in React (see docs), so the value of notes isn't set yet by the time your return notes runs.

If you want to return the value synchronously:

return querySnapshot.docs.map((doc) => doc.data());

More typically though, you'll want to put the code that depends on that return value into its own useEffect hook that depends on the notes state.

Also see:

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Honestly, I dont have to set state, I tried it cause nothing else was working. I just want the async function to return a value which will be then handled by React Query. However I'm unable to make an async function that just returns the `doc.data()` so far. – Kentrell Jr Jul 24 '22 at 15:02
  • I tried `return querySnapshot.docs.map((doc) => doc.data());` however it doesn't work either. – Kentrell Jr Jul 24 '22 at 15:05
  • "it doesn't work" is incredibly hard to help with. I don't know anything about `useQuery`, but does it know how to deal with asynchronous data? – Frank van Puffelen Jul 24 '22 at 15:14
  • Yes it only accepts an async function that returns a value, – Kentrell Jr Jul 24 '22 at 15:15
0

It should be like this, you should not set inside the foreach function

const fetchProduct = async () => {
  const querySnapshot = await getDocs(collection(db, "notes"));
  const notes = [];
  querySnapshot.forEach((note) => {
    notes.push({ ...note.data(), id: note.id })
  }).catch((error) => {
      console.log(error);
      return null;
  });
  return notes;
}

// in the place of the calling the function
const notes = await fetchProduct();
setNotes(notes);

Note: don't use variable name as doc in foreach, instead use some other variable name like since doc is built in function of firebase you might have imported it