diff --git a/Cargo.toml b/Cargo.toml index d1a94ae..411008d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,7 @@ caching-persistent = ["caching", "dep:redb"] [dependencies] tracing = "0.1" -gcloud-sdk = { version = "0.23", features = ["google-firestore-v1"] } +gcloud-sdk = { version = "0.24", features = ["google-firestore-v1"] } hyper = { version ="0.14" } struct-path = "0.2" rvstruct = "0.3.2" @@ -71,4 +71,3 @@ required-features = ["caching-memory"] name = "caching_persistent_test" path = "tests/caching_persistent_test.rs" required-features = ["caching-persistent"] - diff --git a/examples/token_auth.rs b/examples/token_auth.rs new file mode 100644 index 0000000..f018cc3 --- /dev/null +++ b/examples/token_auth.rs @@ -0,0 +1,78 @@ +use chrono::{DateTime, Utc}; +use firestore::*; +use futures::stream::BoxStream; +use futures::TryStreamExt; +use serde::{Deserialize, Serialize}; +use std::ops::Add; + +pub fn config_env_var(name: &str) -> Result { + std::env::var(name).map_err(|e| format!("{}: {}", name, e)) +} + +// Example structure to play with +#[derive(Debug, Clone, Deserialize, Serialize)] +struct MyTestStructure { + some_id: String, + some_string: String, + one_more_string: String, + some_num: u64, + created_at: DateTime, +} + +async fn my_token() -> gcloud_sdk::error::Result { + Ok(gcloud_sdk::Token::new( + "Bearer".to_string(), + gcloud_sdk::SecretValue::from(config_env_var("TOKEN_VALUE")?), + chrono::Utc::now().add(std::time::Duration::from_secs(3600)), + )) +} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Logging with debug enabled + let subscriber = tracing_subscriber::fmt() + .with_env_filter("firestore=debug") + .finish(); + tracing::subscriber::set_global_default(subscriber)?; + + // Create an instance + let db = FirestoreDb::with_options_token_source( + FirestoreDbOptions::new(config_env_var("PROJECT_ID")?), + gcloud_sdk::GCP_DEFAULT_SCOPES.clone(), + gcloud_sdk::TokenSourceType::ExternalSource(Box::new( + gcloud_sdk::ExternalJwtFunctionSource::new(my_token), + )), + ) + .await?; + + const TEST_COLLECTION_NAME: &'static str = "test-query"; + + // Query as a stream our data + let object_stream: BoxStream> = db + .fluent() + .select() + .fields( + paths!(MyTestStructure::{some_id, some_num, some_string, one_more_string, created_at}), + ) + .from(TEST_COLLECTION_NAME) + .filter(|q| { + q.for_all([ + q.field(path!(MyTestStructure::some_num)).is_not_null(), + q.field(path!(MyTestStructure::some_string)).eq("Test"), + Some("Test2") + .and_then(|value| q.field(path!(MyTestStructure::one_more_string)).eq(value)), + ]) + }) + .order_by([( + path!(MyTestStructure::some_num), + FirestoreQueryDirection::Descending, + )]) + .obj() + .stream_query_with_errors() + .await?; + + let as_vec: Vec = object_stream.try_collect().await?; + println!("{:?}", as_vec); + + Ok(()) +}