Jump to content

Building a Firestore Database CLI with Rust: Difference between revisions

From JOHNWICK
PC (talk | contribs)
Created page with "This article leverages the Gemini CLI and the underlying Gemini LLM to develop native compiled code built in the Rust Language for integration to the Firestore NOSQL database. A fully functional CLI is developed in Rust for interacting with a remote Firestore database hosted in Google Cloud directly from the command line. What is Rust? Rust is a high performance, memory safe, compiled language: Rust A language empowering everyone to build reliable and efficient software...."
 
(No difference)

Latest revision as of 17:05, 15 November 2025

This article leverages the Gemini CLI and the underlying Gemini LLM to develop native compiled code built in the Rust Language for integration to the Firestore NOSQL database. A fully functional CLI is developed in Rust for interacting with a remote Firestore database hosted in Google Cloud directly from the command line. What is Rust? Rust is a high performance, memory safe, compiled language: Rust A language empowering everyone to build reliable and efficient software. www.rust-lang.org

Rust provides memory safe operations beyond C/C++ and also can provide exceptional performance gains as it is compiled directly to native binaries. Initial Environment Setup The environment is meant to be run from a Bash like shell. You can run this from a Linux VM, ChromeOS Linux VM, Firebase Studio environment, or any environment that provides a basic shell. Rust Setup Instructions to install Rust are available here: Getting started A language empowering everyone to build reliable and efficient software. www.rust-lang.org

For a Linux like environment the command looks like this: curl — proto ‘=https’ — tlsv1.2 -sSf https://sh.rustup.rs | sh What is Firestore? Google Firestore, also known as Cloud Firestore is a part of the Google Firebase application development platform. It is fundamentally a cloud-hosted NoSQL database for storing and syncing data. Firestore can be directly accessed by mobile and web applications through native SDKs. Cloud Firestore | Store and sync app data at global scale Discover Firebase, Google’s mobile and web app development platform that helps developers build apps and games that… firebase.google.com

Rust Deployment Strategy Rust has not been the typical deployment path for Firestore software development — so a step by step approach is used with validation at each milestone. Clone the Samples Repo and Setup the Basic Environment Now that the Gemini CLI and the Rust installation has been validated from the base shell — you can clone the GitHub Repo with support scripts: cd ~ git clone https://github.com/xbill9/gemini-cli-codeassist Then run init.sh from the cloned directory. The script will attempt to determine your shell environment and set the correct variables: cd gemini-cli-codeassist source init.sh Set application default credentials for authentication: gcloud auth application-default login Debugging API Permission Errors If your application default credentials expires or your Google Cloud Authentication expires you will get an error similar to this: Finished `dev` profile [unoptimized + debuginfo] target(s) in 27.94s

    Running `target/debug/firestore-client-rust`

Starting client API call Project comglitn Error: Error { kind: Authentication, source: Some(CredentialsError { is_transient: false, message: Some("Request to fetch the token failed. Subsequent calls with this credential will also fail."), source: Some(Error { kind: Authentication, source: Some(CredentialsError { is_transient: false, message: Some("failed to refresh user access token, body=<{\n \"error\": \"invalid_grant\",\n \"error_description\": \"reauth related error (invalid_rapt)\",\n \"error_uri\": \"https://support.google.com/a/answer/9368756\",\n \"error_subtype\": \"invalid_rapt\"\n}>"), source: Some(reqwest::Error { kind: Status(400, None), url: "https://oauth2.googleapis.com/token" }) }) }) }) } The workaround is to re-authenticate: gcloud auth login gcloud auth application-default login Another common error is that the environment variables are not set correctly. Go the the root directory and re-run the set_env.sh to set the variables: cd ~/gemini-cli-codeassist source set_env.sh Basic Firestore Library in Rust Native Code The first step is to build a minimal Rust client sample that connects to Firestore using the Rust native Firestore libraries. The most popular implementation is the firestore crate: firestore — Rust Firestore for Rust docs.rs GitHub — abdolence/firestore-rs: Google Firestore for Rust based on gRPC API with Serde serializer Google Firestore for Rust based on gRPC API with Serde serializer — abdolence/firestore-rs github.com

Debugging and Logging with Rust The environment variable RUST_LOG controls how verbose the logging from the Rust code will produce messages. Initially — set the variable to info: export RUST_LOG=info echo $RUST_LOG info Rust Log Levels These levels filter messages based on their severity, from most critical to least:

  • ERROR: Only error messages are logged.
  • WARN: Warning messages and higher (error) are logged.
  • INFO: Informational messages and higher (warn, error) are logged.
  • DEBUG: Debug messages and higher (info, warn, error) are logged.
  • TRACE: Trace messages and higher (debug, info, warn, error) are logged. This is the most verbose level.
  • OFF: Disables all logging.

Next Steps- Build Rust Sample Client Code A basic native Rust client sample the makes a direct connection to Firestore has been included in the GitHub repo. Change to the sample directory and validate the Cargo.toml file for the minimal sample: cd ~/gemini-cli-codeassist/firestore-cli-rust pwd /home/xbill/gemini-cli-codeassist/firestore-cli-rust The Rust standard format file Cargo.toml contains details about the code: head Cargo.toml [package] name = "firestore-cli-rust" version = "0.1.0" edition = "2024" description = "Basic Rust local Connection CLI tool to Firestore" license = "MIT" repository = "https://github.com/xbill9/gemini-cli-codeassist" Build the Firestore client sample with the Makefile: xbill@penguin:~/gemini-cli-codeassist/firestore-cli-rust$ make release Building Release...

  Compiling firestore-cli-rust v0.1.0 (/home/xbill/gemini-cli-codeassist/firestore-cli-rust)
   Finished `release` profile [optimized] target(s) in 7.38s

Then run the generated Rust binary: ./target/release/firestore-cli-rust Basic Rust local Connection CLI tool to Firestore firestore-cli> help Basic Rust local CLI tool to Firestore Usage: firestore-cli-rust <COMMAND> Commands:

 seed    Seeds the Firestore database with initial product data
 list    Lists all products in the Firestore database
 get     Gets a product by its ID from the Firestore database
 search  Searches for products by name
 help    Print this message or the help of the given subcommand(s)

Options:

 -h, --help     Print help
 -V, --version  Print version

firestore-cli> The Firestore integration has been bundled as a basic CLI in the firestore-cli-rust binary to allow real-time validation of the connection to Firestore from the Rust client code. Seed the Firestore Database with Sample Data To pre-populate the sample test data in the Firestore database- use the seed command: ./target/release/firestore-cli-rust seed 2025-10-10T15:17:38.497028Z INFO firestore::db: Creating a new database client. database_path="projects/comglitn/databases/(default)" api_url="https://firestore.googleapis.com" token_scopes="https://www.googleapis.com/auth/cloud-platform" 2025-10-10T15:17:38.615203Z INFO firestore_client_rust: Seeding database... 2025-10-10T15:17:44.374093Z INFO firestore_client_rust: Database seeded successfully. Get a List of Products from Firestore This command lists the products that have just been seeded: ./target/release/firestore-cli-rust list 2025-10-10T15:19:32.689483Z INFO firestore_client_rust: Product { id: None, name: "Sunflower Seeds", price: 2.0, quantity: 337, imgfile: "product-images/sunflowerseeds.png", timestamp: 2025-03-02T07:20:37.494Z, actualdateadded: 2025-09-23T15:39:43.851Z } 2025-10-10T15:19:32.689492Z INFO firestore_client_rust: Product { id: None, name: "Parmesan Crisps", price: 4.0, quantity: 69, imgfile: "product-images/parmesancrisps.png", timestamp: 2025-09-19T22:43:17.206Z, actualdateadded: 2025-09-23T15:39:44.035Z } 2025-10-10T15:19:32.689502Z INFO firestore_client_rust: Product { id: None, name: "Black Beans", price: 7.0, quantity: 488, imgfile: "product-images/blackbeans.png", timestamp: 2024-09-16T18:02:45.258Z, actualdateadded: 2025-09-23T15:39:42.844Z } Lookup A Product by ID Another feature of the client is to look up a product by the Firestore ID: ./target/release/firestore-cli-rust list | grep coffee 2025-10-10T15:21:42.964343Z INFO firestore_client_rust: Product { id: Some("28JSxzPTzljYcwUvUZUH"), name: "Coffee Beans", price: 8.318669309680374, quantity: 211, imgfile: "product-images/coffeebeans.png", timestamp: 2024-12-31T15:17:38.615278383Z, actualdateadded: 2025-10-10T15:17:38.615278608Z } 2025-10-10T15:21:42.964612Z INFO firestore_client_rust: Product { id: None, name: "Coffee Beans", price: 2.0468191712577912, quantity: 480, imgfile: "product-images/coffeebeans.png", timestamp: 2024-10-14T20:40:44.060282548Z, actualdateadded: 2025-10-09T20:40:44.060283278Z } xbill@penguin:~/gemini-cli-codeassist/firestore-client-rust$ ./target/release/firestore-client-rust get 28JSxzPTzljYcwUvUZUH 2025-10-10T15:21:54.307875Z INFO firestore::db: Creating a new database client. database_path="projects/comglitn/databases/(default)" api_url="https://firestore.googleapis.com" token_scopes="https://www.googleapis.com/auth/cloud-platform" 2025-10-10T15:21:54.368794Z INFO firestore_client_rust: Fetching product by id: 28JSxzPTzljYcwUvUZUH 2025-10-10T15:21:54.733277Z INFO firestore_client_rust: Found product: Product { id: Some("28JSxzPTzljYcwUvUZUH"), name: "Coffee Beans", price: 8.318669309680374, quantity: 211, imgfile: "product-images/coffeebeans.png", timestamp: 2024-12-31T15:17:38.615278383Z, actualdateadded: 2025-10-10T15:17:38.615278608Z } xbill@penguin:~/gemini-cli-codeassist/firestore-client-rust$ Perform a Code Review with Rust Tools First — basic Rust tools are used to review and check the code. The key Rust tool for lint code is clippy: GitHub — rust-lang/rust-clippy: A bunch of lints to catch common mistakes and improve your Rust… A bunch of lints to catch common mistakes and improve your Rust code. Book: https://doc.rust-lang.org/clippy/ … github.com The main commands include — Checking versions in Cargo.toml for updates: cargo update Checking for syntax issues: cargo check Linting code: cargo clippy Formatting code: cargo fmt Deep Dive with Rust Logging Update the RUST_LOG environment variable to a more granular level to get deeper visibility into the Firestore connection : export RUST_LOG=debug echo $RUST_LOG debug

Now re-run the Firestore connection with the new log level: ./target/release/firestore-cli-rust get 28JSxzPTzljYcwUvUZUH 2025–10–10T15:51:02.711441Z INFO firestore::db: Creating a new database client. database_path=”projects/comglitn/databases/(default)” api_url=”https://firestore.googleapis.com" token_scopes=”https://www.googleapis.com/auth/cloud-platform" 2025–10–10T15:51:02.711480Z DEBUG gcloud_sdk::api_client: Creating a new Google API client for https://firestore.googleapis.com. Scopes: [“https://www.googleapis.com/auth/cloud-platform"] 2025–10–10T15:51:02.735501Z DEBUG rustls::webpki::anchors: add_parsable_certificates processed 143 valid and 0 invalid certs 2025–10–10T15:51:03.330295Z DEBUG Connection{peer=Client}: h2::codec::framed_write: send frame=Ping { ack: true, payload: [0, 0, 0, 0, 0, 0, 2, 28] } 2025–10–10T15:51:03.331053Z DEBUG gcloud_sdk::middleware: OK: /google.firestore.v1.Firestore/GetDocument took 524ms (incl. token gen: 156ms) 2025–10–10T15:51:03.331306Z DEBUG Firestore Get Doc{/firestore/collection_name=”inventory” /firestore/document_name=”projects/comglitn/databases/(default)/documents/inventory/28JSxzPTzljYcwUvUZUH” /firestore/response_time=524}: firestore::db::get: Read document. document_path=”projects/comglitn/databases/(default)/documents/inventory/28JSxzPTzljYcwUvUZUH” duration_milliseconds=524 2025–10–10T15:51:03.331659Z INFO firestore_client_rust: Found product: Product { id: Some(“28JSxzPTzljYcwUvUZUH”), name: “Coffee Beans”, price: 8.318669309680374, quantity: 211, imgfile: “product-images/coffeebeans.png”, timestamp: 2024–12–31T15:17:38.615278383Z, actualdateadded: 2025–10–10T15:17:38.615278608Z } Package Information on crates.io The complete firestore-cli-rust is available on the Rust crates.io site: crates.io: Rust Package Registry Edit description crates.io


Summary A complete Rust native CLI client was built and testing using the Gemini CLI along with Rust libraries for a direct connection to Google Firestore- a NOSQL database hosted in Google Cloud. This compiled Rust code was then called directly from the local shell and performed interactive operations against the backing Firestore Database. The overall goal was to validate the Rust Firestore client libraries and the environment needed to successfully connect to a Firestore Database from Rust native compiled code.