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 FirestoreDb::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(())
}
The key file is read as a service account key.
For any other credentials use FirestoreDb::with_options_auth, which takes everything that converts into gcloud-sdk’s
GoogleAuthHeaders:
Credentialsfrom the builders offirestore::gcloud_sdk::google_cloud_auth::credentials: service account keys, user credentials, impersonation, workload identity federation, the metadata server, etc.;- a
CredentialsProviderof your own, passed toCredentials::from; GoogleAuthHeaders::from_adc_with_scopesfor the Application Default Credentials with other scopes;GoogleAuthHeaders::from_service_account_keyfor a service account key with other scopes.
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_auth(
FirestoreDbOptions::new(config_env_var("PROJECT_ID")?.to_string()),
firestore::gcloud_sdk::GoogleAuthHeaders::from_adc_with_scopes(vec![
"https://www.googleapis.com/auth/datastore".to_string(),
])
.await?,
)
.await?
;
Ok(())
}
These types come from gcloud-sdk, which the library re-exports as firestore::gcloud_sdk,
so your project needs no gcloud-sdk dependency of its own.
Full example with a custom CredentialsProvider available here.
Multiple databases
Firestore supports multiple databases per project, 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(())
}
The edition, Standard or Enterprise, belongs to a database, so the database ID chooses it too. A project can hold databases of both editions, and a client per database ID reaches each. See Standard and Enterprise editions for what each edition runs.