#firebase #firestore #grpc #gcp

firestore_grpc

A gRPC client library for Firestore, generated automatically from the API definition files in Google APIs

30 breaking releases

0.31.0 Apr 20, 2021
0.30.0 Nov 1, 2020
0.29.0 Jun 10, 2020
0.1.1 Mar 11, 2020

#475 in Network programming

Download history 37/week @ 2021-04-07 47/week @ 2021-04-14 68/week @ 2021-04-21 49/week @ 2021-04-28 11/week @ 2021-05-05 46/week @ 2021-05-12 53/week @ 2021-05-19 48/week @ 2021-05-26 3/week @ 2021-06-02 40/week @ 2021-06-09 6/week @ 2021-06-16 6/week @ 2021-06-23 8/week @ 2021-06-30 12/week @ 2021-07-07 37/week @ 2021-07-14 12/week @ 2021-07-21

161 downloads per month
Used in 2 crates

MIT license

3MB
2K SLoC

Prolog 2K SLoC Rust 28 SLoC Shell 6 SLoC

firestore-grpc

Firestore client library for Rust. If you use Cloud Run, please use https://github.com/gkkachi/firestore-grpc-cloudrun instead, which provides some useful functions such as get_client(), get_project_id().

Example

This example is experimental. In a real situation, you need to implement features such as token updates.

Environment variables

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

Code

Cargo.toml

[dependencies]
firestore_grpc = "0.31"
tokio = {version = "0.2", features = ["full"]}

main.rs

use firestore_grpc::tonic::{
    metadata::MetadataValue,
    transport::{Channel, ClientTlsConfig},
    Request,
};
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<Channel>, 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();
}

Dependencies

~15MB
~316K SLoC