1
votes

I am new in react, I hope you can help me.

I'm using firebase authentication + react for a small application. I have a component to login and another when logged, with that there's no problem. The problem arises when I update the page, it shows me for a few seconds the login component even though it is already logged. I guess this happens because in my constructor I have a variable "user: null" and only in componentDidMount I use the "onAuthStateChanged" method that firebase gives me to change the value of the user.

I have something in mind but I don't know how to implement it. Firebase gives me a method called currentUser.getIdToken(), with this I can verify if I have an active token, but this method is a promise, so react doesn't recommend using this type of asynchronous methods in the constructor. But in the case of implementing it in the constructor, is it a good practice to use conditionals within a constructor variable?

Thank you!

import React, { Component } from 'react';
import firebase from 'firebase';
import Main from './MainComponent'
import Login from './LoginComponent'

export default class Main extends Component {

    constructor() {
        super();
        this.state = {
            user: null
        };
    }

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

    render() {
        if(!this.state.user) {  
            return(
                <Login />               
            );
        }        
        else {
            return(    
                <MainComponent user={this.state.user} /> 
            );
        }
    
    }
}
1
do you have redux wired up? you would need to use redux for this, have 3 states undefined, logged in, not logged in ,and render component accordingly. - Bola
You do NOT need Redux for that. @Bola is correct in saying that you need a third state though to show that you're checking their login status. - CodingIntrigue
@CodingIntrigue i agree he doesnt need redux, but if has it wired up it would make things more elegant :) - Bola
Right now I'm implementing a redux version of the same. Thanks for letting me know that I need a third state! - adflytec

1 Answers

2
votes

This is actually quite a frustrating issue with Firebase authentication. There is no way to synchronously check if your user is logged in.

Most people get around this by showing a "loading" screen until the check is done:

import React, { Component } from 'react';
import firebase from 'firebase';
import Main from './MainComponent'
import Login from './LoginComponent'

export default class Main extends Component {

    constructor() {
        super();
        this.state = {
            hasCheckedLogin: false,
            user: null
        };
    }

    componentDidMount() {
        firebase.auth().onAuthStateChanged(user => {
            this.setState({user: user, hasCheckedLogin: true});    
        });
    }  

    render() {
        // Hasn't checked login yet, show a loading message
        if(!this.state.hasCheckedLogin) {
            return <Loading />:
        }
        // Has checked login, but user isn't authenticated
        if(!this.state.user) {  
            return(
                <Login />               
            );
        }        
        // Has checked login, and user is authenticated
        else {
            return(    
                <MainComponent user={this.state.user} /> 
            );
        }

    }
}