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,16 @@
|
|
|
1
|
+
import { useMutation } from "@tanstack/react-query";
|
|
2
|
+
import { deleteDoc } from "firebase/firestore";
|
|
3
|
+
import { useMemo } from "react";
|
|
4
|
+
export const useDeleteDocMutation = ({ reference, options = {} }) => {
|
|
5
|
+
const mutationKey = useMemo(() => [reference?.path], [reference?.path]);
|
|
6
|
+
return useMutation({
|
|
7
|
+
...options,
|
|
8
|
+
mutationFn: async () => {
|
|
9
|
+
if (!reference) {
|
|
10
|
+
throw new Error("Reference is undefined");
|
|
11
|
+
}
|
|
12
|
+
await deleteDoc(reference);
|
|
13
|
+
},
|
|
14
|
+
mutationKey
|
|
15
|
+
});
|
|
16
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { CollectionReference, DocumentData, DocumentReference } from "firebase/firestore";
|
|
2
|
+
export type UseDocReferenceOptions<AppModelType, DbModelType extends DocumentData = DocumentData> = {
|
|
3
|
+
reference?: CollectionReference<AppModelType, DbModelType> | DocumentReference<AppModelType, DbModelType>;
|
|
4
|
+
path?: string;
|
|
5
|
+
pathSegments?: string[];
|
|
6
|
+
};
|
|
7
|
+
export declare const useDocReference: <AppModelType, DbModelType extends DocumentData = DocumentData>({ path, reference, pathSegments }: UseDocReferenceOptions<AppModelType, DbModelType>) => DocumentReference<AppModelType, DbModelType> | null;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { doc } from "firebase/firestore";
|
|
2
|
+
import { useEffect, useRef } from "react";
|
|
3
|
+
import { useFirestore } from "../useFirestore";
|
|
4
|
+
const getDocReference = (db, { path, pathSegments, reference }) => {
|
|
5
|
+
if (!path) {
|
|
6
|
+
return null;
|
|
7
|
+
}
|
|
8
|
+
return (!reference
|
|
9
|
+
? doc(db, path || "", ...(pathSegments || []))
|
|
10
|
+
: reference.type === "collection"
|
|
11
|
+
? doc(reference, path, ...(pathSegments || []))
|
|
12
|
+
: doc(reference, path, ...(pathSegments || [])));
|
|
13
|
+
};
|
|
14
|
+
export const useDocReference = ({ path, reference, pathSegments }) => {
|
|
15
|
+
const db = useFirestore();
|
|
16
|
+
const ref = useRef(getDocReference(db, { path, pathSegments, reference }));
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
ref.current = getDocReference(db, { path, pathSegments, reference });
|
|
19
|
+
}, [path, reference, pathSegments]);
|
|
20
|
+
return ref.current;
|
|
21
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { CollectionReference, DocumentData, DocumentReference } from "firebase/firestore";
|
|
2
|
+
export type UseDocReferencesOptions<AppModelType, DbModelType extends DocumentData = DocumentData> = {
|
|
3
|
+
reference?: CollectionReference<AppModelType, DbModelType> | DocumentReference<AppModelType, DbModelType>;
|
|
4
|
+
path: string;
|
|
5
|
+
pathSegments?: string[];
|
|
6
|
+
};
|
|
7
|
+
export declare const useDocReferences: <AppModelType, DbModelType extends DocumentData = DocumentData>(references: UseDocReferencesOptions<AppModelType, DbModelType>[]) => DocumentReference<AppModelType, DbModelType>[];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { doc } from "firebase/firestore";
|
|
2
|
+
import { useMemo } from "react";
|
|
3
|
+
import { useFirestore } from "../useFirestore";
|
|
4
|
+
export const useDocReferences = (references) => {
|
|
5
|
+
const db = useFirestore();
|
|
6
|
+
return useMemo(() => {
|
|
7
|
+
return references.map(({ path, reference, pathSegments }) => {
|
|
8
|
+
return (!reference
|
|
9
|
+
? doc(db, path || "", ...(pathSegments || []))
|
|
10
|
+
: reference.type === "collection"
|
|
11
|
+
? doc(reference, path, ...(pathSegments || []))
|
|
12
|
+
: doc(reference, path, ...(pathSegments || [])));
|
|
13
|
+
});
|
|
14
|
+
}, [references]);
|
|
15
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { CollectionReference, DocumentData, DocumentReference } from "firebase/firestore";
|
|
2
|
+
import { UseQueryOptions } from "@tanstack/react-query";
|
|
3
|
+
type UseGetDocOptions<AppModelType extends DocumentData = DocumentData, DbModelType extends DocumentData = DocumentData> = {
|
|
4
|
+
options: Omit<UseQueryOptions<AppModelType | null, Error, AppModelType>, "queryFn"> & Required<Pick<UseQueryOptions<AppModelType, Error, AppModelType>, "queryKey">>;
|
|
5
|
+
path?: string;
|
|
6
|
+
pathSegments?: string[];
|
|
7
|
+
reference: CollectionReference<AppModelType, DbModelType> | DocumentReference<AppModelType, DbModelType>;
|
|
8
|
+
};
|
|
9
|
+
export declare const useGetDocData: <AppModelType extends DocumentData = DocumentData, DbModelType extends DocumentData = DocumentData>({ options, reference, path, pathSegments }: UseGetDocOptions<AppModelType, DbModelType>) => import("@tanstack/react-query").UseQueryResult<AppModelType, Error>;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { useFirestore } from "../useFirestore";
|
|
2
|
+
import { getDocData } from "./utils/getDocData";
|
|
3
|
+
import { useQuery } from "@tanstack/react-query";
|
|
4
|
+
export const useGetDocData = ({ options, reference, path, pathSegments }) => {
|
|
5
|
+
const db = useFirestore();
|
|
6
|
+
return useQuery({
|
|
7
|
+
...options,
|
|
8
|
+
queryFn: () => getDocData({ db, reference, path, pathSegments })
|
|
9
|
+
});
|
|
10
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { DocumentData, FirestoreDataConverter, Query, QueryCompositeFilterConstraint, QueryConstraint, QueryNonFilterConstraint } from "firebase/firestore";
|
|
2
|
+
import { UseInfiniteQueryOptions as UseReactInfiniteQueryOptions, QueryKey, UseInfiniteQueryResult, InfiniteData } from "@tanstack/react-query";
|
|
3
|
+
type UseInfiniteQueryOptions<AppModelType extends DocumentData = DocumentData, DbModelType extends DocumentData = DocumentData, TQueryKey extends QueryKey = QueryKey> = {
|
|
4
|
+
options: Omit<UseReactInfiniteQueryOptions<AppModelType[], Error, InfiniteData<AppModelType[]>, AppModelType[], TQueryKey, QueryConstraint>, "queryFn"> & Required<Pick<UseReactInfiniteQueryOptions<AppModelType[], Error, InfiniteData<AppModelType[]>, AppModelType[], TQueryKey, QueryConstraint>, "queryKey">>;
|
|
5
|
+
query: Query<AppModelType, DbModelType>;
|
|
6
|
+
queryConstraints?: QueryConstraint[] | QueryNonFilterConstraint[];
|
|
7
|
+
compositeFilter?: QueryCompositeFilterConstraint;
|
|
8
|
+
converter?: FirestoreDataConverter<AppModelType, DbModelType>;
|
|
9
|
+
};
|
|
10
|
+
export declare const useInfiniteQuery: <AppModelType extends DocumentData = DocumentData, DbModelType extends DocumentData = DocumentData>({ options, query: queryReference, queryConstraints, compositeFilter, converter }: UseInfiniteQueryOptions<AppModelType, DbModelType>) => UseInfiniteQueryResult<InfiniteData<AppModelType[]>>;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { getDocs, query } from "firebase/firestore";
|
|
2
|
+
import { useInfiniteQuery as useInfiniteReactQuery } from "@tanstack/react-query";
|
|
3
|
+
export const useInfiniteQuery = ({ options, query: queryReference, queryConstraints = [], compositeFilter, converter }) => {
|
|
4
|
+
return useInfiniteReactQuery({
|
|
5
|
+
...options,
|
|
6
|
+
queryFn: async ({ pageParam }) => {
|
|
7
|
+
const allQueryConstraints = [...queryConstraints, ...(pageParam ? [pageParam] : [])];
|
|
8
|
+
const queryToExecute = compositeFilter
|
|
9
|
+
? query(queryReference, compositeFilter, ...allQueryConstraints)
|
|
10
|
+
: query(queryReference, ...allQueryConstraints);
|
|
11
|
+
const querySnapshot = await getDocs(converter ? queryToExecute.withConverter(converter) : queryToExecute);
|
|
12
|
+
const docs = [];
|
|
13
|
+
if (querySnapshot) {
|
|
14
|
+
querySnapshot.forEach((doc) => {
|
|
15
|
+
docs.push(doc.data());
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
return docs;
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { DocumentData, FirestoreDataConverter, Query, QueryCompositeFilterConstraint, QueryConstraint, QueryNonFilterConstraint } from "firebase/firestore";
|
|
2
|
+
import { UseQueryResult, UseQueryOptions as UseReactQueryOptions } from "@tanstack/react-query";
|
|
3
|
+
type UseQueryOptions<AppModelType extends DocumentData = DocumentData, DbModelType extends DocumentData = DocumentData> = {
|
|
4
|
+
options: Omit<UseReactQueryOptions<AppModelType[], Error, AppModelType[]>, "queryFn"> & Required<Pick<UseReactQueryOptions<AppModelType[], Error, AppModelType[]>, "queryKey">>;
|
|
5
|
+
query: Query<AppModelType, DbModelType>;
|
|
6
|
+
queryConstraints?: QueryConstraint[] | QueryNonFilterConstraint[];
|
|
7
|
+
compositeFilter?: QueryCompositeFilterConstraint;
|
|
8
|
+
converter?: FirestoreDataConverter<AppModelType, DbModelType>;
|
|
9
|
+
};
|
|
10
|
+
export declare const useQuery: <AppModelType extends DocumentData = DocumentData, DbModelType extends DocumentData = DocumentData>({ options, query: queryReference, queryConstraints, compositeFilter, converter }: UseQueryOptions<AppModelType, DbModelType>) => UseQueryResult<AppModelType[]>;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { getDocs, query } from "firebase/firestore";
|
|
2
|
+
import { useQuery as useReactQuery } from "@tanstack/react-query";
|
|
3
|
+
export const useQuery = ({ options, query: queryReference, queryConstraints = [], compositeFilter, converter }) => {
|
|
4
|
+
return useReactQuery({
|
|
5
|
+
...options,
|
|
6
|
+
queryFn: async () => {
|
|
7
|
+
const queryToExecute = compositeFilter
|
|
8
|
+
? query(queryReference, compositeFilter, ...queryConstraints)
|
|
9
|
+
: query(queryReference, ...queryConstraints);
|
|
10
|
+
const querySnapshot = await getDocs(converter ? queryToExecute.withConverter(converter) : queryToExecute);
|
|
11
|
+
const docs = [];
|
|
12
|
+
if (querySnapshot) {
|
|
13
|
+
querySnapshot.forEach((doc) => {
|
|
14
|
+
docs.push(doc.data());
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
return docs;
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { UseMutationOptions } from "@tanstack/react-query";
|
|
2
|
+
import { Transaction } from "firebase/firestore";
|
|
3
|
+
import { FirebaseError } from "firebase/app";
|
|
4
|
+
export type UseRunTransactionValues = <AppModelType = unknown>(transaction: Transaction) => AppModelType;
|
|
5
|
+
export type UseRunTransactionOptions<AppModelType = unknown, TContext = unknown> = {
|
|
6
|
+
options?: Omit<UseMutationOptions<AppModelType, FirebaseError, UseRunTransactionValues, TContext>, "mutationFn">;
|
|
7
|
+
};
|
|
8
|
+
export declare const useRunTransaction: <AppModelType = unknown, TContext = unknown>({ options }: UseRunTransactionOptions<AppModelType, TContext>) => import("@tanstack/react-query").UseMutationResult<AppModelType, FirebaseError, UseRunTransactionValues, TContext>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { useMutation } from "@tanstack/react-query";
|
|
2
|
+
import { runTransaction } from "firebase/firestore";
|
|
3
|
+
import { useFirestore } from "../useFirestore";
|
|
4
|
+
export const useRunTransaction = ({ options = {} }) => {
|
|
5
|
+
const db = useFirestore();
|
|
6
|
+
return useMutation({
|
|
7
|
+
...options,
|
|
8
|
+
mutationFn: async (transactionFn) => {
|
|
9
|
+
return runTransaction(db, transactionFn);
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { UseMutationOptions } from "@tanstack/react-query";
|
|
2
|
+
import { DocumentData, DocumentReference, WithFieldValue } from "firebase/firestore";
|
|
3
|
+
import { FirebaseError } from "firebase/app";
|
|
4
|
+
export type UseSetDocMutationValues<AppModelType> = {
|
|
5
|
+
data: WithFieldValue<AppModelType>;
|
|
6
|
+
};
|
|
7
|
+
export type UseSetDocMutationOptions<AppModelType = unknown, DbModelType extends DocumentData = DocumentData, TContext = unknown> = {
|
|
8
|
+
reference: DocumentReference<AppModelType, DbModelType> | null;
|
|
9
|
+
options?: Omit<UseMutationOptions<void, FirebaseError, UseSetDocMutationValues<AppModelType>, TContext>, "mutationFn" | "mutationKey">;
|
|
10
|
+
};
|
|
11
|
+
export declare const useSetDocMutation: <AppModelType = unknown, DbModelType extends DocumentData = DocumentData, TContext = unknown>({ reference, options }: UseSetDocMutationOptions<AppModelType, DbModelType, TContext>) => import("@tanstack/react-query").UseMutationResult<void, FirebaseError, UseSetDocMutationValues<AppModelType>, TContext>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { useMutation } from "@tanstack/react-query";
|
|
2
|
+
import { setDoc } from "firebase/firestore";
|
|
3
|
+
import { useMemo } from "react";
|
|
4
|
+
export const useSetDocMutation = ({ reference, options }) => {
|
|
5
|
+
const mutationKey = useMemo(() => [reference?.path], [reference?.path]);
|
|
6
|
+
return useMutation({
|
|
7
|
+
...options,
|
|
8
|
+
mutationFn: ({ data }) => {
|
|
9
|
+
if (!reference) {
|
|
10
|
+
throw new Error("Reference is undefined");
|
|
11
|
+
}
|
|
12
|
+
return setDoc(reference, data);
|
|
13
|
+
},
|
|
14
|
+
mutationKey
|
|
15
|
+
});
|
|
16
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { UseMutationOptions } from "@tanstack/react-query";
|
|
2
|
+
import { DocumentData, FirestoreDataConverter, DocumentReference, UpdateData } from "firebase/firestore";
|
|
3
|
+
import { FirebaseError } from "firebase/app";
|
|
4
|
+
export type UseUpdateDocMutationValues<DbModelType> = {
|
|
5
|
+
data: UpdateData<DbModelType>;
|
|
6
|
+
};
|
|
7
|
+
export type UseUpdateDocMutationOptions<AppModelType extends DocumentData = DocumentData, DbModelType extends DocumentData = DocumentData, TContext = unknown> = {
|
|
8
|
+
reference: DocumentReference<AppModelType, DbModelType> | null;
|
|
9
|
+
converter?: FirestoreDataConverter<AppModelType, DbModelType>;
|
|
10
|
+
options?: Omit<UseMutationOptions<AppModelType, FirebaseError, UseUpdateDocMutationValues<DbModelType>, TContext>, "mutationFn" | "mutationKey">;
|
|
11
|
+
};
|
|
12
|
+
export declare const useUpdateDocMutation: <AppModelType extends DocumentData = DocumentData, DbModelType extends DocumentData = DocumentData, TContext = unknown>({ reference, converter, options }: UseUpdateDocMutationOptions<AppModelType, DbModelType, TContext>) => import("@tanstack/react-query").UseMutationResult<AppModelType, FirebaseError, UseUpdateDocMutationValues<DbModelType>, TContext>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { useMutation } from "@tanstack/react-query";
|
|
2
|
+
import { updateDoc, getDoc } from "firebase/firestore";
|
|
3
|
+
import { useMemo } from "react";
|
|
4
|
+
export const useUpdateDocMutation = ({ reference, converter, options = {} }) => {
|
|
5
|
+
const mutationKey = useMemo(() => [reference?.path], [reference?.path]);
|
|
6
|
+
return useMutation({
|
|
7
|
+
...options,
|
|
8
|
+
mutationFn: async ({ data }) => {
|
|
9
|
+
if (!reference) {
|
|
10
|
+
throw new Error("Reference is undefined");
|
|
11
|
+
}
|
|
12
|
+
await updateDoc(reference, data);
|
|
13
|
+
const docSnap = await getDoc(converter ? reference.withConverter(converter) : reference);
|
|
14
|
+
return docSnap.data();
|
|
15
|
+
},
|
|
16
|
+
mutationKey
|
|
17
|
+
});
|
|
18
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { DocumentData } from "firebase/firestore";
|
|
2
|
+
import { GetDocSnapOptions } from "./getDocSnap";
|
|
3
|
+
export type GetDocDataOptions<AppModelType extends DocumentData = DocumentData, DbModelType extends DocumentData = DocumentData> = GetDocSnapOptions<AppModelType, DbModelType>;
|
|
4
|
+
export declare const getDocData: <AppModelType extends DocumentData = DocumentData, DbModelType extends DocumentData = DocumentData>({ db, reference, path, pathSegments }: GetDocDataOptions<AppModelType, DbModelType>) => Promise<AppModelType | null>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { getDocSnap } from "./getDocSnap";
|
|
2
|
+
export const getDocData = async ({ db, reference, path, pathSegments }) => {
|
|
3
|
+
const docSnap = await getDocSnap({ db, reference, path, pathSegments });
|
|
4
|
+
if (docSnap && docSnap.exists()) {
|
|
5
|
+
return docSnap.data();
|
|
6
|
+
}
|
|
7
|
+
return null;
|
|
8
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { CollectionReference, DocumentData, DocumentReference, Firestore } from "firebase/firestore";
|
|
2
|
+
export type GetDocRefOptions<AppModelType extends DocumentData = DocumentData, DbModelType extends DocumentData = DocumentData> = {
|
|
3
|
+
db: Firestore;
|
|
4
|
+
reference?: CollectionReference<AppModelType, DbModelType> | DocumentReference<AppModelType, DbModelType>;
|
|
5
|
+
path?: string;
|
|
6
|
+
pathSegments?: string[];
|
|
7
|
+
};
|
|
8
|
+
export declare const getDocRef: <AppModelType extends DocumentData = DocumentData, DbModelType extends DocumentData = DocumentData>({ db, reference, path, pathSegments }: GetDocRefOptions<AppModelType, DbModelType>) => Promise<DocumentReference<AppModelType, DbModelType>>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { doc } from "firebase/firestore";
|
|
2
|
+
export const getDocRef = async ({ db, reference, path, pathSegments }) => {
|
|
3
|
+
if (!reference && !path) {
|
|
4
|
+
throw new Error("One of the options must be provided: path or reference.");
|
|
5
|
+
}
|
|
6
|
+
const docRef = !reference
|
|
7
|
+
? doc(db, path, ...(pathSegments || []))
|
|
8
|
+
: reference.type === "collection"
|
|
9
|
+
? doc(reference, path, ...(pathSegments || []))
|
|
10
|
+
: reference.type === "document"
|
|
11
|
+
? doc(reference, path, ...(pathSegments || []))
|
|
12
|
+
: null;
|
|
13
|
+
return docRef;
|
|
14
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { DocumentData } from "firebase/firestore";
|
|
2
|
+
import { GetDocRefOptions } from "./getDocRef";
|
|
3
|
+
export type GetDocSnapOptions<AppModelType extends DocumentData = DocumentData, DbModelType extends DocumentData = DocumentData> = GetDocRefOptions<AppModelType, DbModelType>;
|
|
4
|
+
export declare const getDocSnap: <AppModelType extends DocumentData = DocumentData, DbModelType extends DocumentData = DocumentData>({ db, reference, path, pathSegments }: GetDocSnapOptions<AppModelType, DbModelType>) => Promise<import("@firebase/firestore").DocumentSnapshot<AppModelType, DbModelType> | null>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { getDoc as firestoreGetDoc } from "firebase/firestore";
|
|
2
|
+
import { getDocRef } from "./getDocRef";
|
|
3
|
+
export const getDocSnap = async ({ db, reference, path, pathSegments }) => {
|
|
4
|
+
const docRef = await getDocRef({ db, reference, path, pathSegments });
|
|
5
|
+
if (docRef) {
|
|
6
|
+
return await firestoreGetDoc(docRef);
|
|
7
|
+
}
|
|
8
|
+
return null;
|
|
9
|
+
};
|
|
@@ -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,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,22 @@
|
|
|
1
|
+
import { useRemoteConfig } from "../useRemoteConfig";
|
|
2
|
+
import { ensureInitialized, fetchAndActivate } from "firebase/remote-config";
|
|
3
|
+
import { useCallback, useMemo, useState } from "react";
|
|
4
|
+
export const useFetchAndActivate = () => {
|
|
5
|
+
const remoteConfig = useRemoteConfig();
|
|
6
|
+
const [isFetched, setIsFetched] = useState(false);
|
|
7
|
+
const fetchAndActivateCallback = useCallback(async () => {
|
|
8
|
+
try {
|
|
9
|
+
await ensureInitialized(remoteConfig);
|
|
10
|
+
await fetchAndActivate(remoteConfig);
|
|
11
|
+
setIsFetched(true);
|
|
12
|
+
}
|
|
13
|
+
catch (e) {
|
|
14
|
+
setIsFetched(true);
|
|
15
|
+
console.log(`Cannot read remote config: ${e?.message}`);
|
|
16
|
+
}
|
|
17
|
+
}, [isFetched]);
|
|
18
|
+
return useMemo(() => ({
|
|
19
|
+
fetchAndActivate: fetchAndActivateCallback,
|
|
20
|
+
isFetched
|
|
21
|
+
}), [isFetched, fetchAndActivateCallback]);
|
|
22
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const useGetValue: (key: string) => import("@firebase/remote-config").Value | null;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { getValue } from "firebase/remote-config";
|
|
2
|
+
import { useRemoteConfig } from "../useRemoteConfig";
|
|
3
|
+
import { useMemo } from "react";
|
|
4
|
+
export const useGetValue = (key) => {
|
|
5
|
+
const remoteConfig = useRemoteConfig();
|
|
6
|
+
return useMemo(() => {
|
|
7
|
+
return remoteConfig ? getValue(remoteConfig, key) : null;
|
|
8
|
+
}, [remoteConfig?.lastFetchStatus, key]);
|
|
9
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const useAnalytics: () => import("@firebase/analytics").Analytics;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const useAuth: () => import("firebase/auth").Auth;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const useFirebase: () => import("@firebase/app").FirebaseApp;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const useFirestore: () => import("@firebase/firestore").Firestore;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const useRemoteConfig: () => import("@firebase/remote-config").RemoteConfig;
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"author": "Victor Pishuk <victor.pishuk@gmail.com>",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"bugs": {
|
|
5
|
+
"url": "https://github.com/vpishuk/react-query-firebase/issues"
|
|
6
|
+
},
|
|
7
|
+
"dependencies": {
|
|
8
|
+
"firebase": "^11.0.1"
|
|
9
|
+
},
|
|
10
|
+
"peerDependencies": {
|
|
11
|
+
"react": "^19.0.0",
|
|
12
|
+
"@tanstack/react-query": "^5.62.15"
|
|
13
|
+
},
|
|
14
|
+
"publishConfig": {
|
|
15
|
+
"access": "public"
|
|
16
|
+
},
|
|
17
|
+
"description": "This module offers react hooks to work with Firebase",
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@laverve/eslint-utils": "^5.1.1",
|
|
20
|
+
"@types/react": "^19.0.2",
|
|
21
|
+
"husky": "^9.1.1",
|
|
22
|
+
"lint-staged": "^15.1.0",
|
|
23
|
+
"prettier": "^3.0.3",
|
|
24
|
+
"react": "^19.0.0",
|
|
25
|
+
"typescript": "^5.2.2"
|
|
26
|
+
},
|
|
27
|
+
"homepage": "https://github.com/vpishuk/react-query-firebase",
|
|
28
|
+
"keywords": [
|
|
29
|
+
"firebase",
|
|
30
|
+
"react",
|
|
31
|
+
"hooks"
|
|
32
|
+
],
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"main": "./dist/src/index.js",
|
|
35
|
+
"types": "./dist/src/index.d.ts",
|
|
36
|
+
"name": "react-query-firebase",
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "https://github.com/vpishuk/react-query-firebase.git"
|
|
40
|
+
},
|
|
41
|
+
"files": [
|
|
42
|
+
"./dist/src/",
|
|
43
|
+
"./src/",
|
|
44
|
+
"package.json",
|
|
45
|
+
"package-lock.json",
|
|
46
|
+
"README.md",
|
|
47
|
+
"LICENSE"
|
|
48
|
+
],
|
|
49
|
+
"scripts": {
|
|
50
|
+
"build": "rm -rf ./dist/ && tsc -p tsconfig.build.json",
|
|
51
|
+
"lint": "eslint",
|
|
52
|
+
"lint:fix": "eslint --fix",
|
|
53
|
+
"lint:staged": "lint-staged",
|
|
54
|
+
"prepare": "husky"
|
|
55
|
+
},
|
|
56
|
+
"version": "1.0.0"
|
|
57
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { createContext } from "react";
|
|
3
|
+
|
|
4
|
+
import { Auth } from "firebase/auth";
|
|
5
|
+
import { Analytics } from "firebase/analytics";
|
|
6
|
+
import { Firestore } from "firebase/firestore";
|
|
7
|
+
import { FirebaseApp } from "firebase/app";
|
|
8
|
+
import { RemoteConfig } from "firebase/remote-config";
|
|
9
|
+
|
|
10
|
+
export type FirebaseContextValue = {
|
|
11
|
+
auth: Auth;
|
|
12
|
+
analytics: Analytics;
|
|
13
|
+
firebase: FirebaseApp;
|
|
14
|
+
remoteConfig: RemoteConfig;
|
|
15
|
+
firestore: Firestore;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const FirebaseContext = createContext<Partial<FirebaseContextValue>>({});
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import React, { PropsWithChildren, useMemo } from "react";
|
|
2
|
+
import { FirebaseContext, FirebaseContextValue } from "./FirebaseContext";
|
|
3
|
+
import { connectAuthEmulator, getAuth } from "firebase/auth";
|
|
4
|
+
import { getAnalytics } from "firebase/analytics";
|
|
5
|
+
import { getRemoteConfig, RemoteConfigSettings } from "firebase/remote-config";
|
|
6
|
+
import { connectFirestoreEmulator, getFirestore } from "firebase/firestore";
|
|
7
|
+
import { FirebaseOptions, initializeApp } from "firebase/app";
|
|
8
|
+
|
|
9
|
+
type FirestorEmulatorConfig = {
|
|
10
|
+
host: string;
|
|
11
|
+
port: number;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
type AuthEmulatorConfig = {
|
|
15
|
+
host: string;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
type Emulators = {
|
|
19
|
+
firestore?: FirestorEmulatorConfig;
|
|
20
|
+
auth?: AuthEmulatorConfig;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
type FirebaseContextProvider = PropsWithChildren & {
|
|
24
|
+
emulators?: Emulators;
|
|
25
|
+
options: FirebaseOptions;
|
|
26
|
+
authEnabled?: boolean;
|
|
27
|
+
analyticsEnabled?: boolean;
|
|
28
|
+
firestoreEnabled?: boolean;
|
|
29
|
+
remoteConfigSettings?: RemoteConfigSettings;
|
|
30
|
+
remoteConfigDefaults?: { [key: string]: string | number | boolean };
|
|
31
|
+
remoteConfigEnabled?: boolean;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const FirebaseContextProvider: React.FC<FirebaseContextProvider> = ({
|
|
35
|
+
emulators,
|
|
36
|
+
options,
|
|
37
|
+
children,
|
|
38
|
+
authEnabled = true,
|
|
39
|
+
firestoreEnabled = true,
|
|
40
|
+
analyticsEnabled = true,
|
|
41
|
+
remoteConfigEnabled = true,
|
|
42
|
+
remoteConfigSettings,
|
|
43
|
+
remoteConfigDefaults = {}
|
|
44
|
+
}) => {
|
|
45
|
+
const firebase = useMemo(() => {
|
|
46
|
+
return initializeApp(options);
|
|
47
|
+
}, [options]);
|
|
48
|
+
|
|
49
|
+
const contextValue = useMemo(() => {
|
|
50
|
+
const value: Partial<FirebaseContextValue> = {};
|
|
51
|
+
|
|
52
|
+
if (firestoreEnabled) {
|
|
53
|
+
const firestore = getFirestore(firebase);
|
|
54
|
+
|
|
55
|
+
if (emulators?.firestore?.host && emulators?.firestore?.port) {
|
|
56
|
+
connectFirestoreEmulator(firestore, emulators.firestore.host, emulators.firestore.port);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
value.firestore = firestore;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (authEnabled) {
|
|
63
|
+
const auth = getAuth(firebase);
|
|
64
|
+
if (emulators?.auth?.host) {
|
|
65
|
+
connectAuthEmulator(auth, emulators?.auth?.host, {
|
|
66
|
+
disableWarnings: true
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
value.auth = auth;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (analyticsEnabled && options.measurementId && typeof window !== "undefined") {
|
|
73
|
+
const analytics = getAnalytics(firebase);
|
|
74
|
+
value.analytics = analytics;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (remoteConfigEnabled && typeof window !== "undefined") {
|
|
78
|
+
const remoteConfig = getRemoteConfig(firebase);
|
|
79
|
+
if (remoteConfigSettings) {
|
|
80
|
+
remoteConfig.settings.fetchTimeoutMillis = remoteConfigSettings.fetchTimeoutMillis;
|
|
81
|
+
remoteConfig.settings.minimumFetchIntervalMillis = remoteConfigSettings.minimumFetchIntervalMillis;
|
|
82
|
+
remoteConfig.defaultConfig = remoteConfigDefaults;
|
|
83
|
+
}
|
|
84
|
+
value.remoteConfig = remoteConfig;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return { firebase, ...value };
|
|
88
|
+
}, [firebase]);
|
|
89
|
+
|
|
90
|
+
return <FirebaseContext.Provider value={contextValue}>{children}</FirebaseContext.Provider>;
|
|
91
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./useLogEvent";
|