firebase_rs_sdk/firestore/mod.rs
1//! # Firebase Firestore module
2//!
3//! This module ports core pieces of the Firestore SDK to Rust so applications
4//! can discover collections and create, update, retrieve and delete documents.
5//!
6//! It provides functionality to interact with Firestore, including retrieving and querying documents,
7//! working with collections, and managing real-time updates.
8//!
9//! It includes error handling, configuration options, and integration with Firebase apps.
10//!
11//! ## Features
12//!
13//! - Connect to Firestore emulator
14//! - Get Firestore instance for a Firebase app
15//! - Register Firestore component
16//! - Manage collections and documents
17//! - Build and execute queries
18//! - Comprehensive error handling
19//!
20//! ## References to the Firebase JS SDK - firestore module
21//!
22//! - QuickStart: <https://firebase.google.com/docs/firestore/quickstart>
23//! - API: <https://firebase.google.com/docs/reference/js/firestore.md#firestore_package>
24//! - Github Repo - Module: <https://github.com/firebase/firebase-js-sdk/tree/main/packages/firestore>
25//! - Github Repo - API: <https://github.com/firebase/firebase-js-sdk/tree/main/packages/firebase/firestore>
26//!
27//! ## Development status as of 14th October 2025
28//!
29//! - Core functionalities: Mostly implemented (see the module's [README.md](https://github.com/dgasparri/firebase-rs-sdk/tree/main/src/firestore) for details)
30//! - Tests: 31 tests (passed)
31//! - Documentation: Most public functions are documented
32//! - Examples: None provided
33//!
34//! DISCLAIMER: This is not an official Firebase product, nor it is guaranteed that it has no bugs or that it will work as intended.
35//!
36//! # Example
37//!
38//! ```rust,no_run
39//! use firebase_rs_sdk::app::api::initialize_app;
40//! use firebase_rs_sdk::app::{FirebaseAppSettings, FirebaseOptions};
41//! use firebase_rs_sdk::app_check::api::{custom_provider, initialize_app_check, token_with_ttl};
42//! use firebase_rs_sdk::app_check::{AppCheckOptions, FirebaseAppCheckInternal};
43//! use firebase_rs_sdk::auth::api::auth_for_app;
44//! use firebase_rs_sdk::firestore::*;
45//! use std::collections::BTreeMap;
46//! use std::time::Duration;
47//!
48//! fn main() -> Result<(), Box<dyn std::error::Error>> {
49//! // TODO: replace with your project configuration
50//! let options = FirebaseOptions {
51//! project_id: Some("your-project".into()),
52//! // add other Firebase options as needed
53//! ..Default::default()
54//! };
55//! let app = initialize_app(options, Some(FirebaseAppSettings::default()))?;
56//! let auth = auth_for_app(app.clone())?;
57//!
58//! // Optional: wire App Check tokens into Firestore.
59//! let app_check_provider = custom_provider(|| token_with_ttl("fake-token", Duration::from_secs(60)));
60//! let app_check = initialize_app_check(Some(app.clone()), AppCheckOptions::new(app_check_provider))?;
61//! let app_check_internal = FirebaseAppCheckInternal::new(app_check);
62//!
63//! let firestore = get_firestore(Some(app.clone()))?;
64//! let client = FirestoreClient::with_http_datastore_authenticated(
65//! firebase_rs_sdk::firestore::api::Firestore::from_arc(firestore.clone()),
66//! auth.token_provider(),
67//! Some(app_check_internal.token_provider()),
68//! )?;
69//!
70//! let mut ada = BTreeMap::new();
71//! ada.insert("first".into(), FirestoreValue::from_string("Ada"));
72//! ada.insert("last".into(), FirestoreValue::from_string("Lovelace"));
73//! ada.insert("born".into(), FirestoreValue::from_integer(1815));
74//! let ada_snapshot = client.add_doc("users", ada)?;
75//! println!("Document written with ID: {}", ada_snapshot.id());
76//!
77//! let mut alan = BTreeMap::new();
78//! alan.insert("first".into(), FirestoreValue::from_string("Alan"));
79//! alan.insert("middle".into(), FirestoreValue::from_string("Mathison"));
80//! alan.insert("last".into(), FirestoreValue::from_string("Turing"));
81//! alan.insert("born".into(), FirestoreValue::from_integer(1912));
82//! let alan_snapshot = client.add_doc("users", alan)?;
83//! println!("Document written with ID: {}", alan_snapshot.id());
84//!
85//! Ok(())
86//! }
87//! ```
88//!
89//! If App Check is not enabled for your app, pass `None` as the third argument to
90//! `with_http_datastore_authenticated`.
91//!
92//! Using Converters:
93//!
94//! ```rust,no_run
95//! use firebase_rs_sdk::app::*;
96//! use firebase_rs_sdk::firestore::*;
97//! use std::collections::BTreeMap;
98//!
99//! #[derive(Clone)]
100//! struct MyUser {
101//! name: String,
102//! }
103//!
104//! #[derive(Clone)]
105//! struct UserConverter;
106//!
107//! impl FirestoreDataConverter for UserConverter {
108//! type Model = MyUser;
109//!
110//! fn to_map(
111//! &self,
112//! value: &Self::Model,
113//! ) -> FirestoreResult<BTreeMap<String, FirestoreValue>> {
114//! // Encode your model into Firestore fields.
115//! todo!()
116//! }
117//!
118//! fn from_map(&self, value: &MapValue) -> FirestoreResult<Self::Model> {
119//! // Decode Firestore fields into your model.
120//! todo!()
121//! }
122//! }
123//!
124//! fn example_with_converter(firestore: &Firestore, client: &FirestoreClient) -> FirestoreResult<Option<MyUser>> {
125//! let users = firestore.collection("typed-users")?.with_converter(UserConverter);
126//! let doc = users.doc(Some("ada"))?;
127//! client.set_doc_with_converter(&doc, MyUser { name: "Ada".to_string() }, None)?;
128//! let typed_snapshot = client.get_doc_with_converter(&doc)?;
129//! let user: Option<MyUser> = typed_snapshot.data()?;
130//! Ok(user)
131//! }
132//! ```
133
134pub mod api;
135mod constants;
136pub mod error;
137pub mod model;
138pub mod remote;
139pub mod value;
140
141#[doc(inline)]
142pub use api::{
143 get_firestore, register_firestore_component, CollectionReference, ConvertedCollectionReference,
144 ConvertedDocumentReference, ConvertedQuery, DocumentReference, DocumentSnapshot,
145 FilterOperator, Firestore, FirestoreClient, FirestoreDataConverter, LimitType, OrderDirection,
146 PassthroughConverter, Query, QuerySnapshot, SetOptions, SnapshotMetadata,
147 TypedDocumentSnapshot, TypedQuerySnapshot,
148};
149
150#[doc(inline)]
151pub use api::query::QueryDefinition;
152
153#[doc(inline)]
154pub use constants::{DEFAULT_DATABASE_ID, FIRESTORE_COMPONENT_NAME};
155
156#[doc(inline)]
157pub use model::{DatabaseId, DocumentKey, FieldPath, GeoPoint, ResourcePath, Timestamp};
158
159#[doc(inline)]
160pub use remote::{
161 map_http_error, Connection, ConnectionBuilder, Datastore, HttpDatastore, InMemoryDatastore,
162 JsonProtoSerializer, NoopTokenProvider, RequestContext, RetrySettings, TokenProviderArc,
163};
164
165#[doc(inline)]
166pub use remote::datastore::{http::HttpDatastoreBuilder, TokenProvider};
167
168#[doc(inline)]
169pub use value::{ArrayValue, BytesValue, FirestoreValue, MapValue, ValueKind};
170
171#[doc(inline)]
172pub use error::{FirestoreError, FirestoreErrorCode, FirestoreResult};