@tatsuokaniwa/swr-firestore 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +192 -0
- package/dist/hooks/useCollection.d.ts +5 -0
- package/dist/hooks/useCollectionCount.d.ts +4 -0
- package/dist/hooks/useCollectionGroup.d.ts +5 -0
- package/dist/hooks/useCollectionGroupCount.d.ts +4 -0
- package/dist/hooks/useDoc.d.ts +5 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +4427 -0
- package/dist/index.umd.cjs +4429 -0
- package/dist/manifest.json +7 -0
- package/dist/util/getConverter.d.ts +3 -0
- package/dist/util/type.d.ts +11 -0
- package/package.json +77 -0
package/README.md
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# swr-firestore
|
|
2
|
+
|
|
3
|
+
React Hooks library for Firestore, built using the Firebase v9 modular SDK. It utilizes the [`useSWRSubscription`](https://swr.vercel.app/ja/docs/subscription) function from SWR library to enable subscription-based data fetching and caching.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { useCollection, useCollectionCount } from "@tatsuokaniwa/swr-firestore";
|
|
9
|
+
import { initializeApp } from "firebase/app";
|
|
10
|
+
import { getFirestore } from "firebase/firestore";
|
|
11
|
+
|
|
12
|
+
initializeApp();
|
|
13
|
+
const db = getFirestore();
|
|
14
|
+
|
|
15
|
+
type Post = {
|
|
16
|
+
content: string;
|
|
17
|
+
status: "draft" | "published";
|
|
18
|
+
createdAt: Date;
|
|
19
|
+
};
|
|
20
|
+
export default function App() {
|
|
21
|
+
// Conditional Fetching
|
|
22
|
+
const [isLogin, setIsLogin] = useState(false);
|
|
23
|
+
const { data } = useCollection<Post>(
|
|
24
|
+
isLogin
|
|
25
|
+
? {
|
|
26
|
+
path: "Posts",
|
|
27
|
+
where: [["status", "==", "published"]],
|
|
28
|
+
orderBy: [["createdAt", "desc"]],
|
|
29
|
+
parseDates: ["createdAt"],
|
|
30
|
+
}
|
|
31
|
+
: null
|
|
32
|
+
);
|
|
33
|
+
const { data: postCount } = useCollectionCount<Post>({
|
|
34
|
+
path: "Posts",
|
|
35
|
+
where: [["status", "==", "published"]],
|
|
36
|
+
});
|
|
37
|
+
return (
|
|
38
|
+
<div>
|
|
39
|
+
<h1>{postCount} posts</h1>
|
|
40
|
+
{data?.map((x, i) => (
|
|
41
|
+
<div key={i}>
|
|
42
|
+
{x.content} {x.createdAt.toLocaleString()}
|
|
43
|
+
</div>
|
|
44
|
+
))}
|
|
45
|
+
<button onClick={() => setIsLogin(!isLogin)}>Toggle auth</button>
|
|
46
|
+
</div>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## API
|
|
52
|
+
|
|
53
|
+
### Type definitions for parameters
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
import type { orderBy, where } from "firebase/firestore";
|
|
57
|
+
// First argument of hook, specifies options to firestore, and is also used as a key for SWR.
|
|
58
|
+
type KeyParams<T> = {
|
|
59
|
+
// The path to the collection or document of Firestore.
|
|
60
|
+
path: string;
|
|
61
|
+
where?: [Extract<keyof T, string>, Parameters<typeof where>[1], ValueOf<T>][];
|
|
62
|
+
orderBy?: [Extract<keyof T, string>, Parameters<typeof orderBy>[1]][];
|
|
63
|
+
limit?: number;
|
|
64
|
+
// Array of field names that should be parsed as dates.
|
|
65
|
+
parseDates?: Extract<keyof T, string>[];
|
|
66
|
+
};
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Type definitions for return data
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
import type { QueryDocumentSnapshot } from "firebase/firestore";
|
|
73
|
+
|
|
74
|
+
type DocumentData<T> = T & Pick<QueryDocumentSnapshot, "exists" | "id" | "ref">;
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### `useCollection(params)`
|
|
78
|
+
|
|
79
|
+
Subscription for collection
|
|
80
|
+
|
|
81
|
+
#### Parameters
|
|
82
|
+
|
|
83
|
+
- `params`: KeyParams | null
|
|
84
|
+
|
|
85
|
+
#### Return values
|
|
86
|
+
|
|
87
|
+
- `data`: data for given path's collection
|
|
88
|
+
- `error`: FirestoreError | Error
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
import { useCollection } from "@tatsuokaniwa/swr-firestore";
|
|
92
|
+
|
|
93
|
+
const { data, error } = useCollection<Post>({
|
|
94
|
+
path: "Posts",
|
|
95
|
+
});
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### `useCollectionCount(params, swrOptions)`
|
|
99
|
+
|
|
100
|
+
Wrapper for getCountFromServer for collection
|
|
101
|
+
|
|
102
|
+
#### Parameters
|
|
103
|
+
|
|
104
|
+
- `params`: KeyParams except `orderBy`, `parseDates` | null
|
|
105
|
+
- `swrOptions`: [Options for SWR hook](https://swr.vercel.app/docs/api#options) except `fetcher`
|
|
106
|
+
|
|
107
|
+
#### Return values
|
|
108
|
+
|
|
109
|
+
Returns [`SWRResponse`](https://swr.vercel.app/docs/api#return-values)
|
|
110
|
+
|
|
111
|
+
- `data`: number for given path's collection count result
|
|
112
|
+
- `error`: FirestoreError | Error
|
|
113
|
+
- `isLoading`: if there's an ongoing request and no "loaded data". Fallback data and previous data are not considered "loaded data"
|
|
114
|
+
- `isValidating`: if there's a request or revalidation loading
|
|
115
|
+
- `mutate(data?, options?)`: function to mutate the cached data (details)
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
import { useCollectionCount } from "@tatsuokaniwa/swr-firestore";
|
|
119
|
+
|
|
120
|
+
const {
|
|
121
|
+
data: postCount,
|
|
122
|
+
error,
|
|
123
|
+
isLoading,
|
|
124
|
+
} = useCollectionCount<Post>({
|
|
125
|
+
path: "Posts",
|
|
126
|
+
});
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### `useCollectionGroup(params)`
|
|
130
|
+
|
|
131
|
+
Subscription for collectionGroup
|
|
132
|
+
|
|
133
|
+
#### Parameters
|
|
134
|
+
|
|
135
|
+
- `params`: KeyParams | null
|
|
136
|
+
|
|
137
|
+
#### Return values
|
|
138
|
+
|
|
139
|
+
- `data`: data for given path's collectionGroup
|
|
140
|
+
- `error`: FirestoreError | Error
|
|
141
|
+
|
|
142
|
+
### `useCollectionGroupCount(params, swrOptions)`
|
|
143
|
+
|
|
144
|
+
Wrapper for getCountFromServer for collectionGroup
|
|
145
|
+
|
|
146
|
+
#### Parameters
|
|
147
|
+
|
|
148
|
+
- `params`: KeyParams except `orderBy`, `parseDates` | null
|
|
149
|
+
- `swrOptions`: [Options for SWR hook](https://swr.vercel.app/docs/api#options) except `fetcher`
|
|
150
|
+
|
|
151
|
+
#### Return values
|
|
152
|
+
|
|
153
|
+
Returns [`SWRResponse`](https://swr.vercel.app/docs/api#return-values)
|
|
154
|
+
|
|
155
|
+
- `data`: number for given path's collectionGroup count result
|
|
156
|
+
- `error`: FirestoreError | Error
|
|
157
|
+
- `isLoading`: if there's an ongoing request and no "loaded data". Fallback data and previous data are not considered "loaded data"
|
|
158
|
+
- `isValidating`: if there's a request or revalidation loading
|
|
159
|
+
- `mutate(data?, options?)`: function to mutate the cached data (details)
|
|
160
|
+
|
|
161
|
+
### `useDoc(params)`
|
|
162
|
+
|
|
163
|
+
Subscription for document
|
|
164
|
+
|
|
165
|
+
#### Parameters
|
|
166
|
+
|
|
167
|
+
- `params`: KeyParams except `where`, `orderBy`, `limit` | null
|
|
168
|
+
|
|
169
|
+
#### Return values
|
|
170
|
+
|
|
171
|
+
- `data`: data for given path's document
|
|
172
|
+
- `error`: FirestoreError | Error
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
import { useDoc } from "@tatsuokaniwa/swr-firestore";
|
|
176
|
+
|
|
177
|
+
const { data, error } = useDoc<Post>({
|
|
178
|
+
path: `Posts/${postId}`,
|
|
179
|
+
});
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## Testing
|
|
183
|
+
|
|
184
|
+
Before running the test, you need to install the [Firebase tools](https://firebase.google.com/docs/cli).
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
npm run test:ci
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## License
|
|
191
|
+
|
|
192
|
+
MIT
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { SWRSubscriptionResponse } from "swr/subscription";
|
|
2
|
+
import type { FirestoreError } from "firebase/firestore";
|
|
3
|
+
import type { DocumentData, KeyParams } from "../util/type";
|
|
4
|
+
declare const useCollection: <T>(params: KeyParams<T> | null) => SWRSubscriptionResponse<DocumentData<T>[], FirestoreError | Error>;
|
|
5
|
+
export default useCollection;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { SWRHook } from "swr";
|
|
2
|
+
import type { KeyParams } from "../util/type";
|
|
3
|
+
declare const useCollectionCount: <T>(params: Omit<KeyParams<T>, "orderBy" | "parseDates"> | null, swrOptions?: Omit<Parameters<SWRHook>[2], "fetcher">) => import("swr/_internal").SWRResponse<number, any, Required<Omit<Partial<import("swr/_internal").PublicConfiguration<unknown, unknown, import("swr/_internal").BareFetcher<unknown>>> | undefined, "fetcher">>>;
|
|
4
|
+
export default useCollectionCount;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { SWRSubscriptionResponse } from "swr/subscription";
|
|
2
|
+
import type { FirestoreError } from "firebase/firestore";
|
|
3
|
+
import type { DocumentData, KeyParams } from "../util/type";
|
|
4
|
+
declare const useCollectionGroup: <T>(params: KeyParams<T> | null) => SWRSubscriptionResponse<DocumentData<T>[], FirestoreError>;
|
|
5
|
+
export default useCollectionGroup;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { SWRHook } from "swr";
|
|
2
|
+
import type { KeyParams } from "../util/type";
|
|
3
|
+
declare const useCollectionGroupCount: <T>(params: Omit<KeyParams<T>, "orderBy" | "parseDates"> | null, swrOptions?: Omit<Parameters<SWRHook>[2], "fetcher">) => import("swr/_internal").SWRResponse<number, any, Required<Omit<Partial<import("swr/_internal").PublicConfiguration<unknown, unknown, import("swr/_internal").BareFetcher<unknown>>> | undefined, "fetcher">>>;
|
|
4
|
+
export default useCollectionGroupCount;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { FirestoreError } from "firebase/firestore";
|
|
2
|
+
import type { SWRSubscriptionResponse } from "swr/subscription";
|
|
3
|
+
import type { DocumentData, KeyParams } from "../util/type";
|
|
4
|
+
declare const useDoc: <T>(params: Omit<KeyParams<T>, "where" | "orderBy" | "limit"> | null) => SWRSubscriptionResponse<DocumentData<T>, FirestoreError>;
|
|
5
|
+
export default useDoc;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { DocumentData, KeyParams } from "./util/type";
|
|
2
|
+
import useCollection from "./hooks/useCollection";
|
|
3
|
+
import useCollectionCount from "./hooks/useCollectionCount";
|
|
4
|
+
import useCollectionGroup from "./hooks/useCollectionGroup";
|
|
5
|
+
import useCollectionGroupCount from "./hooks/useCollectionGroupCount";
|
|
6
|
+
import useDoc from "./hooks/useDoc";
|
|
7
|
+
export type { DocumentData, KeyParams };
|
|
8
|
+
export { useCollection, useCollectionCount, useCollectionGroup, useCollectionGroupCount, useDoc, };
|