Authentication
import { Tabs, TabItem } from ‘@astrojs/starlight/components’;
svelte-firekit exposes two authentication primitives:
firekitAuth— methods for signing in, registering, and managing usersfirekitUser— reactive object that always reflects the current auth state
Sign in
Section titled “Sign in”Email & password
Section titled “Email & password”import { firekitAuth } from 'svelte-firekit';
OAuth providers (popup)
Section titled “OAuth providers (popup)”await firekitAuth.signInWithGoogle();await firekitAuth.signInWithGithub();await firekitAuth.signInWithFacebook();await firekitAuth.signInWithApple();await firekitAuth.signInWithTwitter();await firekitAuth.signInWithMicrosoft();OAuth providers (redirect)
Section titled “OAuth providers (redirect)”Use the redirect flow on mobile or when popups are blocked. Call getRedirectResult() when the app loads to pick up the pending result.
// Trigger the redirectawait firekitAuth.signInWithGoogleRedirect();
// On app load — returns null if no pending redirectconst result = await firekitAuth.getRedirectResult();SAML & OIDC
Section titled “SAML & OIDC”await firekitAuth.signInWithSAML('saml.my-provider');await firekitAuth.signInWithOIDC('oidc.my-provider', ['email', 'profile']);Phone number
Section titled “Phone number”// Step 1 — send SMS, pass the ID of a div where the reCAPTCHA will renderconst { confirm } = await firekitAuth.signInWithPhoneNumber('+1234567890', 'recaptcha-container');
// Step 2 — confirm the code the user enteredawait confirm('123456');Other methods
Section titled “Other methods”await firekitAuth.signInAnonymously();await firekitAuth.signInWithCustomToken(serverIssuedToken);Registration & account management
Section titled “Registration & account management”// Register with email + password; optionally set a display name
// Update profileawait firekitAuth.updateUserProfile({ displayName: 'Jane', photoURL: 'https://...' });
// Change email (requires recent sign-in)
// Change passwordawait firekitAuth.updatePassword('newPassword', 'currentPassword');
// Password reset email
// Email verificationawait firekitAuth.sendEmailVerification();
// Sign outawait firekitAuth.signOut();
// Delete account (requires current password for email users)await firekitAuth.deleteAccount('currentPassword');Multi-factor authentication (MFA)
Section titled “Multi-factor authentication (MFA)”Enroll a phone factor
Section titled “Enroll a phone factor”// Step 1 — send verification SMSconst verificationId = await firekitAuth.startPhoneMFAEnrollment('+1234567890', 'recaptcha-container');
// Step 2 — confirm the codeawait firekitAuth.completeMFAEnrollment(verificationId, '123456', 'My Phone');Manage enrolled factors
Section titled “Manage enrolled factors”const factors = firekitAuth.getMFAEnrolledFactors();
// Unenroll a specific factorawait firekitAuth.unenrollMFA(factors[0]);Complete an MFA-required sign-in
Section titled “Complete an MFA-required sign-in”When a sign-in requires MFA, Firebase throws a MultiFactorError. Catch it and use the resolver to complete the flow:
try { await firekitAuth.signInWithEmail(email, password);} catch (err) { // err is a MultiFactorError const resolver = firekitAuth.getMFAResolver(err);
// Start the SMS challenge for the first enrolled factor const verificationId = await firekitAuth.startMFASignIn(resolver, 0, 'recaptcha-container');
// Complete after the user enters the code const result = await firekitAuth.completeMFASignIn(resolver, verificationId, '123456');}Reactive user state (firekitUser)
Section titled “Reactive user state (firekitUser)”firekitUser is a reactive singleton. Read its properties anywhere in your Svelte components — no subscription needed.
<script lang="ts"> import { firekitUser } from 'svelte-firekit';</script>
{#if firekitUser.loading} <p>Loading auth state…</p>{:else if firekitUser.isAuthenticated} <p>Welcome, {firekitUser.user?.displayName}</p> <p>Email: {firekitUser.user?.email}</p>{:else} <p>Not signed in</p>{/if}Properties
Section titled “Properties”| Property | Type | Description |
|---|---|---|
user | UserProfile | null | Current user profile or null |
loading | boolean | true while the initial auth state is being resolved |
isAuthenticated | boolean | true when signed in and not anonymous |
isAnonymous | boolean | true when the session is anonymous |
initialized | boolean | true after the first auth state has been received |
Wait for auth (SSR / load functions)
Section titled “Wait for auth (SSR / load functions)”In SvelteKit load functions you may need to wait for the auth state before proceeding:
import { firekitUser } from 'svelte-firekit';
export async function load() { const user = await firekitUser.waitForAuth();
if (!user) { return { redirect: '/login', status: 302 }; }
return { user };}On the server waitForAuth() resolves immediately with null.
Auth components
Section titled “Auth components”Use these components for declarative auth gating directly in templates.
<SignedIn> and <SignedOut>
Section titled “<SignedIn> and <SignedOut>”<script lang="ts"> import { SignedIn, SignedOut } from 'svelte-firekit';</script>
<SignedIn> <p>Only shown when the user is signed in.</p></SignedIn>
<SignedOut> <a href="/login">Sign in</a></SignedOut><AuthGuard>
Section titled “<AuthGuard>”Redirects unauthenticated users. Pass requireAuth={true} to protect a route, or requireAuth={false} to redirect already-signed-in users away from login pages.
<script lang="ts"> import { AuthGuard } from 'svelte-firekit'; import { goto } from '$app/navigation';</script>
<AuthGuard requireAuth={true} onUnauthorized={() => goto('/login')}> <p>This content is only visible to signed-in users.</p></AuthGuard><CustomGuard>
Section titled “<CustomGuard>”For role checks or any async authorization logic. Pass an array of async functions that each return a boolean; all must resolve to true for the content to render.
<script lang="ts"> import { CustomGuard } from 'svelte-firekit'; import { goto } from '$app/navigation'; import { getDoc, doc } from 'firebase/firestore'; import { getFirestoreContext } from 'svelte-firekit';
const db = getFirestoreContext();
const checks = [ async () => { const snap = await getDoc(doc(db, 'users', userId)); return snap.data()?.role === 'admin'; }, ];</script>
<CustomGuard verificationChecks={checks} onUnauthorized={() => goto('/403')}> <p>Admin-only content</p></CustomGuard>