Auth Overview

authenticate app users

The Auth client SDK authenticates users, and notifies the app about Auth events. It provides alternative authentication flows.

the auth helper and reading currentUser

We keep a reference to the auth helper to read currentUser. We also use it in auth related functions.

const auth = getAuth(app)
auth.currentUser // User | null

currentUser starts as null. When the SDK has finished loading, and given that the user has logged in, currentUser switches to a User instance.

As a User instance, It exposes the user identifier (uid). The other properties are optional:

currentUser.uid
currentUser.email
currentUser.phoneNumber
currentUser.displayName
currentUser.isAnonymous

react to authentication events

We register a callback on onAuthStateChanged, which Firebase runs on auth events. Firebase gives us a user object (of type User | null).

onAuthStateChanged(auth, (user) => {
    if (user) {
        // user.uid
    }
})

Auth events:

  • the auth SDK has finished loading and no user is authenticated

  • the user has registered (sign up)

  • the user has logged in (sign in)

  • the user has logged out (sign out)

Login occurs in three specific scenarios:

  • the user fills out the standard login form or logs in through an identity provider (hard-login)
  • the user is recognized by the SDK and is logged in automatically (credentials stored in browser)
  • (canonically a registration) 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: It's best to wait for the SDK to load before making any use of isSignedIn, given that the state should be indeterminate.

As such, we track the loading state in a one-off state variable, which becomes true on the first authentication event. Only then do we set isSignedIn with correct state and make use of it.

If we were to read isSignedIn before load, and because we initialize it to false for simplicity, we would have a rapid UI flicker when it switches from false to true if applicable.

const [hasLoaded, setHasLoaded] = useState(false)
const [isSignedIn, setisSignedIn] = useState(false) // the initial state shouldn't be relied upon.

useEffect(() => {
    const unsub = onAuthStateChanged(auth, (user) => {
        setHasLoaded(true)
        setisSignedIn(Boolean(user)) // accurate state
    })
    return unsub
}, []) // subscribe once, unsubscribe on unmount.

if (!hasLoaded) return null
if (!isSignedIn) return <Lobby />
return <Ingame />

sign out

sign out is consistent across all authentication flows:

signOut(auth)
earlymorning logo

Auth Overview

authenticate app users

The Auth client SDK authenticates users, and notifies the app about Auth events. It provides alternative authentication flows.

the auth helper and reading currentUser

We keep a reference to the auth helper to read currentUser. We also use it in auth related functions.

const auth = getAuth(app)
auth.currentUser // User | null

currentUser starts as null. When the SDK has finished loading, and given that the user has logged in, currentUser switches to a User instance.

As a User instance, It exposes the user identifier (uid). The other properties are optional:

currentUser.uid
currentUser.email
currentUser.phoneNumber
currentUser.displayName
currentUser.isAnonymous

react to authentication events

We register a callback on onAuthStateChanged, which Firebase runs on auth events. Firebase gives us a user object (of type User | null).

onAuthStateChanged(auth, (user) => {
    if (user) {
        // user.uid
    }
})

Auth events:

  • the auth SDK has finished loading and no user is authenticated

  • the user has registered (sign up)

  • the user has logged in (sign in)

  • the user has logged out (sign out)

Login occurs in three specific scenarios:

  • the user fills out the standard login form or logs in through an identity provider (hard-login)
  • the user is recognized by the SDK and is logged in automatically (credentials stored in browser)
  • (canonically a registration) 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: It's best to wait for the SDK to load before making any use of isSignedIn, given that the state should be indeterminate.

As such, we track the loading state in a one-off state variable, which becomes true on the first authentication event. Only then do we set isSignedIn with correct state and make use of it.

If we were to read isSignedIn before load, and because we initialize it to false for simplicity, we would have a rapid UI flicker when it switches from false to true if applicable.

const [hasLoaded, setHasLoaded] = useState(false)
const [isSignedIn, setisSignedIn] = useState(false) // the initial state shouldn't be relied upon.

useEffect(() => {
    const unsub = onAuthStateChanged(auth, (user) => {
        setHasLoaded(true)
        setisSignedIn(Boolean(user)) // accurate state
    })
    return unsub
}, []) // subscribe once, unsubscribe on unmount.

if (!hasLoaded) return null
if (!isSignedIn) return <Lobby />
return <Ingame />

sign out

sign out is consistent across all authentication flows:

signOut(auth)