Skip to content

Commit

Permalink
Merge pull request #74 from erayerdin/dev
Browse files Browse the repository at this point in the history
v0.7.0
  • Loading branch information
erayerdin authored Feb 10, 2024
2 parents a8711d8 + d29b486 commit 138373e
Show file tree
Hide file tree
Showing 16 changed files with 99 additions and 129 deletions.
26 changes: 13 additions & 13 deletions docs/components/FirestoreDocument.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const docRef = doc(firestore, "yourCollection", "docId");

<FirestoreDocument
reference={docRef}
done={(snapshot) => {
onDone={(snapshot) => {
const id = snapshot.id;
const data = snapshot.data();

Expand All @@ -32,14 +32,14 @@ You can also define how your loading and error states will look like as such:
```typescript
<FirestoreDocument
reference={docRef}
loading={() => {
onLoading={() => {
return <div>Loading...</div>
}}
error={(error) => {
onError={(error) => {
// error: FirebaseError
return <div>{error.code}</div>
}}
done={(snapshot) => {
onDone={(snapshot) => {
// return a component when it's done
}}
/>
Expand All @@ -50,9 +50,9 @@ Or, in a shorter syntax:
```typescript
<FirestoreDocument
reference={docRef}
loading={() => (<div>Loading...</div>)}
error={(error) => (<div>{error.code}</div>)}
done={(snapshot) => {
onLoading={() => (<div>Loading...</div>)}
onError={(error) => (<div>{error.code}</div>)}
onDone={(snapshot) => {
// return a component when it's done
}}
/>
Expand All @@ -64,9 +64,9 @@ You can also listen to real-time changes in Firestore using `listen`:
<FirestoreDocument
reference={docRef}
listen
loading={() => (<div>Loading...</div>)}
error={(error) => (<div>{error.code}</div>)}
done={(snapshot) => {
onLoading={() => (<div>Loading...</div>)}
onError={(error) => (<div>{error.code}</div>)}
onDone={(snapshot) => {
// return a component when it's done
}}
/>
Expand All @@ -79,10 +79,10 @@ Input parameters for `FirestoreDocument` component is as follows:
| Name | Type | Description | Required | Default Value |
|---|---|---|---|---|
| `reference` | [`firebase/firestore/DocumentReference`][DocumentReferenceRefDoc] | Reference to a document in Firestore. || - |
| `done` | `(snapshot: DocumentSnapshot) => ReactNode`[^1] | The component to render when the process is done. || - |
| `onDone` | `(snapshot: DocumentSnapshot) => ReactNode`[^1] | The component to render when the process is done. || - |
| `listen` | `boolean` | Whether to listen to realtime changes of the document or not. || `false` |
| `loading` | `() => ReactNode` | The component to render while it's loading. || An empty component |
| `error` | `(error: FirebaseError) => ReactNode`[^2] | The component to render when a Firebase error occurs. || An empty component |
| `onLoading` | `() => ReactNode` | The component to render while it's loading. || An empty component |
| `onError` | `(error: FirebaseError) => ReactNode`[^2] | The component to render when a Firebase error occurs. || An empty component |

!!! note
`listen` is `false` by default to prevent unnecessary READ queries from Firestore.
Expand Down
9 changes: 4 additions & 5 deletions docs/hooks/useCollection.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,13 @@ Input parameters for `useCollection` hook is as follows:
| Name | Type | Description | Required | Default Value |
|---|---|---|---|---|
| `reference` | [`firebase/firestore/CollectionRefference`][CollectionReferenceRefDoc] or [`firebase/firestore/Query`][QueryRefDoc] | Reference to a collection in Firestore or a query. || - |
| `options` | Object | Options for the hook. || `{ listen: false }` |
| `options` | Object | Options for the hook. || See below. |
| `options.listen` | `boolean` | Whether to listen to realtime changes of the document or not. || `false` |
| `options.listenToMetadataChanges` | `boolean` | Whether to listen to realtime changes of the document or not as well as its metadata. See [this][EventsForMetadataChangesDoc]. || `false` |

!!! note
`options.listen` is `false` by default to prevent unnecessary READ queries from Firestore.

!!! warning
When `options.listen` is `true`, the change is reflected including the metadata changes on the document. See [this page](https://firebase.google.com/docs/firestore/query-data/listen#events-metadata-changes) to understand `includeMetadataChanges` option in Firestore.

## Return Type

`useCollection` hook returns an object with properties as below:
Expand All @@ -58,4 +56,5 @@ Input parameters for `useCollection` hook is as follows:
[CollectionReferenceRefDoc]: https://firebase.google.com/docs/reference/node/firebase.firestore.CollectionReference
[QueryRefDoc]: https://firebase.google.com/docs/reference/node/firebase.database.Query
[QuerySnapshotRefDoc]: https://firebase.google.com/docs/reference/node/firebase.firestore.QuerySnapshot
[FirebaseErrorRefDoc]: https://firebase.google.com/docs/reference/node/firebase.FirebaseError
[FirebaseErrorRefDoc]: https://firebase.google.com/docs/reference/node/firebase.FirebaseError
[EventsForMetadataChangesDoc]: https://firebase.google.com/docs/firestore/query-data/listen#events-metadata-changes
9 changes: 4 additions & 5 deletions docs/hooks/useDocument.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,13 @@ Input parameters for `useDocument` hook is as follows:
| Name | Type | Description | Required | Default Value |
|---|---|---|---|---|
| `reference` | [`firebase/firestore/DocumentReference`][DocumentReferenceRefDoc] | Reference to a document in Firestore. || - |
| `options` | Object | Options for the hook. || `{ listen: false }` |
| `options` | Object | Options for the hook. || See the following parameters. |
| `options.listen` | `boolean` | Whether to listen to realtime changes of the document or not. || `false` |
| `options.listenToMetadataChanges` | `boolean` | Whether to listen to realtime changes of the document as well its metadata. See [here][EventsForMetadataChangesDoc] || `false` |

!!! note
`options.listen` is `false` by default to prevent unnecessary READ queries from Firestore.

!!! warning
When `options.listen` is `true`, the change is reflected including the metadata changes on the document. See [this page](https://firebase.google.com/docs/firestore/query-data/listen#events-metadata-changes) to understand `includeMetadataChanges` option in Firestore.

## Return Type

`useDocument` hook returns an object with properties as below:
Expand All @@ -49,4 +47,5 @@ Input parameters for `useDocument` hook is as follows:

[DocumentReferenceRefDoc]: https://firebase.google.com/docs/reference/node/firebase.firestore.DocumentReference
[DocumentSnapshotRefDoc]: https://firebase.google.com/docs/reference/node/firebase.firestore.DocumentSnapshot
[FirebaseErrorRefDoc]: https://firebase.google.com/docs/reference/node/firebase.FirebaseError
[FirebaseErrorRefDoc]: https://firebase.google.com/docs/reference/node/firebase.FirebaseError
[EventsForMetadataChangesDoc]: https://firebase.google.com/docs/firestore/query-data/listen#events-metadata-changes
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "firereact",
"version": "0.6.5",
"version": "0.7.0",
"description": "React hooks, components and utils for Firebase",
"type": "module",
"main": "dist/index.cjs.js",
Expand Down
8 changes: 4 additions & 4 deletions src/firestore/FirestoreDocument.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ describe("initially FirestoreDocument component", () => {
render(
<FirestoreDocument
reference={docRef}
loading={() => <div>Loading...</div>}
done={() => <></>}
onLoading={() => <div>Loading...</div>}
onDone={() => <></>}
/>,
);
expect(screen.getByText("Loading...").innerHTML).toBe("Loading...");
Expand All @@ -39,8 +39,8 @@ describe("later FirestoreDocument component", () => {
render(
<FirestoreDocument
reference={docRef}
loading={() => <div>Loading...</div>}
done={(snapshot) => <div>{snapshot.data()?.displayName}</div>}
onLoading={() => <div>Loading...</div>}
onDone={(snapshot) => <div>{snapshot.data()?.displayName}</div>}
/>,
);
await sleep(250);
Expand Down
16 changes: 8 additions & 8 deletions src/firestore/FirestoreDocument.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,25 @@ import { useDocument } from ".";

type FirestoreDocumentProps = {
reference: DocumentReference;
loading?: () => ReactNode;
error?: (error: FirebaseError) => ReactNode;
done: (snapshot: DocumentSnapshot) => ReactNode;
onLoading?: () => ReactNode;
onError?: (error: FirebaseError) => ReactNode;
onDone: (snapshot: DocumentSnapshot) => ReactNode;
listen?: boolean;
};

export const FirestoreDocument = ({
reference,
loading = () => <></>,
onLoading = () => <></>,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
error = (_err) => <></>,
done,
onError = (_err) => <></>,
onDone,
listen = false,
}: FirestoreDocumentProps) => {
const {
loading: processing,
snapshot,
error: err,
} = useDocument({ reference, options: { listen } });
} = useDocument(reference, { listen });

return processing ? loading() : err ? error(err) : done(snapshot!);
return processing ? onLoading() : err ? onError(err) : onDone(snapshot!);
};
14 changes: 7 additions & 7 deletions src/firestore/useAddDocument.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ describe("initially useAddDocument hook", () => {
await deleteDoc(docRef);

// test
const { result } = renderHook(() => useAddDocument({ reference: colRef }));
const { result } = renderHook(() => useAddDocument(colRef));
const { state } = result.current;
expect(state).toBe("ready");

Expand All @@ -32,7 +32,7 @@ describe("initially useAddDocument hook", () => {
await deleteDoc(docRef);

// test
const { result } = renderHook(() => useAddDocument({ reference: colRef }));
const { result } = renderHook(() => useAddDocument(colRef));
const { reference } = result.current;
expect(reference).toBeUndefined();

Expand All @@ -45,7 +45,7 @@ describe("initially useAddDocument hook", () => {
await deleteDoc(docRef);

// test
const { result } = renderHook(() => useAddDocument({ reference: colRef }));
const { result } = renderHook(() => useAddDocument(colRef));
const { error } = result.current;
expect(error).toBeUndefined();

Expand All @@ -61,7 +61,7 @@ describe("as soon as dispatched, useAddDocument hook", () => {
await deleteDoc(docRef);

// test
const { result } = renderHook(() => useAddDocument({ reference: colRef }));
const { result } = renderHook(() => useAddDocument(colRef));
const { dispatch } = result.current;
dispatch(docData);
await sleep(30);
Expand All @@ -80,7 +80,7 @@ describe("after dispatched, useAddDocument hook", () => {
await deleteDoc(docRef);

// test
const { result } = renderHook(() => useAddDocument({ reference: colRef }));
const { result } = renderHook(() => useAddDocument(colRef));
const { dispatch } = result.current;
await dispatch(docData);
await sleep(250);
Expand All @@ -97,7 +97,7 @@ describe("after dispatched, useAddDocument hook", () => {
await deleteDoc(docRef);

// test
const { result } = renderHook(() => useAddDocument({ reference: colRef }));
const { result } = renderHook(() => useAddDocument(colRef));
const { dispatch } = result.current;
await dispatch(docData);
await sleep(250);
Expand All @@ -114,7 +114,7 @@ describe("after dispatched, useAddDocument hook", () => {
await deleteDoc(docRef);

// test
const { result } = renderHook(() => useAddDocument({ reference: colRef }));
const { result } = renderHook(() => useAddDocument(colRef));
const { dispatch } = result.current;
await dispatch(docData);
await sleep(250);
Expand Down
10 changes: 3 additions & 7 deletions src/firestore/useAddDocument.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@ import {
} from "firebase/firestore";
import { useState } from "react";

type UseAddDocumentParams = {
reference: CollectionReference;
};

type UseAddDocumentState = "ready" | "loading" | "done";
type UseAddDocumentDispatcher = (
data: DocumentData,
Expand All @@ -28,9 +24,9 @@ type UseAddDocument = {
error?: FirebaseError;
};

export const useAddDocument = ({
reference,
}: UseAddDocumentParams): UseAddDocument => {
export const useAddDocument = (
reference: CollectionReference,
): UseAddDocument => {
const [state, setState] = useState<UseAddDocumentState>("ready");
const [refer, setRefer] = useState<DocumentReference | undefined>();
const [error, setError] = useState<FirebaseError | undefined>();
Expand Down
12 changes: 6 additions & 6 deletions src/firestore/useCollection.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ describe("initially useCollection hook", () => {
await setDoc(docRef, docData);

// test
const { result } = renderHook(() => useCollection({ query: colRef }));
const { result } = renderHook(() => useCollection(colRef));
const { loading } = result.current;
expect(loading).toBe(true);

Expand All @@ -34,7 +34,7 @@ describe("initially useCollection hook", () => {
await setDoc(docRef, docData);

// test
const { result } = renderHook(() => useCollection({ query: colRef }));
const { result } = renderHook(() => useCollection(colRef));
const { snapshot } = result.current;
expect(snapshot).toBeUndefined();

Expand All @@ -48,7 +48,7 @@ describe("initially useCollection hook", () => {
await setDoc(docRef, docData);

// test
const { result } = renderHook(() => useCollection({ query: colRef }));
const { result } = renderHook(() => useCollection(colRef));
const { error } = result.current;
expect(error).toBeUndefined();

Expand All @@ -64,7 +64,7 @@ describe("later useCollection hook", () => {
await setDoc(docRef, docData);

// test
const { result } = renderHook(() => useCollection({ query: colRef }));
const { result } = renderHook(() => useCollection(colRef));
await sleep(250);
const { loading } = result.current;
expect(loading).toBe(false);
Expand All @@ -79,7 +79,7 @@ describe("later useCollection hook", () => {
await setDoc(docRef, docData);

// test
const { result } = renderHook(() => useCollection({ query: colRef }));
const { result } = renderHook(() => useCollection(colRef));
await sleep(250);
const { snapshot } = result.current;
expect(snapshot?.size).toBeGreaterThan(0);
Expand All @@ -94,7 +94,7 @@ describe("later useCollection hook", () => {
await setDoc(docRef, docData);

// test
const { result } = renderHook(() => useCollection({ query: colRef }));
const { result } = renderHook(() => useCollection(colRef));
await sleep(250);
const { error } = result.current;
expect(error).toBeUndefined();
Expand Down
25 changes: 12 additions & 13 deletions src/firestore/useCollection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@ import { FirebaseError } from "firebase/app";
import { Query, QuerySnapshot, getDocs, onSnapshot } from "firebase/firestore";
import { useEffect, useState } from "react";

type UseCollectionParams = {
query: Query;
options?: {
listen: boolean;
};
type UseCollectionOptions = {
listen?: boolean;
listenToMetadataChanges?: boolean;
};

type UseCollection = {
Expand All @@ -20,12 +18,13 @@ type UseCollection = {
error?: FirebaseError;
};

export const useCollection = ({
query,
options = { listen: false },
}: UseCollectionParams): UseCollection => {
const { listen } = options;

export const useCollection = (
query: Query,
{ listen, listenToMetadataChanges }: UseCollectionOptions = {
listen: false,
listenToMetadataChanges: false,
},
): UseCollection => {
const [loading, setLoading] = useState<boolean>(true);
const [snapshot, setSnapshot] = useState<QuerySnapshot | undefined>();
const [error, setError] = useState<FirebaseError | undefined>();
Expand All @@ -36,7 +35,7 @@ export const useCollection = ({
if (listen) {
const unsub = onSnapshot(
query,
{ includeMetadataChanges: true },
{ includeMetadataChanges: listenToMetadataChanges },
(snap) => {
setSnapshot(snap);
setLoading(false);
Expand All @@ -62,7 +61,7 @@ export const useCollection = ({
})
.finally(() => setLoading(false));
}
}, [listen, query]);
}, [query, listen, listenToMetadataChanges]);

return { loading, snapshot, error };
};
Loading

0 comments on commit 138373e

Please sign in to comment.