1

I'm creating a new account in Signup.tsx and redirecting to the dashboard after success, this way

try {
            await auth.createUserWithEmailAndPassword(
              emailRef.current!.value,
              passwordRef.current!.value,
            );
            const user = firebase.auth().currentUser;
            await user?.updateProfile({
              displayName: nameRef.current?.value
            })
             navigate('/dashboard')
          } catch (error) {
            console.error(error);
          }
        }

And google auth is managed this way, googleAuth.tsx

import { auth, provider } from "../../../firebaseSetup";
import { NavigateFunction, useNavigate } from "react-router-dom"


const GoogleAuth = async(navigate: NavigateFunction) => {
    auth.signInWithPopup(provider).then(() => {
      if (auth.currentUser?.metadata?.creationTime !== auth.currentUser?.metadata?.lastSignInTime)
          {
            navigate('/dashboard');
          }
          else{
            navigate('/welcome')
          }
    }).catch((error) => {
      console.log(error.message)
    })
}
export default GoogleAuth

And in my dashboard's navbar, I'm displaying the current user's display name and profile pic if logged in via google this way sidebar.tsx

import { auth } from "../../firebaseSetup";

export default sidebar(){
   const pic = auth.currentUser?.photoURL
   return(
      <Text>{auth.currentUser?.displayName}</Text>
      <Avatar size={'sm'} src={pic}/>
    )
}

All this works perfectly fine when users sign-in/up for the first time i.e that is when they are redirected from the landing page, but if the user refreshes or moves to another route, both text and avatar go blank. I tried printing using

console.log(auth.currentUser?.displayName)

It returns the correct name the first time, but on refreshing it prints undefined. I looked up and figured I need to be using useState and useEffect to manage current users, which I tried and failed. Can anyone tell me how do I retain the users name even on refreshing

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Sumukh Jadhav
  • 212
  • 1
  • 14

1 Answers1

0

That is the expected behavior. While Firebase automatically restores the user credentials when the page/app reloads, this requires it to call to the server (a.o. to check whether the account has been disabled) and that is an asynchronous call.

To get notified when the authentication state has been restored, you should use an auth state listener as shown in first example in the documentation on getting the current user:

firebase.auth().onAuthStateChanged((user) => {
  if (user) {
    // User is signed in, see docs for a list of available properties
    // https://firebase.google.com/docs/reference/js/firebase.User
    var uid = user.uid;
    // ...
  } else {
    // User is signed out
    // ...
  }
});

Once this callback gets called for the first time, the auth state has been restored or has failed to restore, so that is the perfect moment to navigate to the corresponding screen of your app.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • I couldn't figure out where exactly I need to insert this code block – Sumukh Jadhav Feb 26 '22 at 06:51
  • I'd typically put this in the constructor of the widget that shows the user data. But a search also gives promising results: https://stackoverflow.com/search?q=%5Breactjs%5D+where+to+put+onAuthStateChanged If none of this works for you, edit your question to show what you tried. – Frank van Puffelen Feb 26 '22 at 15:41