FirebaseError, Quota exceeded

FirebaseError, Quota exceeded

Hey there,

Let me tell you today regarding how not to program infinite loop in reactjs.

Finding


Yesterday I was trying to make a Reddit clone in ReactJS with a database from firebase firestore. I made the structure of the app where the inputs were taking the data and outputs were showing a user's post.

The problem happened when I tried to add some posts and tried to upvote or downvote those posts. After some minutes I see a page saying,

Firebase Error, Quota exceeded

I canceled it and refresh the page to see if it magically disappears, However, I was wrong, It didn't and I had to spend and full day and a lot of help/discussion from #TeamTanay community. I was constantly getting this error,

FirebaseError

I checked the firebase console out of curiosity and I was over 50,000 reads in less than 4 hours.

ReadCount

Reaching out


I reached out to #TeamTanay community with my problems and link to this code sandbox URL. Members of the community offered different solutions to me.

I think it's because of the logic that you have in your useData component — you're reading the entire collection every time times changes.

if you read the fine print in the quota limits in firebase, you should see that this is what is leading to it

Suggestions


One user said.

this, and you are calling firebase read every time the page renders... so for 50k reads, assuming you have 10 posts, you'd only need like 100 or so refreshes in a day to cross the quota...

Don't do that.

optimize using memoization first. I am not sure, but probably useMemo after reading upon them. the firebase read should only work periodically, or when you write something new.

another one said.

At this point, My useData function was looking like this,

function UseData() {
  const [times, setTimes] = useState([]);

  useEffect(() => {
    var citiesRef = firebase.firestore().collection("times");

    // Create a query against the collection.
    //   var query = citiesRef.where("uid", "==", uid);

    citiesRef.get().then((snapshot) => {
      const newTimes = snapshot.docs.map((doc) => ({
        id: doc.id,
        ...doc.data(),
      }));

      setTimes(newTimes);
    });
  }, [times]);

  return times;
}

Discovery


After this communication, I was sure that my page making much more rerendering than I need in reality. My first thought was to get for useEffect, but I was not sure how it was causing this error. I did everything right(Narrator: he didn't) and rerendering only when update in the database, It was only when another person suggested me,

No, useEffect that you have created in the useData function is called every time "times" is updated. But you update "times" in useEffect itself which leads to useEffect being called infinitely. (You can use console.log() to check this)

Pass [ ] instead of [times] as the second argument in that useEffect then it will work properly.

Solution


I looked at the function again and discovered that I was making an infinite loop between the useEffect and Times state. I was calling the useData function to retrieve and update the data. So whenever I was doing that, I was invoking the useEffect function and Due to that, Times was getting updated. And I have passed Times in useEffect rerender array, So whenever times was getting updated, invoking useEffect again. And It was going in a loop until firebase stops it by giving an error.

Key Takeaways


  • Always check and understand what you are passing in useEffect(or any function in general)
  • Google won't be able to find your answers, reach out to the community.
  • Ask questions multiple times, if unanswered once.
  • Listen to people's feedback and improve that mistake next time.

A Nice ending with dev joke for you,

Ques: What is the problem with git jokes?

Answer: Everyone has their own version!