News & Updates

How to Add Firebase Authentication to a Python FastAPI App

By Julian Ashford 5 min read 2754 views

How to Add Firebase Authentication to a Python FastAPI App

FastAPI’s speed and modern design make it a favorite for building APIs, but handling user authentication can feel like a separate beast. Luckily, Firebase Authentication offers a ready‑made, scalable solution that pairs nicely with Python. In this guide we’ll walk through the essentials: setting up a Firebase project, wiring the SDK into FastAPI, and protecting endpoints with JWT validation.

Why Pair Firebase with FastAPI?

Firebase takes care of the heavy lifting—email/password sign‑in, social providers, token refresh, and even password resets—while FastAPI handles the business logic. The result is a clean separation: you focus on your domain, Firebase handles identity.

  • Scalable out of the box: No need to manage a separate user database.
  • Built‑in security: Tokens are signed with Google’s private keys, making forgery extremely unlikely.
  • Cross‑platform support: Same auth flow works for web, iOS, Android, or other back‑ends.

Prerequisites

Before diving in, make sure you have:

  • Python 3.9+ installed.
  • FastAPI and uvicorn (run pip install fastapi uvicorn).
  • A Firebase project (you’ll need the serviceAccountKey.json file).
  • The firebase-admin Python package (pip install firebase-admin).

Step 1 – Create and Configure the Firebase Project

Head to the Firebase console and create a new project if you haven’t already. Under “Authentication” enable the sign‑in methods you need—email/password is the simplest start.

Next, generate a service account:

  1. Project Settings → Service Accounts.
  2. Click “Generate new private key” and download the JSON file.
  3. Store this file securely; you’ll reference it in your FastAPI code.

Step 2 – Initialize Firebase Admin SDK in FastAPI

Place the downloaded serviceAccountKey.json somewhere your app can read it (e.g., a config/ folder). Then, add the initialization code:

import firebase_admin

from firebase_admin import credentials, auth

cred = credentials.Certificate('config/serviceAccountKey.json')

firebase_admin.initialize_app(cred)

It’s usually a good idea to wrap this in a separate module, say auth_firebase.py, so you can import auth wherever you need it.

Step 3 – Verify ID Tokens in a Dependency

FastAPI’s dependency injection system shines for auth. Here’s a compact dependency that extracts the bearer token, verifies it with Firebase, and raises an HTTP 401 if anything’s off:

from fastapi import Depends, Header, HTTPException, status

from firebase_admin import auth

async def get_current_user(authorization: str = Header(...)):

if not authorization.startswith('Bearer '):

raise HTTPException(

status_code=status.HTTP_401_UNAUTHORIZED,

detail='Invalid authentication scheme.'

)

id_token = authorization.split(' ')[1]

try:

decoded_token = auth.verify_id_token(id_token)

return decoded_token # contains uid, email, etc.

except Exception:

raise HTTPException(

status_code=status.HTTP_401_UNAUTHORIZED,

detail='Could not validate credentials.'

)

This function can now be used as a Depends argument on any route that requires a logged‑in user.

Step 4 – Protect Your Endpoints

Let’s see the dependency in action. The following route returns the authenticated user's UID and email:

from fastapi import FastAPI, Depends

app = FastAPI()

@app.get("/me")

async def read_current_user(user: dict = Depends(get_current_user)):

return {"uid": user['uid'], "email": user.get('email')}

Try hitting /me with a valid Firebase ID token in the Authorization header, and you’ll get a JSON payload with the user’s info. If the token is missing or expired, FastAPI automatically responds with a 401.

Step 5 – Refresh Tokens on the Client Side

Firebase issues short‑lived ID tokens (about one hour). The client SDK automatically refreshes them, but if you’re writing a custom client you’ll need to call the Firebase REST endpoint https://securetoken.googleapis.com/v1/token with the refresh token. From the server’s perspective, you don’t need to do anything—just keep verifying whatever token arrives.

Handling Edge Cases

Real‑world apps rarely have a single happy path. Here are a few gotchas you might run into:

  • Revoked tokens: Users can be forced to sign out from the Firebase console. Call auth.check_revoked_id_token() if you need to enforce immediate revocation.
  • Custom claims: Want to add roles like “admin”? Use auth.set_custom_user_claims(uid, {'admin': True}) and check the claim in get_current_user.
  • Rate limits: Firebase Admin SDK caches public keys, but extremely high request volumes might still hit limits. Consider adding a thin caching layer around token verification if you anticipate heavy traffic.

Testing Locally

When you run uvicorn main:app --reload, you can test with the Firebase CLI’s auth:emulators:start to spin up a local auth emulator. It mimics the real service, letting you generate test tokens without touching production data.

Deploying to Production

On a cloud platform (e.g., Railway, Render, or AWS Lambda via Mangum), make sure the service account JSON isn’t baked into the image. Instead, store it as an environment variable or secret, write it to a temporary file at startup, and point the SDK to that path. This keeps your credentials out of version control.

Where to Go From Here

Firebase Authentication is just one piece of the puzzle. Once you’ve secured your API, you might want to:

  • Integrate Firestore for user‑specific data.
  • Use Firebase Cloud Messaging to push notifications based on FastAPI events.
  • Add rate limiting or API keys for public endpoints.

All of those extensions still play nicely with the same authentication flow we built here.

FastAPI Authentication Guide | PropelAuth
Authentication & Protocols: Setting up Python FastAPI with Google OAuth ...
Firebase Authentication
How To Integrate Firebase Authentication With A React Application ...

Written by Julian Ashford

Julian Ashford is a Chief Correspondent with over a decade of experience covering breaking trends, in-depth analysis, and exclusive insights.