vasilis 123
vasilis 123

Reputation: 665

cannot display data from firestore in react app

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

Answers (1)

Frank van Puffelen
Frank van Puffelen

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

Related Questions