react-query-firebase 1.0.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/LICENSE +21 -0
- package/README.md +44 -0
- package/dist/src/FirebaseContext.d.ts +13 -0
- package/dist/src/FirebaseContext.js +3 -0
- package/dist/src/FirebaseContextProvider.d.ts +28 -0
- package/dist/src/FirebaseContextProvider.js +46 -0
- package/dist/src/analytics/index.d.ts +1 -0
- package/dist/src/analytics/index.js +1 -0
- package/dist/src/analytics/useLogEvent.d.ts +10 -0
- package/dist/src/analytics/useLogEvent.js +14 -0
- package/dist/src/auth/index.d.ts +9 -0
- package/dist/src/auth/index.js +9 -0
- package/dist/src/auth/mutation-keys.d.ts +7 -0
- package/dist/src/auth/mutation-keys.js +19 -0
- package/dist/src/auth/useAuthStateReady.d.ts +1 -0
- package/dist/src/auth/useAuthStateReady.js +14 -0
- package/dist/src/auth/useCreateUserWitEmailAndPasswordMutation.d.ts +8 -0
- package/dist/src/auth/useCreateUserWitEmailAndPasswordMutation.js +12 -0
- package/dist/src/auth/useCurrentUser.d.ts +1 -0
- package/dist/src/auth/useCurrentUser.js +15 -0
- package/dist/src/auth/useSendEmailVerificationMutation.d.ts +7 -0
- package/dist/src/auth/useSendEmailVerificationMutation.js +10 -0
- package/dist/src/auth/useSignInWitEmailAndPasswordMutation.d.ts +8 -0
- package/dist/src/auth/useSignInWitEmailAndPasswordMutation.js +12 -0
- package/dist/src/auth/useSignInWitRedirectMutation.d.ts +8 -0
- package/dist/src/auth/useSignInWitRedirectMutation.js +12 -0
- package/dist/src/auth/useSignOutMutation.d.ts +3 -0
- package/dist/src/auth/useSignOutMutation.js +12 -0
- package/dist/src/auth/useUpdateProfileMutation.d.ts +8 -0
- package/dist/src/auth/useUpdateProfileMutation.js +10 -0
- package/dist/src/firestore/index.d.ts +14 -0
- package/dist/src/firestore/index.js +14 -0
- package/dist/src/firestore/useAddDocMutation.d.ts +12 -0
- package/dist/src/firestore/useAddDocMutation.js +15 -0
- package/dist/src/firestore/useBatchWrite.d.ts +8 -0
- package/dist/src/firestore/useBatchWrite.js +14 -0
- package/dist/src/firestore/useCollectionReference.d.ts +7 -0
- package/dist/src/firestore/useCollectionReference.js +13 -0
- package/dist/src/firestore/useCompositeFilter.d.ts +20 -0
- package/dist/src/firestore/useCompositeFilter.js +26 -0
- package/dist/src/firestore/useCountQuery.d.ts +10 -0
- package/dist/src/firestore/useCountQuery.js +17 -0
- package/dist/src/firestore/useDeleteDocMutation.d.ts +11 -0
- package/dist/src/firestore/useDeleteDocMutation.js +16 -0
- package/dist/src/firestore/useDocReference.d.ts +7 -0
- package/dist/src/firestore/useDocReference.js +21 -0
- package/dist/src/firestore/useDocReferences.d.ts +7 -0
- package/dist/src/firestore/useDocReferences.js +15 -0
- package/dist/src/firestore/useGetDocData.d.ts +10 -0
- package/dist/src/firestore/useGetDocData.js +10 -0
- package/dist/src/firestore/useInfiniteQuery.d.ts +11 -0
- package/dist/src/firestore/useInfiniteQuery.js +21 -0
- package/dist/src/firestore/useQuery.d.ts +11 -0
- package/dist/src/firestore/useQuery.js +20 -0
- package/dist/src/firestore/useRunTransaction.d.ts +8 -0
- package/dist/src/firestore/useRunTransaction.js +12 -0
- package/dist/src/firestore/useSetDocMutation.d.ts +11 -0
- package/dist/src/firestore/useSetDocMutation.js +16 -0
- package/dist/src/firestore/useUpdateDocMutation.d.ts +12 -0
- package/dist/src/firestore/useUpdateDocMutation.js +18 -0
- package/dist/src/firestore/utils/getDocData.d.ts +4 -0
- package/dist/src/firestore/utils/getDocData.js +8 -0
- package/dist/src/firestore/utils/getDocRef.d.ts +8 -0
- package/dist/src/firestore/utils/getDocRef.js +14 -0
- package/dist/src/firestore/utils/getDocSnap.d.ts +4 -0
- package/dist/src/firestore/utils/getDocSnap.js +9 -0
- package/dist/src/index.d.ts +10 -0
- package/dist/src/index.js +10 -0
- package/dist/src/remoteConfig/index.d.ts +2 -0
- package/dist/src/remoteConfig/index.js +2 -0
- package/dist/src/remoteConfig/useFetchAndActivate.d.ts +4 -0
- package/dist/src/remoteConfig/useFetchAndActivate.js +22 -0
- package/dist/src/remoteConfig/useGetValue.d.ts +1 -0
- package/dist/src/remoteConfig/useGetValue.js +9 -0
- package/dist/src/useAnalytics.d.ts +1 -0
- package/dist/src/useAnalytics.js +6 -0
- package/dist/src/useAuth.d.ts +1 -0
- package/dist/src/useAuth.js +6 -0
- package/dist/src/useFirebase.d.ts +1 -0
- package/dist/src/useFirebase.js +6 -0
- package/dist/src/useFirestore.d.ts +1 -0
- package/dist/src/useFirestore.js +6 -0
- package/dist/src/useRemoteConfig.d.ts +1 -0
- package/dist/src/useRemoteConfig.js +6 -0
- package/package.json +57 -0
- package/src/FirebaseContext.ts +18 -0
- package/src/FirebaseContextProvider.tsx +91 -0
- package/src/analytics/index.ts +1 -0
- package/src/analytics/useLogEvent.ts +27 -0
- package/src/auth/index.ts +9 -0
- package/src/auth/mutation-keys.ts +19 -0
- package/src/auth/useAuthStateReady.ts +19 -0
- package/src/auth/useCreateUserWitEmailAndPasswordMutation.ts +26 -0
- package/src/auth/useCurrentUser.ts +19 -0
- package/src/auth/useIdToken.ts +35 -0
- package/src/auth/useReauthenticateWitCredentialMutation.ts +23 -0
- package/src/auth/useReauthenticateWitRedirectMutation.ts +29 -0
- package/src/auth/useSendEmailVerificationMutation.ts +22 -0
- package/src/auth/useSignInWitEmailAndPasswordMutation.ts +27 -0
- package/src/auth/useSignInWitRedirectMutation.ts +27 -0
- package/src/auth/useSignOutMutation.ts +18 -0
- package/src/auth/useUpdateProfileMutation.ts +23 -0
- package/src/firestore/index.ts +14 -0
- package/src/firestore/useAddDocMutation.ts +51 -0
- package/src/firestore/useBatchWrite.ts +24 -0
- package/src/firestore/useCollectionReference.ts +26 -0
- package/src/firestore/useCompositeFilter.ts +68 -0
- package/src/firestore/useCountQuery.ts +51 -0
- package/src/firestore/useDeleteDocMutation.ts +40 -0
- package/src/firestore/useDocReference.ts +44 -0
- package/src/firestore/useDocReferences.ts +28 -0
- package/src/firestore/useGetDocData.ts +33 -0
- package/src/firestore/useInfiniteQuery.ts +84 -0
- package/src/firestore/useQuery.ts +58 -0
- package/src/firestore/useRunTransaction.ts +24 -0
- package/src/firestore/useSetDocMutation.ts +43 -0
- package/src/firestore/useUpdateDocMutation copy.ts +51 -0
- package/src/firestore/useUpdateDocMutation.ts +55 -0
- package/src/firestore/utils/getDocData.ts +25 -0
- package/src/firestore/utils/getDocRef.ts +35 -0
- package/src/firestore/utils/getDocSnap.ts +25 -0
- package/src/index.ts +10 -0
- package/src/remoteConfig/index.ts +2 -0
- package/src/remoteConfig/useFetchAndActivate.ts +27 -0
- package/src/remoteConfig/useGetValue.ts +10 -0
- package/src/useAnalytics.ts +8 -0
- package/src/useAuth.ts +8 -0
- package/src/useFirebase.ts +8 -0
- package/src/useFirestore.ts +7 -0
- package/src/useRemoteConfig.ts +7 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { CollectionReference, doc, DocumentData, DocumentReference } from "firebase/firestore";
|
|
2
|
+
|
|
3
|
+
import { useMemo } from "react";
|
|
4
|
+
import { useFirestore } from "../useFirestore";
|
|
5
|
+
|
|
6
|
+
export type UseDocReferencesOptions<AppModelType, DbModelType extends DocumentData = DocumentData> = {
|
|
7
|
+
reference?: CollectionReference<AppModelType, DbModelType> | DocumentReference<AppModelType, DbModelType>;
|
|
8
|
+
path: string;
|
|
9
|
+
pathSegments?: string[];
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const useDocReferences = <AppModelType, DbModelType extends DocumentData = DocumentData>(
|
|
13
|
+
references: UseDocReferencesOptions<AppModelType, DbModelType>[]
|
|
14
|
+
) => {
|
|
15
|
+
const db = useFirestore();
|
|
16
|
+
|
|
17
|
+
return useMemo(() => {
|
|
18
|
+
return references.map(({ path, reference, pathSegments }) => {
|
|
19
|
+
return (
|
|
20
|
+
!reference
|
|
21
|
+
? doc(db, path || "", ...(pathSegments || []))
|
|
22
|
+
: reference.type === "collection"
|
|
23
|
+
? doc(reference, path, ...(pathSegments || []))
|
|
24
|
+
: doc(reference, path, ...(pathSegments || []))
|
|
25
|
+
) as DocumentReference<AppModelType, DbModelType>;
|
|
26
|
+
});
|
|
27
|
+
}, [references]);
|
|
28
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { CollectionReference, DocumentData, DocumentReference } from "firebase/firestore";
|
|
2
|
+
|
|
3
|
+
import { useFirestore } from "../useFirestore";
|
|
4
|
+
import { getDocData } from "./utils/getDocData";
|
|
5
|
+
import { useQuery, UseQueryOptions } from "@tanstack/react-query";
|
|
6
|
+
|
|
7
|
+
type UseGetDocOptions<
|
|
8
|
+
AppModelType extends DocumentData = DocumentData,
|
|
9
|
+
DbModelType extends DocumentData = DocumentData
|
|
10
|
+
> = {
|
|
11
|
+
options: Omit<UseQueryOptions<AppModelType | null, Error, AppModelType>, "queryFn"> &
|
|
12
|
+
Required<Pick<UseQueryOptions<AppModelType, Error, AppModelType>, "queryKey">>;
|
|
13
|
+
path?: string;
|
|
14
|
+
pathSegments?: string[];
|
|
15
|
+
reference: CollectionReference<AppModelType, DbModelType> | DocumentReference<AppModelType, DbModelType>;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const useGetDocData = <
|
|
19
|
+
AppModelType extends DocumentData = DocumentData,
|
|
20
|
+
DbModelType extends DocumentData = DocumentData
|
|
21
|
+
>({
|
|
22
|
+
options,
|
|
23
|
+
reference,
|
|
24
|
+
path,
|
|
25
|
+
pathSegments
|
|
26
|
+
}: UseGetDocOptions<AppModelType, DbModelType>) => {
|
|
27
|
+
const db = useFirestore();
|
|
28
|
+
|
|
29
|
+
return useQuery({
|
|
30
|
+
...options,
|
|
31
|
+
queryFn: () => getDocData<AppModelType, DbModelType>({ db, reference, path, pathSegments })
|
|
32
|
+
});
|
|
33
|
+
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DocumentData,
|
|
3
|
+
FirestoreDataConverter,
|
|
4
|
+
getDocs,
|
|
5
|
+
Query,
|
|
6
|
+
query,
|
|
7
|
+
QueryCompositeFilterConstraint,
|
|
8
|
+
QueryConstraint,
|
|
9
|
+
QueryNonFilterConstraint
|
|
10
|
+
} from "firebase/firestore";
|
|
11
|
+
|
|
12
|
+
import {
|
|
13
|
+
useInfiniteQuery as useInfiniteReactQuery,
|
|
14
|
+
UseInfiniteQueryOptions as UseReactInfiniteQueryOptions,
|
|
15
|
+
QueryKey,
|
|
16
|
+
UseInfiniteQueryResult,
|
|
17
|
+
InfiniteData
|
|
18
|
+
} from "@tanstack/react-query";
|
|
19
|
+
|
|
20
|
+
type UseInfiniteQueryOptions<
|
|
21
|
+
AppModelType extends DocumentData = DocumentData,
|
|
22
|
+
DbModelType extends DocumentData = DocumentData,
|
|
23
|
+
TQueryKey extends QueryKey = QueryKey
|
|
24
|
+
> = {
|
|
25
|
+
options: Omit<
|
|
26
|
+
UseReactInfiniteQueryOptions<
|
|
27
|
+
AppModelType[],
|
|
28
|
+
Error,
|
|
29
|
+
InfiniteData<AppModelType[]>,
|
|
30
|
+
AppModelType[],
|
|
31
|
+
TQueryKey,
|
|
32
|
+
QueryConstraint
|
|
33
|
+
>,
|
|
34
|
+
"queryFn"
|
|
35
|
+
> &
|
|
36
|
+
Required<
|
|
37
|
+
Pick<
|
|
38
|
+
UseReactInfiniteQueryOptions<
|
|
39
|
+
AppModelType[],
|
|
40
|
+
Error,
|
|
41
|
+
InfiniteData<AppModelType[]>,
|
|
42
|
+
AppModelType[],
|
|
43
|
+
TQueryKey,
|
|
44
|
+
QueryConstraint
|
|
45
|
+
>,
|
|
46
|
+
"queryKey"
|
|
47
|
+
>
|
|
48
|
+
>;
|
|
49
|
+
query: Query<AppModelType, DbModelType>;
|
|
50
|
+
queryConstraints?: QueryConstraint[] | QueryNonFilterConstraint[];
|
|
51
|
+
compositeFilter?: QueryCompositeFilterConstraint;
|
|
52
|
+
converter?: FirestoreDataConverter<AppModelType, DbModelType>;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export const useInfiniteQuery = <
|
|
56
|
+
AppModelType extends DocumentData = DocumentData,
|
|
57
|
+
DbModelType extends DocumentData = DocumentData
|
|
58
|
+
>({
|
|
59
|
+
options,
|
|
60
|
+
query: queryReference,
|
|
61
|
+
queryConstraints = [],
|
|
62
|
+
compositeFilter,
|
|
63
|
+
converter
|
|
64
|
+
}: UseInfiniteQueryOptions<AppModelType, DbModelType>): UseInfiniteQueryResult<InfiniteData<AppModelType[]>> => {
|
|
65
|
+
return useInfiniteReactQuery({
|
|
66
|
+
...options,
|
|
67
|
+
queryFn: async ({ pageParam }) => {
|
|
68
|
+
const allQueryConstraints = [...queryConstraints, ...(pageParam ? [pageParam] : [])];
|
|
69
|
+
const queryToExecute = compositeFilter
|
|
70
|
+
? query(queryReference, compositeFilter, ...(allQueryConstraints as QueryNonFilterConstraint[]))
|
|
71
|
+
: query(queryReference, ...allQueryConstraints);
|
|
72
|
+
|
|
73
|
+
const querySnapshot = await getDocs(converter ? queryToExecute.withConverter(converter) : queryToExecute);
|
|
74
|
+
const docs: AppModelType[] = [];
|
|
75
|
+
|
|
76
|
+
if (querySnapshot) {
|
|
77
|
+
querySnapshot.forEach((doc) => {
|
|
78
|
+
docs.push(doc.data());
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
return docs;
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DocumentData,
|
|
3
|
+
FirestoreDataConverter,
|
|
4
|
+
getDocs,
|
|
5
|
+
Query,
|
|
6
|
+
query,
|
|
7
|
+
QueryCompositeFilterConstraint,
|
|
8
|
+
QueryConstraint,
|
|
9
|
+
QueryNonFilterConstraint
|
|
10
|
+
} from "firebase/firestore";
|
|
11
|
+
|
|
12
|
+
import {
|
|
13
|
+
UseQueryResult,
|
|
14
|
+
useQuery as useReactQuery,
|
|
15
|
+
UseQueryOptions as UseReactQueryOptions
|
|
16
|
+
} from "@tanstack/react-query";
|
|
17
|
+
|
|
18
|
+
type UseQueryOptions<
|
|
19
|
+
AppModelType extends DocumentData = DocumentData,
|
|
20
|
+
DbModelType extends DocumentData = DocumentData
|
|
21
|
+
> = {
|
|
22
|
+
options: Omit<UseReactQueryOptions<AppModelType[], Error, AppModelType[]>, "queryFn"> &
|
|
23
|
+
Required<Pick<UseReactQueryOptions<AppModelType[], Error, AppModelType[]>, "queryKey">>;
|
|
24
|
+
query: Query<AppModelType, DbModelType>;
|
|
25
|
+
queryConstraints?: QueryConstraint[] | QueryNonFilterConstraint[];
|
|
26
|
+
compositeFilter?: QueryCompositeFilterConstraint;
|
|
27
|
+
converter?: FirestoreDataConverter<AppModelType, DbModelType>;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const useQuery = <
|
|
31
|
+
AppModelType extends DocumentData = DocumentData,
|
|
32
|
+
DbModelType extends DocumentData = DocumentData
|
|
33
|
+
>({
|
|
34
|
+
options,
|
|
35
|
+
query: queryReference,
|
|
36
|
+
queryConstraints = [],
|
|
37
|
+
compositeFilter,
|
|
38
|
+
converter
|
|
39
|
+
}: UseQueryOptions<AppModelType, DbModelType>): UseQueryResult<AppModelType[]> => {
|
|
40
|
+
return useReactQuery({
|
|
41
|
+
...options,
|
|
42
|
+
queryFn: async () => {
|
|
43
|
+
const queryToExecute = compositeFilter
|
|
44
|
+
? query(queryReference, compositeFilter, ...(queryConstraints as QueryNonFilterConstraint[]))
|
|
45
|
+
: query(queryReference, ...queryConstraints);
|
|
46
|
+
|
|
47
|
+
const querySnapshot = await getDocs(converter ? queryToExecute.withConverter(converter) : queryToExecute);
|
|
48
|
+
const docs: AppModelType[] = [];
|
|
49
|
+
|
|
50
|
+
if (querySnapshot) {
|
|
51
|
+
querySnapshot.forEach((doc) => {
|
|
52
|
+
docs.push(doc.data());
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
return docs;
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { useMutation, UseMutationOptions } from "@tanstack/react-query";
|
|
2
|
+
import { runTransaction, Transaction } from "firebase/firestore";
|
|
3
|
+
|
|
4
|
+
import { FirebaseError } from "firebase/app";
|
|
5
|
+
import { useFirestore } from "../useFirestore";
|
|
6
|
+
|
|
7
|
+
export type UseRunTransactionValues = <AppModelType = unknown>(transaction: Transaction) => AppModelType;
|
|
8
|
+
|
|
9
|
+
export type UseRunTransactionOptions<AppModelType = unknown, TContext = unknown> = {
|
|
10
|
+
options?: Omit<UseMutationOptions<AppModelType, FirebaseError, UseRunTransactionValues, TContext>, "mutationFn">;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const useRunTransaction = <AppModelType = unknown, TContext = unknown>({
|
|
14
|
+
options = {}
|
|
15
|
+
}: UseRunTransactionOptions<AppModelType, TContext>) => {
|
|
16
|
+
const db = useFirestore();
|
|
17
|
+
|
|
18
|
+
return useMutation({
|
|
19
|
+
...options,
|
|
20
|
+
mutationFn: async (transactionFn) => {
|
|
21
|
+
return runTransaction<AppModelType>(db, transactionFn);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { useMutation, UseMutationOptions } from "@tanstack/react-query";
|
|
2
|
+
import { DocumentData, DocumentReference, setDoc, WithFieldValue } from "firebase/firestore";
|
|
3
|
+
|
|
4
|
+
import { FirebaseError } from "firebase/app";
|
|
5
|
+
import { useMemo } from "react";
|
|
6
|
+
|
|
7
|
+
export type UseSetDocMutationValues<AppModelType> = {
|
|
8
|
+
data: WithFieldValue<AppModelType>;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type UseSetDocMutationOptions<
|
|
12
|
+
AppModelType = unknown,
|
|
13
|
+
DbModelType extends DocumentData = DocumentData,
|
|
14
|
+
TContext = unknown
|
|
15
|
+
> = {
|
|
16
|
+
reference: DocumentReference<AppModelType, DbModelType> | null;
|
|
17
|
+
options?: Omit<
|
|
18
|
+
UseMutationOptions<void, FirebaseError, UseSetDocMutationValues<AppModelType>, TContext>,
|
|
19
|
+
"mutationFn" | "mutationKey"
|
|
20
|
+
>;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const useSetDocMutation = <
|
|
24
|
+
AppModelType = unknown,
|
|
25
|
+
DbModelType extends DocumentData = DocumentData,
|
|
26
|
+
TContext = unknown
|
|
27
|
+
>({
|
|
28
|
+
reference,
|
|
29
|
+
options
|
|
30
|
+
}: UseSetDocMutationOptions<AppModelType, DbModelType, TContext>) => {
|
|
31
|
+
const mutationKey = useMemo(() => [reference?.path], [reference?.path]);
|
|
32
|
+
|
|
33
|
+
return useMutation({
|
|
34
|
+
...options,
|
|
35
|
+
mutationFn: ({ data }) => {
|
|
36
|
+
if (!reference) {
|
|
37
|
+
throw new Error("Reference is undefined");
|
|
38
|
+
}
|
|
39
|
+
return setDoc<AppModelType, DbModelType>(reference, data);
|
|
40
|
+
},
|
|
41
|
+
mutationKey
|
|
42
|
+
});
|
|
43
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { useMutation, UseMutationOptions } from "@tanstack/react-query";
|
|
2
|
+
import {
|
|
3
|
+
DocumentData,
|
|
4
|
+
updateDoc,
|
|
5
|
+
getDoc,
|
|
6
|
+
FirestoreDataConverter,
|
|
7
|
+
DocumentReference,
|
|
8
|
+
UpdateData
|
|
9
|
+
} from "firebase/firestore";
|
|
10
|
+
|
|
11
|
+
import { FirebaseError } from "firebase/app";
|
|
12
|
+
import { useMemo } from "react";
|
|
13
|
+
|
|
14
|
+
export type UseUpdateDocMutationValues<DbModelType> = {
|
|
15
|
+
data: UpdateData<DbModelType>;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export type UseUpdateDocMutationOptions<
|
|
19
|
+
AppModelType extends DocumentData = DocumentData,
|
|
20
|
+
DbModelType extends DocumentData = DocumentData,
|
|
21
|
+
TContext = unknown
|
|
22
|
+
> = {
|
|
23
|
+
reference: DocumentReference<AppModelType, DbModelType>;
|
|
24
|
+
converter?: FirestoreDataConverter<AppModelType, DbModelType>;
|
|
25
|
+
options?: Omit<
|
|
26
|
+
UseMutationOptions<AppModelType, FirebaseError, UseUpdateDocMutationValues<DbModelType>, TContext>,
|
|
27
|
+
"mutationFn" | "mutationKey"
|
|
28
|
+
>;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const useUpdateDocMutation = <
|
|
32
|
+
AppModelType extends DocumentData = DocumentData,
|
|
33
|
+
DbModelType extends DocumentData = DocumentData,
|
|
34
|
+
TContext = unknown
|
|
35
|
+
>({
|
|
36
|
+
reference,
|
|
37
|
+
converter,
|
|
38
|
+
options = {}
|
|
39
|
+
}: UseUpdateDocMutationOptions<AppModelType, DbModelType, TContext>) => {
|
|
40
|
+
const mutationKey = useMemo(() => [reference.path], [reference.path]);
|
|
41
|
+
|
|
42
|
+
return useMutation({
|
|
43
|
+
...options,
|
|
44
|
+
mutationFn: async ({ data }) => {
|
|
45
|
+
await updateDoc<AppModelType, DbModelType>(reference, data);
|
|
46
|
+
const docSnap = await getDoc(converter ? reference.withConverter(converter) : reference);
|
|
47
|
+
return docSnap.data() as AppModelType;
|
|
48
|
+
},
|
|
49
|
+
mutationKey
|
|
50
|
+
});
|
|
51
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { useMutation, UseMutationOptions } from "@tanstack/react-query";
|
|
2
|
+
import {
|
|
3
|
+
DocumentData,
|
|
4
|
+
updateDoc,
|
|
5
|
+
getDoc,
|
|
6
|
+
FirestoreDataConverter,
|
|
7
|
+
DocumentReference,
|
|
8
|
+
UpdateData
|
|
9
|
+
} from "firebase/firestore";
|
|
10
|
+
|
|
11
|
+
import { FirebaseError } from "firebase/app";
|
|
12
|
+
import { useMemo } from "react";
|
|
13
|
+
|
|
14
|
+
export type UseUpdateDocMutationValues<DbModelType> = {
|
|
15
|
+
data: UpdateData<DbModelType>;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export type UseUpdateDocMutationOptions<
|
|
19
|
+
AppModelType extends DocumentData = DocumentData,
|
|
20
|
+
DbModelType extends DocumentData = DocumentData,
|
|
21
|
+
TContext = unknown
|
|
22
|
+
> = {
|
|
23
|
+
reference: DocumentReference<AppModelType, DbModelType> | null;
|
|
24
|
+
converter?: FirestoreDataConverter<AppModelType, DbModelType>;
|
|
25
|
+
options?: Omit<
|
|
26
|
+
UseMutationOptions<AppModelType, FirebaseError, UseUpdateDocMutationValues<DbModelType>, TContext>,
|
|
27
|
+
"mutationFn" | "mutationKey"
|
|
28
|
+
>;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const useUpdateDocMutation = <
|
|
32
|
+
AppModelType extends DocumentData = DocumentData,
|
|
33
|
+
DbModelType extends DocumentData = DocumentData,
|
|
34
|
+
TContext = unknown
|
|
35
|
+
>({
|
|
36
|
+
reference,
|
|
37
|
+
converter,
|
|
38
|
+
options = {}
|
|
39
|
+
}: UseUpdateDocMutationOptions<AppModelType, DbModelType, TContext>) => {
|
|
40
|
+
const mutationKey = useMemo(() => [reference?.path], [reference?.path]);
|
|
41
|
+
|
|
42
|
+
return useMutation({
|
|
43
|
+
...options,
|
|
44
|
+
mutationFn: async ({ data }) => {
|
|
45
|
+
if (!reference) {
|
|
46
|
+
throw new Error("Reference is undefined");
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
await updateDoc<AppModelType, DbModelType>(reference, data);
|
|
50
|
+
const docSnap = await getDoc(converter ? reference.withConverter(converter) : reference);
|
|
51
|
+
return docSnap.data() as AppModelType;
|
|
52
|
+
},
|
|
53
|
+
mutationKey
|
|
54
|
+
});
|
|
55
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { DocumentData } from "firebase/firestore";
|
|
2
|
+
import { getDocSnap, GetDocSnapOptions } from "./getDocSnap";
|
|
3
|
+
|
|
4
|
+
export type GetDocDataOptions<
|
|
5
|
+
AppModelType extends DocumentData = DocumentData,
|
|
6
|
+
DbModelType extends DocumentData = DocumentData
|
|
7
|
+
> = GetDocSnapOptions<AppModelType, DbModelType>;
|
|
8
|
+
|
|
9
|
+
export const getDocData = async <
|
|
10
|
+
AppModelType extends DocumentData = DocumentData,
|
|
11
|
+
DbModelType extends DocumentData = DocumentData
|
|
12
|
+
>({
|
|
13
|
+
db,
|
|
14
|
+
reference,
|
|
15
|
+
path,
|
|
16
|
+
pathSegments
|
|
17
|
+
}: GetDocDataOptions<AppModelType, DbModelType>) => {
|
|
18
|
+
const docSnap = await getDocSnap<AppModelType, DbModelType>({ db, reference, path, pathSegments });
|
|
19
|
+
|
|
20
|
+
if (docSnap && docSnap.exists()) {
|
|
21
|
+
return docSnap.data();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return null;
|
|
25
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { CollectionReference, doc, DocumentData, DocumentReference, Firestore } from "firebase/firestore";
|
|
2
|
+
|
|
3
|
+
export type GetDocRefOptions<
|
|
4
|
+
AppModelType extends DocumentData = DocumentData,
|
|
5
|
+
DbModelType extends DocumentData = DocumentData
|
|
6
|
+
> = {
|
|
7
|
+
db: Firestore;
|
|
8
|
+
reference?: CollectionReference<AppModelType, DbModelType> | DocumentReference<AppModelType, DbModelType>;
|
|
9
|
+
path?: string;
|
|
10
|
+
pathSegments?: string[];
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const getDocRef = async <
|
|
14
|
+
AppModelType extends DocumentData = DocumentData,
|
|
15
|
+
DbModelType extends DocumentData = DocumentData
|
|
16
|
+
>({
|
|
17
|
+
db,
|
|
18
|
+
reference,
|
|
19
|
+
path,
|
|
20
|
+
pathSegments
|
|
21
|
+
}: GetDocRefOptions<AppModelType, DbModelType>) => {
|
|
22
|
+
if (!reference && !path) {
|
|
23
|
+
throw new Error("One of the options must be provided: path or reference.");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const docRef = !reference
|
|
27
|
+
? doc(db, path as string, ...(pathSegments || []))
|
|
28
|
+
: reference.type === "collection"
|
|
29
|
+
? doc(reference, path, ...(pathSegments || []))
|
|
30
|
+
: reference.type === "document"
|
|
31
|
+
? doc(reference, path as string, ...(pathSegments || []))
|
|
32
|
+
: null;
|
|
33
|
+
|
|
34
|
+
return docRef as DocumentReference<AppModelType, DbModelType>;
|
|
35
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { DocumentData, getDoc as firestoreGetDoc } from "firebase/firestore";
|
|
2
|
+
import { getDocRef, GetDocRefOptions } from "./getDocRef";
|
|
3
|
+
|
|
4
|
+
export type GetDocSnapOptions<
|
|
5
|
+
AppModelType extends DocumentData = DocumentData,
|
|
6
|
+
DbModelType extends DocumentData = DocumentData
|
|
7
|
+
> = GetDocRefOptions<AppModelType, DbModelType>;
|
|
8
|
+
|
|
9
|
+
export const getDocSnap = async <
|
|
10
|
+
AppModelType extends DocumentData = DocumentData,
|
|
11
|
+
DbModelType extends DocumentData = DocumentData
|
|
12
|
+
>({
|
|
13
|
+
db,
|
|
14
|
+
reference,
|
|
15
|
+
path,
|
|
16
|
+
pathSegments
|
|
17
|
+
}: GetDocSnapOptions<AppModelType, DbModelType>) => {
|
|
18
|
+
const docRef = await getDocRef<AppModelType, DbModelType>({ db, reference, path, pathSegments });
|
|
19
|
+
|
|
20
|
+
if (docRef) {
|
|
21
|
+
return await firestoreGetDoc(docRef);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return null;
|
|
25
|
+
};
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from "./useAuth";
|
|
2
|
+
export * from "./useFirebase";
|
|
3
|
+
export * from "./useFirestore";
|
|
4
|
+
export * from "./FirebaseContextProvider";
|
|
5
|
+
export * from "./useAnalytics";
|
|
6
|
+
export * from "./useRemoteConfig";
|
|
7
|
+
export * from "./analytics";
|
|
8
|
+
export * from "./auth";
|
|
9
|
+
export * from "./firestore";
|
|
10
|
+
export * from "./remoteConfig";
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { useRemoteConfig } from "../useRemoteConfig";
|
|
2
|
+
import { ensureInitialized, fetchAndActivate } from "firebase/remote-config";
|
|
3
|
+
import { useCallback, useMemo, useState } from "react";
|
|
4
|
+
|
|
5
|
+
export const useFetchAndActivate = () => {
|
|
6
|
+
const remoteConfig = useRemoteConfig();
|
|
7
|
+
const [isFetched, setIsFetched] = useState(false);
|
|
8
|
+
|
|
9
|
+
const fetchAndActivateCallback = useCallback(async () => {
|
|
10
|
+
try {
|
|
11
|
+
await ensureInitialized(remoteConfig);
|
|
12
|
+
await fetchAndActivate(remoteConfig);
|
|
13
|
+
setIsFetched(true);
|
|
14
|
+
} catch (e) {
|
|
15
|
+
setIsFetched(true);
|
|
16
|
+
console.log(`Cannot read remote config: ${(e as Error)?.message}`);
|
|
17
|
+
}
|
|
18
|
+
}, [isFetched]);
|
|
19
|
+
|
|
20
|
+
return useMemo(
|
|
21
|
+
() => ({
|
|
22
|
+
fetchAndActivate: fetchAndActivateCallback,
|
|
23
|
+
isFetched
|
|
24
|
+
}),
|
|
25
|
+
[isFetched, fetchAndActivateCallback]
|
|
26
|
+
);
|
|
27
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { getValue } from "firebase/remote-config";
|
|
2
|
+
import { useRemoteConfig } from "../useRemoteConfig";
|
|
3
|
+
import { useMemo } from "react";
|
|
4
|
+
|
|
5
|
+
export const useGetValue = (key: string) => {
|
|
6
|
+
const remoteConfig = useRemoteConfig();
|
|
7
|
+
return useMemo(() => {
|
|
8
|
+
return remoteConfig ? getValue(remoteConfig, key) : null;
|
|
9
|
+
}, [remoteConfig?.lastFetchStatus, key]);
|
|
10
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Context, useContext } from "react";
|
|
2
|
+
|
|
3
|
+
import { FirebaseContext, FirebaseContextValue } from "./FirebaseContext";
|
|
4
|
+
|
|
5
|
+
export const useAnalytics = () => {
|
|
6
|
+
const { analytics } = useContext<FirebaseContextValue>(FirebaseContext as Context<FirebaseContextValue>);
|
|
7
|
+
return analytics;
|
|
8
|
+
};
|
package/src/useAuth.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { useContext, Context } from "react";
|
|
2
|
+
|
|
3
|
+
import { FirebaseContext, FirebaseContextValue } from "./FirebaseContext";
|
|
4
|
+
|
|
5
|
+
export const useAuth = () => {
|
|
6
|
+
const { auth } = useContext<FirebaseContextValue>(FirebaseContext as Context<FirebaseContextValue>);
|
|
7
|
+
return auth;
|
|
8
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Context, useContext } from "react";
|
|
2
|
+
|
|
3
|
+
import { FirebaseContext, FirebaseContextValue } from "./FirebaseContext";
|
|
4
|
+
|
|
5
|
+
export const useFirebase = () => {
|
|
6
|
+
const { firebase } = useContext<FirebaseContextValue>(FirebaseContext as Context<FirebaseContextValue>);
|
|
7
|
+
return firebase;
|
|
8
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Context, useContext } from "react";
|
|
2
|
+
import { FirebaseContext, FirebaseContextValue } from "./FirebaseContext";
|
|
3
|
+
|
|
4
|
+
export const useFirestore = () => {
|
|
5
|
+
const { firestore } = useContext<FirebaseContextValue>(FirebaseContext as Context<FirebaseContextValue>);
|
|
6
|
+
return firestore;
|
|
7
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Context, useContext } from "react";
|
|
2
|
+
import { FirebaseContext, FirebaseContextValue } from "./FirebaseContext";
|
|
3
|
+
|
|
4
|
+
export const useRemoteConfig = () => {
|
|
5
|
+
const { remoteConfig } = useContext<FirebaseContextValue>(FirebaseContext as Context<FirebaseContextValue>);
|
|
6
|
+
return remoteConfig;
|
|
7
|
+
};
|