When mounting a component, I\'d like to render either a log in screen or the app, depending on wether the user in logged in. However, each time I refresh, the user is logged
The user's token is automatically persisted to local storage, and is read when the page is loaded. This means that the user should automatically be authenticated again when you reload the page.
The most likely problem is that your code doesn't detect this authentication, since your App
constructor runs before Firebase has reloaded and validated the user credentials. To fix this, you'll want to listen for the (asynchronous) onAuthStateChanged() event, instead of getting the value synchronously.
constructor(props){
super(props);
firebase.auth().onAuthStateChanged(function(user) {
this.setState({ user: user });
});
}
I had the same issue with Firebase in React. Even though Firebase has an internal persistence mechanisms, you may experience a flicker/glitch when reloading the browser page, because the onAuthStateChanged
listener where you receive the authenticated user takes a couple of seconds. That's why I use the local storage to set/reset it in the onAuthStateChanged listener. Something like the following:
firebase.auth.onAuthStateChanged(authUser => {
authUser
? localStorage.setItem('authUser', JSON.stringify(authUser))
: localStorage.removeItem('authUser')
});
Then it can be retrieved in the constructor of a React component when the application starts:
constructor(props) {
super(props);
this.state = {
authUser: JSON.parse(localStorage.getItem('authUser')),
};
}
You can read more about it over here.
Personally, I feel this way is the best and the most simple.
state = {authUser: null,show:'none'};
componentDidMount() {
firebase.auth().onAuthStateChanged(user => {
if (user) { this.setState({ authUser: true,show:'block'})}
else { this.setState({ authUser: false,show:'none'})}
})
}
return{ /*important*/ this.state.authuser==false?
<Login/>
:this.state.authuser==true?
<Home style={{display:this.state.show}}/>
:<div>/*show loading/spash page*/
</div>
}
You can also add routing to this with Home as the default route ('/' do not use exact path use path instead) and then make it auto reroute to the login or signup if the user is not logged in.