Home > Mobile >  Firebase firestore read operation very high
Firebase firestore read operation very high

Time:12-05

So basically im making a CRUD app using react and firebase firestore for the backend. My write and delete operation is doing well, there is no problem with it.

But my read operation have problem.

My web is getting all document from a collection in firebase using useEffect. So this only run whenever it first mount (when my web load first time) and when im changing "users" value when doing delete and create operation

this my code:

useEffect(() => {
    const getUsers = async () => {
      const querySnapshot = await getDocs(collection(db, "cobadata"));
      setUsers(querySnapshot.docs.map((doc)=> ({...doc.data(), id: doc.id})))
    };
    getUsers();
  }, [users]);

idk whats wrong but im getting a very high read operation when im test the web, its like every one read operation i do in my website, its getting like hundred operation in the firebase. i can see this in my firebase console, when im using the web just like 5 minute in my firebase console the read operation reaching 20k< operation.

can anyone help me how to deal with this, thanks!

CodePudding user response:

You dont show all of your code here, so I will need to do some guessing.

Your useEffect has a dependency array that now is set to [users]. This means that every time the variable users changes your useEffect will rerender. Inside your useEffect you then set a new value to users by the setUsers function. Even if you get the same values returned from firebase regarding the current users, you still create a new array each time you read data. (querySnapshot.docs.map((doc)=> ({...doc.data(), id: doc.id}))). React only does a shallow comparison, meaning that the object reference has changed, and therefore users is different on each render.

First you need to decide when you want to run the useEffect and what should trigger it. If changes in the variable users is not the correct place to check, then I would remove users from the dependency array.

One solution could be to move the functionality in your effect into its own function and wrap it in an useCallbac. You can then call this function from an ´useEffect` on initial load, and after that simply load the effect whenever you delete or create users. Something like this.

const getUsers = useCallback(async () => {
        const querySnapshot = await getDocs(collection(db, "cobadata"));
        setUsers(querySnapshot.docs.map((doc)=> ({...doc.data(), id: doc.id}))) 
    }, [collection])
    
    useEffect(() => {
        getUsers()
    }, [getUsers]);

    const createUser = () => {
        ...
        getUsers()
    }

    const deleteUser = () => {
        ...
        getUsers()
    }

(PS! I would recommend adding the eslint-plugin-react-hooks to your eslint-config. This will give you some warning if your hooks are used wrong)

  • Related