Auth Overview
authenticate app users
The client-SDK provides authentication flows to authenticate users against Firebase's authentication servers.
the auth helper and currentUser
We keep a reference to the auth helper to use it in various functions. It also exposes currentUser.
const auth = getAuth(app)
auth.currentUser // User | null
currentUser starts as null. When the SDK has finished loading and the user is logged-in, currentUser switches to a User instance.
currentUser holds uid, the user unique identifier. The other properties may be empty:
currentUser.uid
currentUser.email
currentUser.phoneNumber
currentUser.displayName
currentUser.isAnonymous
main pattern: react to authentication state changes
We provide a callback to onAuthStateChanged, which Firebase runs on auth events. Firebase gives us a user object, also of type User, and which is null when there is no authenticated user.
onAuthStateChanged(auth, (user) => {
if (user) {
// user.uid
}
})
The auth events are as follows:
-
the auth SDK has finished loading and no user is authenticated
-
the user registers (sign up)
-
the user logs in (sign in)
-
the user logs out (sign out)
The login occurs in three scenarios:
- the user is recognized by the SDK and is logged in automatically (credentials stored in browser)
- the user fills the standard login form or logs in through an identity provider (hard-login)
- the user is automatically logged-in after a successful sign-up. Note: a single authentication event occurs.
React patterns
We make the authentication status part of the React state. For example, we work with a isSignedIn variable. We make the display of the authenticated area conditional on isSignedIn being true.
On page load, the Auth SDK is loading: user starts as null. Once the SDK is loaded, user may switch to a User instance, in a quick UI flicker.
As a best practice, we wait for the SDK load before showing some UI: we track the loading state in a one-off state variable that switches to true on the first authentication event:
const [hasLoaded, setHasLoaded] = useState(false)
const [isSignedIn, setisSignedIn] = useState(false)
useEffect(() => {
const unsub = onAuthStateChanged(auth, (user) => {
setHasLoaded(true)
setisSignedIn(Boolean(user))
})
return unsub
}, []) // subscribe once, subscribe automatically.
if (!hasLoaded) return null
if (!isSignedIn) return <Lobby />
return <Ingame />
sign out
sign out is consistent across all authentication flows:
signOut(auth)