el código que he creado ahora está funcionando, pero creo que de alguna manera es subóptimo, como ocurre con muchas lecturas de bases de datos. Según tengo entendido, el "onAuthStateChange" puede entenderse como un gancho useEffect, que se llama cada vez que la autenticación del usuario cambios de estado (inicio de sesión, cierre de sesión). Siempre que esto suceda, se debe verificar en la base de datos el nombre de usuario que ha elegido el usuario. Pero si echo un vistazo a la consola, docSnap se registra una buena cantidad de veces, lo que para mí indica que la función se llama con más frecuencia que cuando el usuario inicia/cierra sesión.
Componente de contexto
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> ); }Lo que es más, es que cuando inicio sesión con Google y envío un nombre de usuario, los componentes no se vuelven a evaluar, por lo que es necesaria una actualización para que todos los cambios surtan efecto, esto tiene algo que ver con que no actualizo el estado en el submitHandler de la página de inicio de sesión. Si tiene algunas ideas sobre cómo puedo hacer esto de manera más profesional, déjeme escucharlas. ¡Gracias de antemano!
Enviar controlador en la página de inicio de sesión
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 }); };Como se señaló en los comentarios de Dharmaraj, configura varias suscripciones al estado de autenticación. Esto se debe a que llama a onAuthStateChanged en el cuerpo de su componente, por lo que se ejecuta en cada renderizado.
Para evitar esto, debe ajustar la función en useEffect para que solo se suscriba al montar el componente y cancelar la suscripción al desmontarlo:
export default function AuthenticationContext(props) { /* ... */ React.useEffect(() => { const unsubscribe = onAuthStateChanged(auth, (user) => { /* ... */ }); return unsubscribe; }, []); /* ... */ }