Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ typed abstractions that work with Firebase's web SDK (`firebase/firestore`).
- `useCollection`, `useCollectionOnce` - Collection query hooks
- `getDocument*`, `getSpecificDocument*` - Non-hook fetch functions for use with
ReactQuery etc.
- `setDocument`, `setSpecificDocument` - Create or overwrite documents
- `updateDocument`, `updateSpecificDocument` - Partially update documents
- `deleteDocument`, `deleteSpecificDocument` - Delete documents
- `makeDocument`, `makeMutableDocument` - Factory functions

**Error Handling**: Hooks throw errors instead of returning them (except
Expand Down
21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,23 @@ const { data, isError } = useQuery({
| `getSpecificDocumentData` | Fetch only the data part of a specific document |
| `getSpecificDocumentInTransaction` | Fetch a specific document as part of a transaction |

### Write Functions

Standalone functions for creating, updating, and deleting documents without
fetching them first. Useful when you already know the document path and just want
to write.

| Function | Description |
| ------------------------ | ----------------------------------------------- |
| `setDocument` | Create or overwrite a document (supports merge) |
| `setSpecificDocument` | Create or overwrite a specific document |
| `updateDocument` | Partially update an existing document |
| `updateSpecificDocument` | Partially update an existing specific document |
| `deleteDocument` | Delete a document |
| `deleteSpecificDocument` | Delete a specific document |

The `set*` functions accept an optional `SetOptions` parameter for `{ merge: true }` or `{ mergeFields: [...] }` behavior. The `*Specific*` variants accept a `DocumentReference` directly instead of a collection ref + id.

## Working with Documents

The default immutable document type is `FsDocument<T>`. Use this type when you
Expand Down Expand Up @@ -167,7 +184,9 @@ for more info.

## Client-Side Mutations

In my projects I prefer to have all mutations happen on the server-side via an
This library provides both document-level mutation methods (on `FsMutableDocument`) and standalone [write functions](#write-functions) (`setDocument`, `updateDocument`, `deleteDocument`, etc.) for performing client-side writes.

That said, in my projects I prefer to have all mutations happen on the server-side via an
API call. You might want to consider that, especially if older versions of your
app could be around for a while, like with mobile apps. A bug in client-side
code could have lasting effects on the consistency of your database, and
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * from "./make-mutable-document";
export * from "./types";
export * from "./use-collection";
export * from "./use-document";
export * from "./write-document";
84 changes: 84 additions & 0 deletions src/write-document.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import {
doc,
setDoc,
updateDoc,
deleteDoc,
type CollectionReference,
type DocumentData,
type DocumentReference,
type PartialWithFieldValue,
type SetOptions,
type UpdateData,
type WithFieldValue,
} from "firebase/firestore";

export function setDocument<T extends DocumentData>(
collectionRef: CollectionReference<T>,
documentId: string,
data: WithFieldValue<T>,
): Promise<void>;
export function setDocument<T extends DocumentData>(
collectionRef: CollectionReference<T>,
documentId: string,
data: PartialWithFieldValue<T>,
options: SetOptions,
): Promise<void>;
export function setDocument<T extends DocumentData>(
collectionRef: CollectionReference<T>,
documentId: string,
data: WithFieldValue<T> | PartialWithFieldValue<T>,
options?: SetOptions,
): Promise<void> {
if (options) {
return setDoc(doc(collectionRef, documentId), data as PartialWithFieldValue<T>, options);
}
return setDoc(doc(collectionRef, documentId), data as WithFieldValue<T>);
}
Comment thread
0x80 marked this conversation as resolved.

export function setSpecificDocument<T extends DocumentData>(
documentRef: DocumentReference<T>,
data: WithFieldValue<T>,
): Promise<void>;
export function setSpecificDocument<T extends DocumentData>(
documentRef: DocumentReference<T>,
data: PartialWithFieldValue<T>,
options: SetOptions,
): Promise<void>;
export function setSpecificDocument<T extends DocumentData>(
documentRef: DocumentReference<T>,
data: WithFieldValue<T> | PartialWithFieldValue<T>,
options?: SetOptions,
): Promise<void> {
if (options) {
return setDoc(documentRef, data as PartialWithFieldValue<T>, options);
}
return setDoc(documentRef, data as WithFieldValue<T>);
}

export function updateDocument<T extends DocumentData>(
collectionRef: CollectionReference<T>,
documentId: string,
data: UpdateData<T>,
): Promise<void> {
return updateDoc(doc(collectionRef, documentId), data);
}

export function updateSpecificDocument<T extends DocumentData>(
documentRef: DocumentReference<T>,
data: UpdateData<T>,
): Promise<void> {
return updateDoc(documentRef, data);
}

export function deleteDocument<T extends DocumentData>(
collectionRef: CollectionReference<T>,
documentId: string,
): Promise<void> {
return deleteDoc(doc(collectionRef, documentId));
}

export function deleteSpecificDocument<T extends DocumentData>(
documentRef: DocumentReference<T>,
): Promise<void> {
return deleteDoc(documentRef);
}