$col
A clean abstraction for working with Firestore collections in a consistent, typesafe, and test-friendly way. This utility standardizes how you add, fetch, and delete documents from Firestore collections, while handling errors gracefully using Result<T, E> wrappers.
Overview
This utility provides a uniform API for interacting with Firestore collections through:
add– Add or upsert documents to a collectionget– Retrieve all matching documentsdelete– Remove a document by ID
Each method returns a Result<T, string> for observability, testing, and consistent error handling.
API: $col(path, constraints?)
$col<Path extends string>(path: Path, constraints: QueryConstraint[] = [])Returns an object containing collection methods scoped to the given path.
Parameters
path: A string path to the Firestore collection (e.g.,"users","projects/123/tasks")constraints: Optional Firestore query constraints (e.g., filters, ordering, limits)
Methods
add(data: any, id?: string): Promise<Result<string, string>>
Adds a document to the collection. Optionally lets you specify the document ID.
await $col("projects").add({ name: "My Project" })
await $col("users").add({ name: "Alice" }, "user_123")- If
idis provided, performs an upsert usingsetDoc() - If no
id, usesaddDoc()and returns the generated ID - Always returns a
Result<string, string>
get(): Promise<Result<any[], string>>
Fetches all documents in the collection, optionally filtered via query constraints.
const res = await $col("users").get()
$res.match({
ok: ({ data }) => console.log("Users:", data),
err: ({ data }) => console.error("Failed to fetch users:", data),
})- Automatically maps document IDs into returned data objects
- Returns a
Result<T[], string>
delete(id: string): Promise<Result<string, string>>
Deletes a document by ID.
await $col("users").delete("user_123")- Uses the
path/idformat internally - Returns a
Result<string, string>containing the ID on success
SSR/Test Safe
In server-side or test environments (!import.meta.client), stub implementations are returned to avoid accidental reads/writes during rendering or test bootstrapping. These return successful ok(null) results and do not interact with Firestore.
Benefits
- ✅ Unified shape across all Firestore operations
- ✅ Type-safe and IDE-friendly
- ✅ Built-in error observability via
Result - ✅ SSR/test environment aware
- ✅ Pairs beautifully with the
$doc()and$result()helpers
Example
const projects = await $col("projects").get()
projects.match({
ok: ({ data }) => console.log("Projects:", data),
err: ({ data }) => console.error("Failed to load projects", data),
})This utility ensures you're never handling Firestore directly in your core logic. It’s composable, consistent, and built for scale.
Use it everywhere. No raw Firestore calls ever again.™