Nested collections
You can work with nested collections specifying path/location to a parent for documents.
parent_path and the builder’s at also validate the collection name they are given, so a
FirestoreCollectionId or a bad raw &str is caught in the same call rather than at the server.
use firestore::*;
use futures::stream::BoxStream;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Deserialize, Serialize)]
struct MyParentStructure { some_id: String }
#[derive(Debug, Clone, Deserialize, Serialize)]
struct MyChildStructure { some_id: String }
const TEST_PARENT_COLLECTION_NAME: &str = "nested-test";
const TEST_CHILD_COLLECTION_NAME: &str = "test-childs";
async fn example(
db: FirestoreDb,
parent_struct: MyParentStructure,
child_struct: MyChildStructure,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
// Creating a parent doc
db.fluent()
.insert()
.into(TEST_PARENT_COLLECTION_NAME)
.document_id(&parent_struct.some_id)
.object(&parent_struct)
.execute::<()>()
.await?;
// The doc path where we store our children
let parent_path = db.parent_path(TEST_PARENT_COLLECTION_NAME, parent_struct.some_id)?;
// Create a child doc
db.fluent()
.insert()
.into(TEST_CHILD_COLLECTION_NAME)
.document_id(&child_struct.some_id)
.parent(&parent_path)
.object(&child_struct)
.execute::<()>()
.await?;
// Listing children
println!("Listing all children");
let objs_stream: BoxStream<MyChildStructure> = db
.fluent()
.list()
.from(TEST_CHILD_COLLECTION_NAME)
.parent(&parent_path)
.obj()
.stream_all()
.await?;
let _ = objs_stream;
Ok(())
}
Complete example available here.
You can nest multiple levels of collections using at():
use firestore::*;
const TEST_PARENT_COLLECTION_NAME: &str = "nested-test";
const TEST_CHILD_COLLECTION_NAME: &str = "test-childs";
const TEST_GRANDCHILD_COLLECTION_NAME: &str = "test-grandchilds";
fn example(db: &FirestoreDb) -> Result<(), Box<dyn std::error::Error>> {
let parent_path = db
.parent_path(TEST_PARENT_COLLECTION_NAME, "parent-id")?
.at(TEST_CHILD_COLLECTION_NAME, "child-id")?
.at(TEST_GRANDCHILD_COLLECTION_NAME, "grand-child-id")?;
let _ = parent_path;
Ok(())
}