Reputation: 665
This is my first time using firestore and I have a react app where I want to display the logged user's username. I try to fetch the username from a firestore DB where I query users using the email of the user.
firebase.js
export const GetUserName = (email)=>{ //get single doc by email
let name = []; //store the name
//this is where the problem begins
db.collection('users').where("Email", "==" ,email)
.get()
.then(snapShot=>{
snapShot.forEach((snap)=>{
name.push(snap.data().userName); //stores only in array temporarily
console.log(name) //shows correct array
});
})
.catch(err =>{
console.log(err);
})
console.log(name); //shows empty array
return name[0]; //array is empty
}
then I try to display the username in another component I have
profilePage.js
import {GetUserName} from '../firebase';
export default function ProfilePage(){
const {user , logout} = useAuth(); //this is access to user.email
return (
<div>
<h1>Hi {getUsername(user.email)} </h1>
<Button onClick={handleLogout} color = "primary" variant = "outlined">Log out</Button>
</div>
);
}
But I only get "hi" without the username
Upvotes: 0
Views: 231
Reputation: 598668
Since the user name is read from Firestore asynchronously by the time your return name[0]
runs, the name.push(snap.data().userName);
hasn't run yet. You can easily check this by setting breakpoints on these lines and running the code in a debugger.
In situations like this you need to pass the data to the rendering code by putting it in the component's state. Using the useState
hook that'd be:
import {GetUserName} from '../firebase';
export default function ProfilePage(){
const {user , logout} = useAuth(); //this is access to user.email
const [userName, setUsername] = useState();
useEffect(() => {
db.collection('users').where("Email", "==" ,user.email)
.get()
.then(snapShot=>{
snapShot.forEach((snap)=>{
setUsername(snap.data().userName);
});
})
.catch(err =>{
console.log(err);
})
});
return (
<div>
<h1>Hi {userName} </h1>
<Button onClick={handleLogout} color = "primary" variant = "outlined">Log out</Button>
</div>
);
}
Upvotes: 1