# How to Sign Out an User in Firebase

- Tool: Firebase
- Difficulty: Beginner
- Time required: 5-10 min
- Compatibility: Firebase Auth (Spark and Blaze plans), firebase v9+ modular SDK
- Last updated: March 2026

## 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.

## Before you start

- 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.

```
import { getAuth, signOut } from 'firebase/auth';
import { app } from './firebase'; // your Firebase app instance

const auth = getAuth(app);

async function handleSignOut() {
  try {
    await signOut(auth);
    console.log('User signed out successfully');
    // Redirect to login page
    window.location.href = '/login';
  } catch (error) {
    console.error('Sign out error:', error);
  }
}
```

**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.

```
import { getAuth, onAuthStateChanged } from 'firebase/auth';

const auth = getAuth(app);

onAuthStateChanged(auth, (user) => {
  if (user) {
    // User is signed in
    console.log('Signed in as:', user.email);
  } else {
    // User is signed out
    console.log('User signed out');
    // Clear any cached user data
    localStorage.removeItem('userProfile');
    sessionStorage.clear();
  }
});
```

**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.

```
import { useState } from 'react';
import { getAuth, signOut } from 'firebase/auth';

export function SignOutButton() {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  async function handleSignOut() {
    setLoading(true);
    setError(null);

    try {
      const auth = getAuth();
      await signOut(auth);
      window.location.href = '/login';
    } catch (err) {
      setError('Failed to sign out. Please try again.');
      setLoading(false);
    }
  }

  return (
    <div>
      <button onClick={handleSignOut} disabled={loading}>
        {loading ? 'Signing out...' : 'Sign out'}
      </button>
      {error && <p style={{ color: 'red' }}>{error}</p>}
    </div>
  );
}
```

**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.

```
import { getAuth, signOut } from 'firebase/auth';

async function fullSignOut() {
  const auth = getAuth();

  // 1. Sign out from Firebase
  await signOut(auth);

  // 2. Clear application-specific storage
  const appKeys = ['userProfile', 'userSettings', 'cart', 'draftData'];
  appKeys.forEach((key) => localStorage.removeItem(key));
  sessionStorage.clear();

  // 3. Reset state management store (example with Zustand)
  // useStore.getState().reset();

  // 4. Full page redirect to clear in-memory state
  window.location.href = '/login';
}
```

**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.

```
import { createContext, useContext, useEffect, useState } from 'react';
import { getAuth, onAuthStateChanged, signOut, User } from 'firebase/auth';

interface AuthContextType {
  user: User | null;
  loading: boolean;
  logout: () => Promise<void>;
}

const AuthContext = createContext<AuthContextType>({
  user: null,
  loading: true,
  logout: async () => {}
});

export function AuthProvider({ children }: { children: React.ReactNode }) {
  const [user, setUser] = useState<User | null>(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const auth = getAuth();
    const unsubscribe = onAuthStateChanged(auth, (firebaseUser) => {
      setUser(firebaseUser);
      setLoading(false);
    });
    return () => unsubscribe();
  }, []);

  async function logout() {
    const auth = getAuth();
    await signOut(auth);
    window.location.href = '/login';
  }

  return (
    <AuthContext.Provider value={{ user, loading, logout }}>
      {children}
    </AuthContext.Provider>
  );
}

export 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 code example

File: `auth-signout.ts`

```typescript
// Complete Firebase sign-out implementation
// Handles auth state, cleanup, and redirect

import { initializeApp } from 'firebase/app';
import {
  getAuth,
  signOut,
  onAuthStateChanged,
  User
} from 'firebase/auth';

const firebaseConfig = {
  apiKey: 'YOUR_API_KEY',
  authDomain: 'YOUR_PROJECT.firebaseapp.com',
  projectId: 'YOUR_PROJECT_ID',
  storageBucket: 'YOUR_PROJECT.appspot.com',
  messagingSenderId: 'YOUR_SENDER_ID',
  appId: 'YOUR_APP_ID'
};

const app = initializeApp(firebaseConfig);
const auth = getAuth(app);

// Sign out and clean up all application state
export async function handleSignOut(): Promise<void> {
  try {
    await signOut(auth);

    // Clear application-specific cached data
    const appKeys = ['userProfile', 'userSettings', 'cart'];
    appKeys.forEach((key) => localStorage.removeItem(key));
    sessionStorage.clear();

    // Full page redirect to clear in-memory state
    window.location.href = '/login';
  } catch (error) {
    console.error('Sign out failed:', error);
    // Still redirect even if server-side cleanup fails
    window.location.href = '/login';
  }
}

// Initialize global auth state listener
export function initAuthListener(
  onSignIn: (user: User) => void,
  onSignOut: () => void
): () => void {
  const unsubscribe = onAuthStateChanged(auth, (user) => {
    if (user) {
      onSignIn(user);
    } else {
      onSignOut();
    }
  });
  return unsubscribe;
}

// Check current auth state
export function getCurrentUser(): User | null {
  return auth.currentUser;
}
```

## Common mistakes

- **Not clearing application state after sign-out, causing the next user to see stale data from the previous session** — undefined Fix: 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.
- **Using React Router navigation instead of window.location.href after sign-out, leaving component state and context values in memory** — undefined Fix: Use window.location.href = '/login' to force a full page reload that clears all in-memory JavaScript state including React component trees.
- **Not unsubscribing from Firestore/RTDB listeners before sign-out, causing permission-denied errors in the console** — undefined Fix: 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

## 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.

---

Source: https://www.rapidevelopers.com/firebase-tutorial/how-to-sign-out-a-user-in-firebase
© RapidDev — https://www.rapidevelopers.com/firebase-tutorial/how-to-sign-out-a-user-in-firebase
