watersheep23
watersheep23

Reputation: 369

Implementing multiple Firestore calls at different times within useEffect React hook

useEffect(async() => {
await getWord();
const interval = setInterval(() =>{
time2 = time2 - 1;
        if (time2 == 0) {
clearInterval(interval);
          let dataURL = canvasRef.current.toDataURL();
          const db = firebase.firestore();
          db.collection("rooms").where("code", "==", code).get().then((querySnapshot) => {
            querySnapshot.docs.forEach((snapshot) => {
              snapshot.ref.collection("rounds").where("round", "==", round).get().then((querySnapshot) => {
                querySnapshot.docs.forEach((snapshot) => {
                  snapshot.ref.collection("pictures").add({artist: name, dataURL: dataURL, votes: 0}).then(() => {
                    setVoteTime2(true);
                  });
                });
              });
            });
          });
        }
    }, 1000);
}, []);

I am getting error with above useEffect hook. getWord is a function that implements a firestore call. The error is: "TypeError: n is not a function" and it's involving the firestore function that occurs in getWord, and the firestore call that occurs if time2 == 0. How can I get both asynchronous calls to occur, with obviously the firestore call that takes place inside getWord occurring before the call when time2 == 0? Please let me know if more info is needed! I just don't understand how using await is not solving this issue.

Upvotes: 1

Views: 200

Answers (1)

Mukul Kumar Jha
Mukul Kumar Jha

Reputation: 1082

You cannot pass async function as callback inside the useEffect hook because it returns Promise which is not allowed. Simply try calling your function in the useEffect (but don't define the callback function as async itself), and inside that function perform your asynchronous tasks...

useEffect(() => {

    // call your function
myAsyncFunc(); <--- Here
    
async function myAsyncFunc () => {
await getWord();
const interval = setInterval(() =>{
time2 = time2 - 1;
        if (time2 == 0) {
clearInterval(interval);
          let dataURL = canvasRef.current.toDataURL();
          const db = firebase.firestore();
          db.collection("rooms").where("code", "==", code).get().then((querySnapshot) => {
            querySnapshot.docs.forEach((snapshot) => {
              snapshot.ref.collection("rounds").where("round", "==", round).get().then((querySnapshot) => {
                querySnapshot.docs.forEach((snapshot) => {
                  snapshot.ref.collection("pictures").add({artist: name, dataURL: dataURL, votes: 0}).then(() => {
                    setVoteTime2(true);
                  });
                });
              });
            });
          });
        }
    }, 1000);
}


}, []);

What it does is saves you from returning a Promise but still lets you perform all your async tasks

Upvotes: 1

Related Questions