Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Firestore database client instance and lifecycle

To create a new instance of Firestore client you need to provide at least a GCP project ID. It is not recommended creating a new client for each request, so it is recommended to create a client once and reuse it whenever possible. Cloning instances is much cheaper than creating a new one.

The client is created using the Firestore::new method:

fn config_env_var(name: &str) -> Result<String, String> {
    std::env::var(name).map_err(|e| format!("{name}: {e}"))
}
async fn example() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
use firestore::*;

// Create an instance
let db = FirestoreDb::new(&config_env_var("PROJECT_ID")?).await?;
Ok(())
}

This is the recommended way to create a new instance of the client, since it automatically detects the environment and uses credentials, service accounts, Workload Identity on GCP, etc. Look at the section below Google authentication for more details.

In cases if you need to create a new instance explicitly specifying a key file, you can use:

use firestore::*;
fn config_env_var(name: &str) -> Result<String, String> {
    std::env::var(name).map_err(|e| format!("{name}: {e}"))
}
async fn example() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
FirestoreDb::with_options_service_account_key_file(
    FirestoreDbOptions::new(config_env_var("PROJECT_ID")?.to_string()),
    "/tmp/key.json".into(),
)
.await?
;
Ok(())
}

or if you need even more flexibility you can use a preconfigured token source and scopes with:

use firestore::*;
fn config_env_var(name: &str) -> Result<String, String> {
    std::env::var(name).map_err(|e| format!("{name}: {e}"))
}
async fn example() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
FirestoreDb::with_options_token_source(
    FirestoreDbOptions::new(config_env_var("PROJECT_ID")?.to_string()),
    gcloud_sdk::GCP_DEFAULT_SCOPES.clone(),
    gcloud_sdk::TokenSourceType::File("/tmp/key.json".into()),
)
.await?
;
Ok(())
}

Firebase supports multiple databases per project now, so you can specify the database ID in the options:

use firestore::*;
async fn example() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
FirestoreDb::with_options(
    FirestoreDbOptions::new("your-project-id".to_string())
        .with_database_id("your-database-id".to_string()),
)
.await?
;
Ok(())
}