1

I need your ideasssssssss.

renderIt = () => {
    if(!this.state.user){
      return <Login />
    }else {
      return <Home />
    }
  }

here I check is the user is logged in, if he is not logged in <Login /> is displayed, when he logs itself in, then <Home /> is displayed.

Problem is, when I go log out, and refresh, I see <Home/> page for a fraction of a second even if I am not logged in.

componentDidMount = () => {
      this.authListener();
  }

 authListener = () => {
    firebase
      .auth()
      .onAuthStateChanged((user) => user ? this.setState({user}) : this.setState({user: null}))
  }
4
  • How do you set this.state.user? Commented Sep 20, 2020 at 23:52
  • I've updated the post, check it out Commented Sep 20, 2020 at 23:56
  • What you're describing is the exact opposite of what I'd expect. Firebase should initially call your state changed listener with null, while it checks the user's authentication state. Then, once it has restored the state, it calls you with the user. So you should briefly see the Login screen and then the home screen, not the other way around. If that is really what you see, can you set up a repro on a site like jsbin or stackblitz, so I can have a look? Commented Sep 21, 2020 at 0:13
  • Here you go, try clicking the refresh button and you'll end up seeing YOU ARE LOGGED IN and after ... ms you will see the login form. stackblitz.com/edit/react-xutkna?file=src/App.js Commented Sep 21, 2020 at 0:21

2 Answers 2

1

The problem is in your initial state, which is:

class App extends Component {
  state = {
    user: {}
  }
  ...

Since you then check for this.state.user in the rendering code, you end up comparing (!{}) which is false.

I highly recommend keeping this code as simple as possible, following these rules:

  • this.state.user represents the current user object.
  • if there is no current user, this.state.user is null.

In code:

class App extends Component {
  state = {
    user: null
  }

  componentDidMount = () => {
      this.authListener();
  }

  authListener = () => {
    firebase
      .auth()
      .onAuthStateChanged((user) => this.setState({user}));
  }
  ...

Also see the updated working code at: https://stackblitz.com/edit/react-1bv4bb?file=src/App.js

Sign up to request clarification or add additional context in comments.

2 Comments

One more question, because it's connected to this topic, is it possible to update the retrieved object? .onAuthStateChanged((user)) this retrieved user, I saw that already holds properties like profilephoto, phone number, displayName etc.
You can update the existing properties with updateProfile and other methods on the User class, but you can't add new properties. If you want that you'll either store them as custom claims (if they're security related and small) or in the database. See stackoverflow.com/q/37415863 and some more of these: google.com/search?q=firebase+add+property+to+user
1

it's because !this.state.user true initially and until firebase auth finishes its work it will show you <Home/>.

The solution is to use a loading (some spinner animation) component initially until the firebase auth finished

if(this.state.user===null){
//create Loading component first before using it here
  return <Loading />
}else if(!this.state.user){
  return <Login />
}else {
  return <Home />
}
  • This might not be a better way to handle user authentication, it's just to answer your question

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.