Firebase Admin SDK for Rust
Warning This library is currently in an experimental state. The API is subject to change, and features may be incomplete or unstable. Use at your own risk in production environments.
A Rust implementation of the Firebase Admin SDK. This library allows you to interact with Firebase services such as Authentication, Cloud Messaging (FCM), Remote Config, and Firestore from your Rust backend.
Features
- Authentication: User management (create, update, delete, list, get), ID token verification, custom token creation, multi-tenancy support, and OIDC/SAML provider configuration.
- Cloud Messaging (FCM): Send messages (single, batch, multicast), manage topics, and support for all target types (token, topic, condition).
- Remote Config: Get the active template, publish new templates (with ETag optimistic concurrency), rollback to previous versions, and list versions.
- Firestore: Read and write documents, manage collections, perform atomic batch writes and transactions, and support real-time updates via the
listen()API. - Storage: Upload, download, manage files, and generate V4 signed URLs in Google Cloud Storage buckets.
- Crashlytics: Programmatically remove crash reports for specific users (e.g., for privacy compliance).
Installation
Add this to your Cargo.toml:
[]
= "0.1.0" # Replace with actual version
= { = "1", = ["full"] }
= { = "1.0", = ["derive"] }
= "0.3" # Required for Firestore Listen API streams
Usage
Initialization
The entry point for the SDK is the FirebaseApp struct. You will need a service account JSON file from the Firebase Console.
use ;
async
Authentication Example
use CreateUserRequest;
async
Cloud Messaging Example
use ;
async
Remote Config Example
async
Firestore Example
use json;
async
Firestore Listen Example (Real-time Updates)
You can listen for real-time updates on a document or an entire collection using the listen() method.
use StreamExt;
async
Storage Example
async
Crashlytics Example
async
Roadmap & TODO
- Realtime Database: Implement support for reading and writing to the Firebase Realtime Database.
- Machine Learning: Add support for Firebase ML Model management.
- Auth: Add support for OIDC and SAML provider configuration.
- Storage: Add support for setting and updating object metadata.
- General: Improve error handling and add more comprehensive integration tests.
Architecture and Patterns
This SDK is designed with specific architectural patterns to ensure usability, performance, and reliability.
1. Synchronous Constructor, Lazy Asynchronous Authentication
One of the key design goals was to keep the FirebaseApp::new() constructor synchronous. In Rust, async constructors are not idiomatic and can complicate application startup logic.
However, Firebase APIs require OAuth2 authentication, which involves asynchronous HTTP requests to fetch tokens. To bridge this gap, we use a lazy initialization pattern:
FirebaseApp::new()simply stores theServiceAccountKeyand returns immediately.- The HTTP client uses a custom
AuthMiddleware. - This middleware contains a
tokio::sync::OnceCellthat holds the authenticator. - The first time any API request is made (e.g.,
auth.get_user(...)), the middleware checks theOnceCell. If it's empty, it asynchronously initializes the OAuth2 authenticator and fetches a token. - Subsequent requests reuse the initialized authenticator and cached tokens.
2. Middleware Stack
The SDK leverages reqwest_middleware to build a robust HTTP client stack:
- Retry Middleware: Automatically retries failed requests (with exponential backoff) for transient errors (e.g., network blips, 5xx server errors).
- Auth Middleware: Transparently handles OAuth2 token acquisition and injection into the
Authorizationheader.
This separation of concerns keeps the business logic in the service modules (Auth, Messaging, etc.) clean and focused on the Firebase APIs themselves.
3. Factory Pattern
FirebaseApp acts as a lightweight factory and configuration holder.
- Calling
app.auth()orapp.messaging()creates a new, lightweight client instance. - These instances share the underlying
ServiceAccountKey(cloned cheaply) but are otherwise independent. - This allows you to easily create clients where needed without worrying about complex lifecycle management.
4. Type-Safe API
Where possible, the SDK uses strong typing to prevent runtime errors:
- FCM: The
Messagestruct uses generic builders or strictly typed fields to ensure valid payloads. - Remote Config: The
ETagis handled automatically to ensure safe concurrent updates (If-Matchheaders). - Firestore: The
DocumentReferenceandCollectionReferencetypes mirror the path structure of your database.