firebase-admin-python
Google's official Python SDK for privileged server-side access to Firebase Auth, Firestore, Cloud Messaging, Storage, and Remote Config.
Repository Health
Technical Analysis
firebase-admin is Google’s official Firebase Admin SDK for Python, giving trusted server environments (backends, Cloud Functions, batch jobs) elevated, non-user-scoped access to Firebase services. Where the client SDKs enforce per-user security rules in the browser or on-device, this SDK runs with service-account credentials and bypasses those rules by design, which is exactly what a privileged backend needs to mint custom auth tokens, manage users in bulk, send push notifications, or read and write Firestore/Realtime Database data on behalf of the whole application.
The package is organized as one App object per Firebase project plus a set of independent service modules — auth, firestore, messaging, db, storage, remote_config, app_check, and more — each exposing its own factory function or client object rather than one monolithic API surface. Internally it layers on google-auth for credential handling, google-api-core/google-cloud-firestore/google-cloud-storage for the services that already have first-party Google Cloud clients, and a centralized httpx-based HTTP client (with a synchronous and an asyncio-native variant) for the Firebase-specific REST APIs that don’t have their own client library.
It’s the SDK teams reach for when they need to verify or mint Firebase ID tokens outside a Cloud Function trigger, manage users and custom claims from an admin panel, send FCM push notifications to millions of devices via topic or token, or read Firestore/Realtime Database data with service-account privileges rather than a signed-in user’s.
What You Get
- Auth administration - create, look up, update, and delete users; mint and verify custom/ID tokens; manage custom claims, sessions, and multi-tenancy from
firebase_admin.auth. - Firestore & Realtime Database access - privileged read/write access to both databases via
firebase_admin.firestore(sync and async) andfirebase_admin.db, without going through per-user security rules. - Cloud Messaging (FCM) - send push notifications to individual devices, device batches, or topics, and manage topic subscriptions via
firebase_admin.messaging. - Cloud Storage integration - get a configured Google Cloud Storage bucket handle scoped to the Firebase project’s default bucket via
firebase_admin.storage. - Remote Config & App Check - programmatically read and publish Remote Config templates, and validate App Check tokens from trusted backends.
- Multiple credential strategies - Application Default Credentials, a service-account JSON key file, or a Google OAuth2 refresh token, all normalized behind one
credentialsmodule.
Common Use Cases
- Custom authentication backends - a server issues its own login logic (e.g. against a legacy user store) and mints Firebase custom tokens so clients can sign in with the standard client SDKs.
- Bulk user management - admin tooling or migration scripts that create, update, disable, or delete large numbers of Firebase Auth users outside the Firebase console.
- Server-triggered push notifications - a backend event (order shipped, new message) sends an FCM notification to a specific device token or topic without exposing sender credentials to the client.
- Privileged data access from Cloud Functions or Cloud Run - server code reads/writes Firestore or Realtime Database data across all users, bypassing per-document security rules that apply to client SDKs.
- Session and claims management - a backend sets custom claims (roles, plan tier) on a user’s ID token so Firestore security rules or client logic can branch on them.
Under The Hood
Architecture
The SDK is organized around a lightweight App object (in firebase_admin/__init__.py) that holds a credential and per-project options, created once via initialize_app() and cached in a module-level, thread-locked _apps dict keyed by app name; every service module (auth.py, firestore.py, messaging.py, db.py, etc.) then exposes module-level functions or a client()/bucket() factory that lazily instantiates and caches a per-app service client rather than requiring the caller to construct one directly. Two client patterns coexist by design — “direct action” modules like auth and db that expose functions performing the work immediately, and “client factory” modules like firestore and storage that hand back a long-lived client object — and the project’s own AGENTS.md documents this split explicitly as a convention contributors must preserve, which is an unusually clear architectural contract for a Python SDK of this size (926 lines in auth.py alone, 620 in messaging.py).
Tech Stack
Python 3.9+ (3.9 deprecated, 3.10+ recommended), built on google-auth/google-api-core[grpc] for credential and gRPC transport handling, google-cloud-firestore and google-cloud-storage for the services that already have first-party Google Cloud client libraries, pyjwt[crypto] for custom-token signing and verification, and httpx[http2] powering a centralized _http_client.py that provides both a synchronous JsonHttpClient and an asyncio-native HttpxAsyncClient used by every Firebase-only REST API (messaging, remote config, app check) that doesn’t have its own Google Cloud client.
Code Quality
The repository ships a large, service-scoped unit test suite under tests/ (one file per service module, e.g. test_auth_providers.py, test_messaging.py, test_firestore_async.py) alongside a separate integration/ suite that exercises the SDK against a real Firebase project via pytest fixtures in conftest.py, plus a strict .pylintrc enforced through a repo lint.sh script and a nightly-build GitHub Actions workflow. Error handling is centralized and typed rather than ad hoc: every SDK exception inherits from firebase_admin.exceptions.FirebaseError, with platform-wide subclasses (InvalidArgumentError, UnauthenticatedError, PermissionDeniedError, and others) populated from HTTP responses through shared _utils.handle_platform_error_from_requests()/_from_httpx() helpers, giving callers one exception hierarchy to catch regardless of which underlying transport raised it.
API Design
The public API favors small, focused functions over deep object hierarchies — most operations are a single module-level call (auth.create_user(...), messaging.send(...)) that implicitly resolves the default App unless one is passed explicitly, keeping single-project usage nearly boilerplate-free while still supporting multi-project setups by name. Async support is bolted on consistently rather than as an afterthought: any operation with meaningful I/O latency exposes an _async sibling (send_each_async, firestore_async) backed by the dedicated HttpxAsyncClient, and the project’s own AGENTS.md contributor guide — an unusually thorough piece of internal documentation for a library this size — makes the direct-action-vs-client-factory distinction and error-handling conventions explicit for anyone extending the SDK.