AuthProvider / useAuth
Live Firebase user and custom claims for the whole tree, plus app-wide defaults.
Two things in one: the live user for your component tree, and the place your auth and app-wide defaults live.
<AuthProvider auth={auth}>{children}</AuthProvider>;
const { firebaseUser, claims, isAuthenticated, isLoading } = useAuth();
if (claims?.isAdmin) showAdminNav();Every other hook works with no provider at all, given an auth of its own — it's additive, not required. useAuth is the exception: nothing else subscribes to Firebase, so without a provider it has no user to report and throws rather than claiming nobody is signed in.
useAuth
| Field | Type | What it is |
|---|---|---|
firebaseUser | User | null | The live Firebase user |
claims | Record<string, unknown> | null | Custom claims from the ID token |
isAuthenticated | boolean | Whether a user is signed in |
isLoading | boolean | True only until Firebase's first callback |
Claims update without a reload
The provider subscribes to onIdTokenChanged, not onAuthStateChanged. So firebaseUser and claims update on sign-in, sign-out, and token refreshes — meaning a custom-claim change like a role update propagates on its own.
isLoading is true only until the first callback, which is how you tell "signed out" from "not yet known".
App-wide defaults
Set these once and every hook below inherits them:
<AuthProvider
auth={auth}
onIdToken={(idToken) => createSession(idToken)}
onBeforeSignOut={() => clearSession()}
actionCodeSettings={{ url: `${origin}/auth/action`, handleCodeInApp: true }}
formatErrorMessage={(e) => formatFirebaseError(e, { messages: AUTH_ERROR_MESSAGES })}
onError={(error, { action, code }) => track('auth_error', { action, code })}
>
{children}
</AuthProvider>A hook's own option overrides the provider, and an explicit null opts that flow out entirely.
auth follows the same rule with one difference: a hook called without one uses the provider's, and passing your own overrides it — but null means "not ready yet, don't run", never "inherit". That's what lets you hold a hook back while Firebase initialises.
| Prop | What it does |
|---|---|
auth | Your Auth instance, used by every hook below that doesn't pass its own |
onIdToken | Inherited by every sign-in hook |
onBeforeSignOut | Inherited by useLogout |
actionCodeSettings | Inherited by every emailed link |
formatErrorMessage | Inherited by every hook — see Error handling |
onError | Fire-and-forget observer for every failure |
Your own user record
Server-fetched user records are an app concern. Layer your own provider on top of this one rather than expecting this one to fetch them.