Skip to main content
RapidDev - Software Development Agency
firebase-tutorial

How to Sign Out a User in Firebase

To sign out a user in Firebase, call signOut() from the firebase/auth module. This clears the local authentication state and triggers the onAuthStateChanged listener with a null user. After sign-out, redirect the user to your login page and clear any cached application state. The signOut function returns a Promise that resolves when the local session is fully cleared.

What you'll learn

  • How to implement signOut() with the Firebase modular SDK v9+
  • How to listen for sign-out events with onAuthStateChanged
  • How to clear application state and redirect after sign-out
  • How to build a sign-out button component in React
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner8 min read5-10 minFirebase Auth (Spark and Blaze plans), firebase v9+ modular SDKMarch 2026RapidDev Engineering Team
TL;DR

To sign out a user in Firebase, call signOut() from the firebase/auth module. This clears the local authentication state and triggers the onAuthStateChanged listener with a null user. After sign-out, redirect the user to your login page and clear any cached application state. The signOut function returns a Promise that resolves when the local session is fully cleared.

Signing Out a User in Firebase Authentication

Signing out a user in Firebase involves calling the signOut() function, handling the resulting auth state change, clearing any cached user data in your application, and redirecting to a public page. This tutorial covers the complete sign-out flow including error handling, auth state listeners, React component integration, and best practices for cleaning up application state after logout.

Prerequisites

  • A Firebase project with Authentication enabled
  • Firebase SDK installed in your project (npm install firebase)
  • Users who can sign in (email/password, Google, or any provider)
  • Basic understanding of React or your frontend framework

Step-by-step guide

1

Import signOut and call it from your auth instance

Import the signOut function from firebase/auth and your auth instance from your Firebase configuration file. Call signOut(auth) which returns a Promise. The function clears the user's session from local storage (IndexedDB) and invalidates the current ID token. Handle errors in a try/catch block since signOut can fail if there is a network issue, though the local session is still cleared in most cases.

typescript
1import { getAuth, signOut } from 'firebase/auth';
2import { app } from './firebase'; // your Firebase app instance
3
4const auth = getAuth(app);
5
6async function handleSignOut() {
7 try {
8 await signOut(auth);
9 console.log('User signed out successfully');
10 // Redirect to login page
11 window.location.href = '/login';
12 } catch (error) {
13 console.error('Sign out error:', error);
14 }
15}

Expected result: The user's local auth session is cleared. The onAuthStateChanged listener fires with a null user.

2

Listen for sign-out events with onAuthStateChanged

Set up an onAuthStateChanged listener in your app's root component to detect when the user's auth state changes. When the user signs out, the callback fires with null as the user parameter. Use this centralized listener to clear application state, reset stores, and redirect to the login page. This approach catches sign-outs from any trigger including token expiration and manual sign-out.

typescript
1import { getAuth, onAuthStateChanged } from 'firebase/auth';
2
3const auth = getAuth(app);
4
5onAuthStateChanged(auth, (user) => {
6 if (user) {
7 // User is signed in
8 console.log('Signed in as:', user.email);
9 } else {
10 // User is signed out
11 console.log('User signed out');
12 // Clear any cached user data
13 localStorage.removeItem('userProfile');
14 sessionStorage.clear();
15 }
16});

Expected result: The auth state listener fires whenever the user signs in or out, allowing centralized state management.

3

Build a sign-out button component in React

Create a reusable React component that handles the sign-out flow with loading state and error handling. The component disables the button during the async operation to prevent double clicks. After successful sign-out, redirect using window.location.href for a full page reload that clears all in-memory JavaScript state.

typescript
1import { useState } from 'react';
2import { getAuth, signOut } from 'firebase/auth';
3
4export function SignOutButton() {
5 const [loading, setLoading] = useState(false);
6 const [error, setError] = useState<string | null>(null);
7
8 async function handleSignOut() {
9 setLoading(true);
10 setError(null);
11
12 try {
13 const auth = getAuth();
14 await signOut(auth);
15 window.location.href = '/login';
16 } catch (err) {
17 setError('Failed to sign out. Please try again.');
18 setLoading(false);
19 }
20 }
21
22 return (
23 <div>
24 <button onClick={handleSignOut} disabled={loading}>
25 {loading ? 'Signing out...' : 'Sign out'}
26 </button>
27 {error && <p style={{ color: 'red' }}>{error}</p>}
28 </div>
29 );
30}

Expected result: A functional sign-out button that shows loading state, handles errors, and redirects after successful logout.

4

Clear application state after sign-out

When a user signs out, you must clean up any user-specific data stored outside of Firebase Auth. This includes localStorage keys, sessionStorage, state management stores (Redux, Zustand), and any in-memory caches. Failing to clear this data can cause the next user who logs in to see stale data from the previous user.

typescript
1import { getAuth, signOut } from 'firebase/auth';
2
3async function fullSignOut() {
4 const auth = getAuth();
5
6 // 1. Sign out from Firebase
7 await signOut(auth);
8
9 // 2. Clear application-specific storage
10 const appKeys = ['userProfile', 'userSettings', 'cart', 'draftData'];
11 appKeys.forEach((key) => localStorage.removeItem(key));
12 sessionStorage.clear();
13
14 // 3. Reset state management store (example with Zustand)
15 // useStore.getState().reset();
16
17 // 4. Full page redirect to clear in-memory state
18 window.location.href = '/login';
19}

Expected result: All user-specific data is cleared from local storage, session storage, and state management. The app redirects to the login page with a clean state.

5

Handle sign-out in a React context provider

For applications with a centralized auth context, add the sign-out function to your context so any component can trigger logout. This pattern keeps auth logic in one place and provides the sign-out function through React context rather than importing Firebase directly in every component.

typescript
1import { createContext, useContext, useEffect, useState } from 'react';
2import { getAuth, onAuthStateChanged, signOut, User } from 'firebase/auth';
3
4interface AuthContextType {
5 user: User | null;
6 loading: boolean;
7 logout: () => Promise<void>;
8}
9
10const AuthContext = createContext<AuthContextType>({
11 user: null,
12 loading: true,
13 logout: async () => {}
14});
15
16export function AuthProvider({ children }: { children: React.ReactNode }) {
17 const [user, setUser] = useState<User | null>(null);
18 const [loading, setLoading] = useState(true);
19
20 useEffect(() => {
21 const auth = getAuth();
22 const unsubscribe = onAuthStateChanged(auth, (firebaseUser) => {
23 setUser(firebaseUser);
24 setLoading(false);
25 });
26 return () => unsubscribe();
27 }, []);
28
29 async function logout() {
30 const auth = getAuth();
31 await signOut(auth);
32 window.location.href = '/login';
33 }
34
35 return (
36 <AuthContext.Provider value={{ user, loading, logout }}>
37 {children}
38 </AuthContext.Provider>
39 );
40}
41
42export const useAuth = () => useContext(AuthContext);

Expected result: Any component in the app can call logout() from the useAuth() hook to trigger a sign-out with proper cleanup.

Complete working example

auth-signout.ts
1// Complete Firebase sign-out implementation
2// Handles auth state, cleanup, and redirect
3
4import { initializeApp } from 'firebase/app';
5import {
6 getAuth,
7 signOut,
8 onAuthStateChanged,
9 User
10} from 'firebase/auth';
11
12const firebaseConfig = {
13 apiKey: 'YOUR_API_KEY',
14 authDomain: 'YOUR_PROJECT.firebaseapp.com',
15 projectId: 'YOUR_PROJECT_ID',
16 storageBucket: 'YOUR_PROJECT.appspot.com',
17 messagingSenderId: 'YOUR_SENDER_ID',
18 appId: 'YOUR_APP_ID'
19};
20
21const app = initializeApp(firebaseConfig);
22const auth = getAuth(app);
23
24// Sign out and clean up all application state
25export async function handleSignOut(): Promise<void> {
26 try {
27 await signOut(auth);
28
29 // Clear application-specific cached data
30 const appKeys = ['userProfile', 'userSettings', 'cart'];
31 appKeys.forEach((key) => localStorage.removeItem(key));
32 sessionStorage.clear();
33
34 // Full page redirect to clear in-memory state
35 window.location.href = '/login';
36 } catch (error) {
37 console.error('Sign out failed:', error);
38 // Still redirect even if server-side cleanup fails
39 window.location.href = '/login';
40 }
41}
42
43// Initialize global auth state listener
44export function initAuthListener(
45 onSignIn: (user: User) => void,
46 onSignOut: () => void
47): () => void {
48 const unsubscribe = onAuthStateChanged(auth, (user) => {
49 if (user) {
50 onSignIn(user);
51 } else {
52 onSignOut();
53 }
54 });
55 return unsubscribe;
56}
57
58// Check current auth state
59export function getCurrentUser(): User | null {
60 return auth.currentUser;
61}

Common mistakes when signning Out a User in Firebase

Why it's a problem: Not clearing application state after sign-out, causing the next user to see stale data from the previous session

How to avoid: Clear all user-specific localStorage keys, sessionStorage, and state management stores after calling signOut(). Use a full page redirect with window.location.href for a clean slate.

Why it's a problem: Using React Router navigation instead of window.location.href after sign-out, leaving component state and context values in memory

How to avoid: Use window.location.href = '/login' to force a full page reload that clears all in-memory JavaScript state including React component trees.

Why it's a problem: Not unsubscribing from Firestore/RTDB listeners before sign-out, causing permission-denied errors in the console

How to avoid: Track all active real-time listeners and unsubscribe from them in your sign-out function before calling signOut(auth).

Best practices

  • Always redirect with window.location.href after sign-out for a full page reload that clears all JavaScript state
  • Set up onAuthStateChanged in your app root to centralize sign-out handling across the application
  • Clear localStorage, sessionStorage, and state management stores as part of the sign-out flow
  • Unsubscribe from all Firestore and Realtime Database listeners before signing out
  • Disable the sign-out button while the async operation is in progress to prevent double clicks
  • Provide the sign-out function through React context so components do not need to import Firebase directly
  • Handle sign-out errors gracefully and still redirect the user even if the server call fails

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

Show me how to sign out a user in Firebase Auth using the modular v9+ SDK. Include the signOut function, an onAuthStateChanged listener, error handling, clearing local storage, and a React component with loading state.

Firebase Prompt

Implement a complete Firebase Auth sign-out flow in a React TypeScript app using the modular SDK v9+. Include a reusable AuthContext provider with a logout function, onAuthStateChanged listener, localStorage cleanup, and a SignOutButton component.

Frequently asked questions

Does signOut() work when the user is offline?

Yes. signOut() clears the local session regardless of network connectivity. The ID token is invalidated locally, and any server-side revocation happens when the network is available.

Does signOut() sign out from all devices?

No. Firebase Auth signOut() only clears the session on the current device and browser. Other devices where the user is logged in remain signed in until their tokens expire or they sign out manually.

How do I force sign-out on all devices?

Use the Firebase Admin SDK on your server to call auth.revokeRefreshTokens(uid). This invalidates all refresh tokens for the user. On the client side, their session will fail on the next token refresh attempt.

Why do I get permission-denied errors in the console after signing out?

Active Firestore or Realtime Database listeners try to fetch data after the auth state changes to null. Since your security rules require authentication, these listeners receive permission-denied errors. Unsubscribe from all listeners before or during sign-out.

Can I run custom code before the user signs out?

Yes. Call your custom cleanup logic before calling signOut(auth). For example, save unsaved form data, unsubscribe from real-time listeners, or log analytics events before the auth session is cleared.

How do I prevent the sign-out button from being clicked twice?

Use a loading state variable that is set to true when sign-out starts. Disable the button when loading is true to prevent multiple clicks during the async operation.

Can RapidDev help build a complete authentication flow with Firebase?

Yes. RapidDev can implement end-to-end authentication including sign-up, sign-in, sign-out, session management, password reset, and protected routes in your Firebase application.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.