Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

189
Views
How can I minimize firestore reads in the "setUsername" scenario?

the code I have now created is working, but I think it is somehow suboptimal, as it does to many database reads As far as I understand it, the "onAuthStateChange" can be understood like an useEffect hook, which gets called whenever the user authentication state changes (login, logout). Whenever this happens, the database should be checked for the username which has been chosen by the user. But if I take a look at the console the docSnap is logged a fair amount of times which to me indicates that the function gets called more often than just when the user logs in / logs out.

enter image description here

Context Component

import { createContext } from "react/cjs/react.production.min";
import { onAuthStateChanged } from "firebase/auth";
import { doc, getDoc } from "firebase/firestore";
import { auth,db } from "./firebase";
import { useState, useEffect } from "react";

export const authContext = createContext({
  user: "null",
  username: "null",
});

export default function AuthenticationContext(props) {
  const [googleUser, setGoogleUser] = useState(null);
  const [username, setUsername] = useState(null);
  const [userID, setUserID] = useState(null);

  onAuthStateChanged(auth, (user) => {
    if (user) {
      setGoogleUser(user.displayName);
      setUserID(user.uid);
      getUsername();
    } else {
      setGoogleUser(null);
    }
  });


    const getUsername = async () => {
      const docRef = doc(db, `users/${userID}`);
      const docSnap = await getDoc(docRef);
      if(docSnap.exists()){
        setUsername(docSnap.data().username);
      }
      else{
        setUsername(null);
      }
    };
  

  return (
    <authContext.Provider value={{ user: googleUser, username: username }}>
      {props.children}
    </authContext.Provider>
  );
}

What is more, is that when I login with google and submit a username, the components do not get reevaluated - so a refresh is necessary in order for all the changes to take effect, this has something to do with me not updating state in the submitHandler of the login page. If you have some ideas on how I can do this more professionally please let me hear them. Thank you in advance!

Submit Handler on Login Page

const submitHandler = async (event) => {
    event.preventDefault();
    console.log(auth.lastNotifiedUid);
    await setDoc(doc(db, "users", auth.lastNotifiedUid), {
      displayName: user,
      username: username,
    });
    await setDoc(doc(db, "usernames", username), { uid: auth.lastNotifiedUid });
  };
about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

As pointed out in the comments by Dharmaraj, you set multiple subscriptions to the authentication state. This is because you call onAuthStateChanged in the body of your component, so it is executed on every render.

To avoid this, you should wrap the function in useEffect so that you only subscribe on component mounting, and unsubscribe on unmounting:

export default function AuthenticationContext(props) {
  /* ... */
  React.useEffect(() => {
    const unsubscribe = onAuthStateChanged(auth, (user) => { /* ... */ });
    return unsubscribe;
  }, []);
  /* ... */
}
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!