nkhil
nkhil

Reputation: 1610

How to avoid exceeding the firestore quota while using React's live re-load?

I'm fairly new to react so I apologies if this is a basic question. I've tried looking on stack overflow, google, and Github for the errors, but didn't see many posts looking for the error or general terms around it - and none of the ones I found were helpful or directly relevant.

I'm using react with firebase's authentication and firestore services. I don't have any trouble working with the authentication service (in terms of reaching the daily limit), however, I've been reaching the firebase quota within the hour. This is the error I see:

Unhandled Rejection (FirebaseError): Quota exceeded.

I'd like to know if it's the code that's causing these excessive reads, or if there could be another culprit like the react live re-load that fires off a read for every small change I make.

The app currently reads some data from a firestore collection and renders it to a page. Here's what the component looks like:

import React, { useState, useEffect } from 'react';
import firebase from '../../lib/firebase';

import Navbar from '../Navbar';
import MainContainer from '../MainContainer';
import { PostView } from '../Post';

function Home({ currentUser }) {

  const [ posts, setPosts ] = useState([]);

  const signOutUser = () => firebase.auth().signOut();

  useEffect(() => {
    const userId = currentUser.uid;
    const db = firebase.firestore();
    const postsRef = db.collection('posts');
    const query = postsRef.where('userId', '==', userId);
    async function getData() {
      const data = await query.get();
      setPosts(data.docs.map(doc => ({ ...doc.data(), id: doc.id })));
    }
    getData();
  }, [posts, currentUser]);

  return (
    <>
      <Navbar />
      <MainContainer>
        <button onClick={signOutUser}>Sign out</button>
        {posts.length === 0 ? <h1>No posts to display</h1> : '' }
        <ul>
          {posts.map(post => (
            <li key={post.id}>
              <PostView post={post} />
            </li>
          ))}
        </ul>
      </MainContainer>
    </>
  )
}

export default Home;

The above component is rendered in full at the root of the app (if the user isn't signed in, they get redirected to the login page).

In my understanding, the useEffect method loads the first time the component is mounted, and every time either posts or currentUser changes.

I have a sneaking suspicion that I'm doing something silly, causing a large amount of data reads and resulting in this error.

Upvotes: 1

Views: 1953

Answers (1)

nkhil
nkhil

Reputation: 1610

The cause of the problem I think was that I'm using a method that is meant for data fetching once. Even though I was using it in the useEffect function, I think I was badgering the firebase endpoint.

The solution (I think, I'm a react beginner) is to manage the firestore snapshot as mentioned in the docs.

I actually managed to get around it by using react-firebase-hooks which abstracts the data handling away.

I'd still love answers on how to do this appropriately from scratch in the useEffect API.

Upvotes: 1

Related Questions