Home > Back-end >  firebase `onAuthStateChanged` function returns null each time
firebase `onAuthStateChanged` function returns null each time

Time:11-12

When I'm calling handleAuth function after registeration, a user has been created(I can see him being added to the firebase authentication web), but onAuthStateChanged logs null.

I'm caling it inside useEffect after a user is successfully signed in. console.log(data) inside it returns the user's token from the server response data.

Why's onAuthStateChanged returns null?

import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap-icons/font/bootstrap-icons.css';
import { useEffect, useRef, useState } from 'react';
import useFetch from '../hooks/useFetch';
import { useLocation } from 'react-router';
import { auth } from '../config/firebaseConfig';


export default function Authenticate() : JSX.Element {
    const url = useLocation().pathname;
    const { fetchData, data, error, loading } = useFetch();

    const email = useRef() as React.MutableRefObject<HTMLInputElement>;
    const password = useRef() as React.MutableRefObject<HTMLInputElement>;
    const [show, setShow] = useState(false);

    const handleAuth = (e : React.FormEvent<HTMLFormElement>) => {
        e.preventDefault();

        const path = (e.nativeEvent as any).submitter.name === 'login' ?
        `${url}/login/email` : `${url}/register`;
        fetchData(path, 'POST', {
            email : email.current.value,
            password : password.current.value
        });
    }


    useEffect(() => {
        if(data)
        {
            console.log(data)
            auth.onAuthStateChanged(user => console.log(user));
        }
    }, [data])
    
    return (
        <div className="d-flex justify-content-center align-items-center vh-100 bg-white">
            <div className="p-5 border border-2 border-success"> 
                <h1 className="fw-light fs-2 text-center">Authenticate</h1>
                <br/>
                <form onSubmit={e => handleAuth(e)}>
                    <div className="form-group">
                        <label>Email</label>
                        <div className="input-group">
                            <span className="input-group-text bi bi-person-circle"></span>
                            <input type="email" ref={email} className="form-control" placeholder="[email protected]" required/>
                        </div>
                    </div>
                    <div className="form-group">
                        <label>Password</label>
                        <div className="input-group">
                            <span className="input-group-text bi bi-key-fill"/>
                            <input type={show ? "text" : "password"} className="form-control" ref={password} placeholder="enter your password" required/>
                            <button type="button" className={`input-group-text text-decoration-none bi bi-${show ? 'eye-fill' : 'eye-slash-fill' }`} onClick={() => setShow(!show)}/>
                        </div>
                    </div>
                    <br/>
                    { error && <p className={`alert alert-danger p-1 text-center`} role="alert">{error}</p> }
                    <div className="d-flex justify-content-between">
                        <button type="submit" name="register" className="btn btn-primary" disabled={loading}>Register</button>
                        <button type="submit" name="login" className="btn btn-primary" disabled={loading}>Login</button>
                    </div>
                </form>
            </div>
        </div>
  );
}

CodePudding user response:

The creation of the user is different from the authentication of the use.

While creating the user, you will storing new user credentials (email / password), while when authenticating the user you will matching the provided credentials against the stored ones.

The listener onAuthStateChanged seems to be well installed but you are not engaging any authentication so that it submits a new values: the authenticated user.

Once the user has been successfully created, and given his account has been validated, you can trigger a sign in request as follows:

const handleAuth = (e : React.FormEvent<HTMLFormElement>) => {
    // ...
    fetchData(path, 'POST', {
        email : email.current.value,
        password : password.current.value
    }).then(() => auth.signInWithEmailAndPassword(email.current.value, password.current.value))
}

Then the registered onAuthStateChanged listener will get triggered with the proper user identity.

  • Related