I'm trying set up the Firebase auth listener on my top level component App in order to provide the authUser object via React context to all other components.
I'm currently doing this:
function App() {
console.log('Rendering App...');
const [authUser,setAuthUser] = useState(null);
const [authWasListened,setAuthWasListened] = useState(false);
useEffect(()=>{
console.log('Running App useEffect...');
return firebase.auth().onAuthStateChanged(
(authUser) => {
console.log(authUser);
console.log(authUser.uid);
if(authUser) {
setAuthUser(authUser);
setAuthWasListened(true);
} else {
setAuthUser(null);
setAuthWasListened(true);
}
}
);
},[]);
return(
authWasListened ?
<Layout/>
: <div>Waiting for auth...</div>
);
}
But I'm getting the log output:
Rendering App...
Running App useEffect...
It seems that I'm setting up the listener but it doesn't run at first, therefore it's not getting the current auth state (which is null, since I don't even have a login form yet). It seems like it's waiting for a change to occur.
Shouldn't the authListener get the current authUser state at first, and then listen to changes? What am I doing wrong?
UPDATE
I've found out what I was doing wrong. The useEffect should return a function to clear the listener on unmount and not a function call, as I was trying to do above. So my listener was never being set up.
This is working as intended now:
useEffect(()=>{
console.log('Running App useEffect...');
const authListener = firebase.auth().onAuthStateChanged(
(authUser) => {
console.log(authUser);
console.log(authUser.uid);
if(authUser) {
setAuthUser(authUser);
setAuthWasListened(true);
} else {
setAuthUser(null);
setAuthWasListened(true);
}
}
);
return authListener; // THIS MUST BE A FUNCTION, AND NOT A FUNCTION CALL
},[]);