#firestore #grpc-client #grpc #firebase #gcp #google-api

firestore_grpc

Firestore的gRPC客户端库,由Google API中的API定义文件自动生成

172次重大版本发布

0.229.0 2024年8月18日
0.227.0 2024年8月4日
0.226.0 2024年7月28日
0.209.0 2024年3月31日
0.1.1 2020年3月11日

#908 in 网络编程

Download history 291/week @ 2024-04-27 259/week @ 2024-05-04 265/week @ 2024-05-11 255/week @ 2024-05-18 275/week @ 2024-05-25 381/week @ 2024-06-01 312/week @ 2024-06-08 291/week @ 2024-06-15 242/week @ 2024-06-22 262/week @ 2024-06-29 238/week @ 2024-07-06 171/week @ 2024-07-13 188/week @ 2024-07-20 187/week @ 2024-07-27 158/week @ 2024-08-03 170/week @ 2024-08-10

每月709次下载
用于 4 crate

MIT 许可证

7MB

firestore-grpc

Firestore的Rust客户端库。如果您使用Cloud Run,请使用https://github.com/gkkachi/firestore-grpc-cloudrun,它提供了一些有用的功能,例如 get_client()get_project_id()

示例

此示例是实验性的。在实际情况下,您需要实现功能,例如令牌更新。

环境变量

export PROJECT_ID=YOUR_PROJECT_ID
export TOKEN=`gcloud auth print-access-token`

代码

Cargo.toml

[dependencies]
firestore_grpc = "0.109"
tokio = {version = "1.0", features = ["full"]}

main.rs

use firestore_grpc::tonic::{
    codegen::InterceptedService,
    metadata::MetadataValue,
    transport::{Channel, ClientTlsConfig},
    Request, Status,
};
use firestore_grpc::v1::{
    firestore_client::FirestoreClient, value::ValueType, CreateDocumentRequest, Document, Value,
};
use std::env;

const URL: &'static str = "https://firestore.googleapis.com";
const DOMAIN: &'static str = "firestore.googleapis.com";

pub type BoxError = Box<dyn std::error::Error + Sync + Send + 'static>;

fn get_token() -> String {
    env::var("TOKEN").unwrap()
}

fn get_project_id() -> String {
    env::var("PROJECT_ID").unwrap()
}

async fn get_client() -> Result<FirestoreClient<InterceptedService<Channel, impl Fn(Request<()>) -> Result<Request<()>, Status>>>, BoxError> {
    let endpoint = Channel::from_static(URL).tls_config(ClientTlsConfig::new().domain_name(DOMAIN));

    let bearer_token = format!("Bearer {}", get_token());
    let header_value = MetadataValue::from_str(&bearer_token)?;

    let channel = endpoint?.connect().await?;

    let service = FirestoreClient::with_interceptor(channel, move |mut req: Request<()>| {
        req.metadata_mut()
            .insert("authorization", header_value.clone());
        Ok(req)
    });
    Ok(service)
}

async fn create_document() -> Result<Document, BoxError> {
    let parent = format!(
        "projects/{}/databases/(default)/documents",
        get_project_id()
    );
    let collection_id = "greetings".into();
    let document_id = "".into();
    let mut fields = std::collections::HashMap::new();
    fields.insert(
        "message".into(),
        Value {
            value_type: Some(ValueType::StringValue("Hello world!".into())),
        },
    );
    let document = Some(Document {
        name: "".into(),
        fields,
        create_time: None,
        update_time: None,
    });
    let res = get_client()
        .await?
        .create_document(CreateDocumentRequest {
            parent,
            collection_id,
            document_id,
            document,
            mask: None,
        })
        .await?;
    Ok(res.into_inner())
}

#[tokio::main]
async fn main() {
    create_document().await.unwrap();
}

依赖关系

~13–24MB
~423K SLoC