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,27 @@
|
|
|
1
|
+
import { logEvent } from "firebase/analytics";
|
|
2
|
+
import { useAnalytics } from "../useAnalytics";
|
|
3
|
+
import { useCallback, useMemo } from "react";
|
|
4
|
+
|
|
5
|
+
type UseLogEventOptions = {
|
|
6
|
+
eventName: string;
|
|
7
|
+
eventParams?: {
|
|
8
|
+
[key: string]: unknown;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const useLogEvent = ({ eventName, eventParams }: UseLogEventOptions) => {
|
|
13
|
+
const analytics = useAnalytics();
|
|
14
|
+
|
|
15
|
+
const logEventCallback = useCallback(() => {
|
|
16
|
+
if (analytics) {
|
|
17
|
+
logEvent(analytics, eventName, eventParams);
|
|
18
|
+
}
|
|
19
|
+
}, [eventName, eventParams]);
|
|
20
|
+
|
|
21
|
+
return useMemo(
|
|
22
|
+
() => ({
|
|
23
|
+
logEvent: logEventCallback
|
|
24
|
+
}),
|
|
25
|
+
[logEventCallback]
|
|
26
|
+
);
|
|
27
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from "./mutation-keys";
|
|
2
|
+
export * from "./useCreateUserWitEmailAndPasswordMutation";
|
|
3
|
+
export * from "./useSendEmailVerificationMutation";
|
|
4
|
+
export * from "./useSignInWitEmailAndPasswordMutation";
|
|
5
|
+
export * from "./useCurrentUser";
|
|
6
|
+
export * from "./useAuthStateReady";
|
|
7
|
+
export * from "./useSignInWitRedirectMutation";
|
|
8
|
+
export * from "./useUpdateProfileMutation";
|
|
9
|
+
export * from "./useSignOutMutation";
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export const CREATE_USER_WITH_EMAIL_AND_PASSWORD_MUTATION_KEY = [
|
|
2
|
+
"FIREBASE",
|
|
3
|
+
"AUTH",
|
|
4
|
+
"CREATE_USER_WITH_EMAIL_AND_PASSWORD_MUTATION"
|
|
5
|
+
] as const;
|
|
6
|
+
export const SEND_EMAIL_VERIFICATION_MUTATION_KEY = ["FIREBASE", "AUTH", "SEND_EMAIL_VERIFICATION_MUTATION"] as const;
|
|
7
|
+
export const SIGN_IN_WITH_EMAIL_AND_PASSWORD_MUTATION_KEY = [
|
|
8
|
+
"FIREBASE",
|
|
9
|
+
"AUTH",
|
|
10
|
+
"SIGN_IN_WITH_EMAIL_AND_PASSWORD_MUTATION"
|
|
11
|
+
] as const;
|
|
12
|
+
export const SIGN_IN_WITH_REDIRECT_MUTATION_KEY = ["FIREBASE", "AUTH", "SIGN_IN_WITH_REDIRECT_MUTATION"] as const;
|
|
13
|
+
export const SIGN_OUT_MUTATION_KEY = ["FIREBASE", "AUTH", "SIGN_OUT"] as const;
|
|
14
|
+
export const REAUTHENTICATE_WITH_REDIRECT_MUTATION_KEY = ["FIREBASE", "AUTH", "REAUTHENTICATE_WITH_REDIRECT"] as const;
|
|
15
|
+
export const REAUTHENTICATE_WITH_CREDENTIAL_MUTATION_KEY = [
|
|
16
|
+
"FIREBASE",
|
|
17
|
+
"AUTH",
|
|
18
|
+
"REAUTHENTICATE_WITH_CREDENTIAL"
|
|
19
|
+
] as const;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { useAuth } from "../useAuth";
|
|
2
|
+
import { useCallback, useEffect, useState } from "react";
|
|
3
|
+
|
|
4
|
+
export const useAuthStateReady = () => {
|
|
5
|
+
const firebaseAuth = useAuth();
|
|
6
|
+
|
|
7
|
+
const [isAuthStateReady, setIsAuthStateReady] = useState(false);
|
|
8
|
+
|
|
9
|
+
const callback = useCallback(async () => {
|
|
10
|
+
await firebaseAuth.authStateReady();
|
|
11
|
+
setIsAuthStateReady(true);
|
|
12
|
+
}, [isAuthStateReady]);
|
|
13
|
+
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
callback();
|
|
16
|
+
}, [callback]);
|
|
17
|
+
|
|
18
|
+
return isAuthStateReady;
|
|
19
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { useMutation, UseMutationOptions } from "@tanstack/react-query";
|
|
2
|
+
import { createUserWithEmailAndPassword, UserCredential } from "firebase/auth";
|
|
3
|
+
import { useAuth } from "../useAuth";
|
|
4
|
+
import { FirebaseError } from "firebase/app";
|
|
5
|
+
import { CREATE_USER_WITH_EMAIL_AND_PASSWORD_MUTATION_KEY } from "./mutation-keys";
|
|
6
|
+
|
|
7
|
+
export type UseCreateUserWitEmailAndPasswordMutationVariables = {
|
|
8
|
+
email: string;
|
|
9
|
+
password: string;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const useCreateUserWitEmailAndPasswordMutation = <TContext = unknown>(
|
|
13
|
+
options: Omit<
|
|
14
|
+
UseMutationOptions<UserCredential, FirebaseError, UseCreateUserWitEmailAndPasswordMutationVariables, TContext>,
|
|
15
|
+
"mutationKey" | "mutationFn"
|
|
16
|
+
> = {}
|
|
17
|
+
) => {
|
|
18
|
+
const firebaseAuth = useAuth();
|
|
19
|
+
|
|
20
|
+
return useMutation({
|
|
21
|
+
...options,
|
|
22
|
+
mutationFn: async ({ email, password }: UseCreateUserWitEmailAndPasswordMutationVariables) =>
|
|
23
|
+
await createUserWithEmailAndPassword(firebaseAuth, email, password),
|
|
24
|
+
mutationKey: CREATE_USER_WITH_EMAIL_AND_PASSWORD_MUTATION_KEY
|
|
25
|
+
});
|
|
26
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { useAuth } from "../useAuth";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
|
|
4
|
+
export const useCurrentUser = () => {
|
|
5
|
+
const firebaseAuth = useAuth();
|
|
6
|
+
|
|
7
|
+
const [currentUser, setCurrentUser] = useState(firebaseAuth.currentUser);
|
|
8
|
+
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
const unsubscribe = firebaseAuth.onAuthStateChanged((user) => {
|
|
11
|
+
setCurrentUser(user);
|
|
12
|
+
});
|
|
13
|
+
return () => {
|
|
14
|
+
unsubscribe();
|
|
15
|
+
};
|
|
16
|
+
}, [currentUser?.uid ?? ""]);
|
|
17
|
+
|
|
18
|
+
return currentUser;
|
|
19
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { useCallback, useEffect, useState } from "react";
|
|
2
|
+
import { useCurrentUser } from "./useCurrentUser";
|
|
3
|
+
|
|
4
|
+
export const useIdToken = () => {
|
|
5
|
+
const currentUser = useCurrentUser();
|
|
6
|
+
const [idToken, setIdToken] = useState("");
|
|
7
|
+
|
|
8
|
+
const callback = useCallback(async () => {
|
|
9
|
+
if (!currentUser) {
|
|
10
|
+
setIdToken("");
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const idToken = await currentUser.getIdToken();
|
|
15
|
+
setIdToken(idToken);
|
|
16
|
+
}, [currentUser, idToken]);
|
|
17
|
+
|
|
18
|
+
const refresh = useCallback(async () => {
|
|
19
|
+
if (!currentUser) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const idToken = await currentUser.getIdToken(true);
|
|
24
|
+
setIdToken(idToken);
|
|
25
|
+
}, [currentUser, idToken]);
|
|
26
|
+
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
callback();
|
|
29
|
+
}, [currentUser?.uid ?? ""]);
|
|
30
|
+
|
|
31
|
+
return {
|
|
32
|
+
idToken,
|
|
33
|
+
refresh
|
|
34
|
+
};
|
|
35
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { useMutation, UseMutationOptions } from "@tanstack/react-query";
|
|
2
|
+
import { reauthenticateWithCredential, User, AuthCredential, UserCredential } from "firebase/auth";
|
|
3
|
+
import { REAUTHENTICATE_WITH_CREDENTIAL_MUTATION_KEY } from "./mutation-keys";
|
|
4
|
+
import { FirebaseError } from "firebase/app";
|
|
5
|
+
|
|
6
|
+
export type UseReauthenticateWitCredentialMutationVariables = {
|
|
7
|
+
credential: AuthCredential;
|
|
8
|
+
user: User;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const useReauthenticateWitCredentialMutation = <TContext = unknown>(
|
|
12
|
+
options: Omit<
|
|
13
|
+
UseMutationOptions<UserCredential, FirebaseError, UseReauthenticateWitCredentialMutationVariables, TContext>,
|
|
14
|
+
"mutationKey" | "mutationFn"
|
|
15
|
+
> = {}
|
|
16
|
+
) => {
|
|
17
|
+
return useMutation({
|
|
18
|
+
...options,
|
|
19
|
+
mutationFn: async ({ credential, user }: UseReauthenticateWitCredentialMutationVariables) =>
|
|
20
|
+
reauthenticateWithCredential(user, credential),
|
|
21
|
+
mutationKey: REAUTHENTICATE_WITH_CREDENTIAL_MUTATION_KEY
|
|
22
|
+
});
|
|
23
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { useMutation, UseMutationOptions } from "@tanstack/react-query";
|
|
2
|
+
import { reauthenticateWithRedirect, AuthProvider, PopupRedirectResolver, User } from "firebase/auth";
|
|
3
|
+
|
|
4
|
+
import { REAUTHENTICATE_WITH_REDIRECT_MUTATION_KEY } from "./mutation-keys";
|
|
5
|
+
import { FirebaseError } from "firebase/app";
|
|
6
|
+
|
|
7
|
+
export type UseReauthenticateWitRedirectMutationVariables = {
|
|
8
|
+
authProvider: AuthProvider;
|
|
9
|
+
popupRedirectResolver?: PopupRedirectResolver;
|
|
10
|
+
user: User;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const useReauthenticateWitRedirectMutation = <TContext = unknown>(
|
|
14
|
+
options: Omit<
|
|
15
|
+
UseMutationOptions<void, FirebaseError, UseReauthenticateWitRedirectMutationVariables, TContext>,
|
|
16
|
+
"mutationKey" | "mutationFn"
|
|
17
|
+
> = {}
|
|
18
|
+
) => {
|
|
19
|
+
return useMutation({
|
|
20
|
+
...options,
|
|
21
|
+
mutationFn: async ({
|
|
22
|
+
authProvider,
|
|
23
|
+
user,
|
|
24
|
+
popupRedirectResolver
|
|
25
|
+
}: UseReauthenticateWitRedirectMutationVariables) =>
|
|
26
|
+
reauthenticateWithRedirect(user, authProvider, popupRedirectResolver),
|
|
27
|
+
mutationKey: REAUTHENTICATE_WITH_REDIRECT_MUTATION_KEY
|
|
28
|
+
});
|
|
29
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { useMutation, UseMutationOptions } from "@tanstack/react-query";
|
|
2
|
+
import { sendEmailVerification, User } from "firebase/auth";
|
|
3
|
+
|
|
4
|
+
import { SEND_EMAIL_VERIFICATION_MUTATION_KEY } from "./mutation-keys";
|
|
5
|
+
import { FirebaseError } from "firebase/app";
|
|
6
|
+
|
|
7
|
+
export type UseSendEmailVerificationMutationVariables = {
|
|
8
|
+
user: User;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const useSendEmailVerificationMutation = <TContext = unknown>(
|
|
12
|
+
options: Omit<
|
|
13
|
+
UseMutationOptions<void, FirebaseError, UseSendEmailVerificationMutationVariables, TContext>,
|
|
14
|
+
"queryKey" | "queryFn"
|
|
15
|
+
> = {}
|
|
16
|
+
) => {
|
|
17
|
+
return useMutation({
|
|
18
|
+
...options,
|
|
19
|
+
mutationFn: async ({ user }) => await sendEmailVerification(user),
|
|
20
|
+
mutationKey: SEND_EMAIL_VERIFICATION_MUTATION_KEY
|
|
21
|
+
});
|
|
22
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { useMutation, UseMutationOptions } from "@tanstack/react-query";
|
|
2
|
+
import { signInWithEmailAndPassword, UserCredential } from "firebase/auth";
|
|
3
|
+
|
|
4
|
+
import { useAuth } from "../useAuth";
|
|
5
|
+
import { SIGN_IN_WITH_EMAIL_AND_PASSWORD_MUTATION_KEY } from "./mutation-keys";
|
|
6
|
+
import { FirebaseError } from "firebase/app";
|
|
7
|
+
|
|
8
|
+
export type UseSignInWitEmailAndPasswordMutationVariables = {
|
|
9
|
+
email: string;
|
|
10
|
+
password: string;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const useSignInWitEmailAndPasswordMutation = <TContext = unknown>(
|
|
14
|
+
options: Omit<
|
|
15
|
+
UseMutationOptions<UserCredential, FirebaseError, UseSignInWitEmailAndPasswordMutationVariables, TContext>,
|
|
16
|
+
"mutationKey" | "mutationFn"
|
|
17
|
+
> = {}
|
|
18
|
+
) => {
|
|
19
|
+
const firebaseAuth = useAuth();
|
|
20
|
+
|
|
21
|
+
return useMutation({
|
|
22
|
+
...options,
|
|
23
|
+
mutationFn: async ({ email, password }: UseSignInWitEmailAndPasswordMutationVariables) =>
|
|
24
|
+
signInWithEmailAndPassword(firebaseAuth, email, password),
|
|
25
|
+
mutationKey: SIGN_IN_WITH_EMAIL_AND_PASSWORD_MUTATION_KEY
|
|
26
|
+
});
|
|
27
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { useMutation, UseMutationOptions } from "@tanstack/react-query";
|
|
2
|
+
import { signInWithRedirect, AuthProvider, PopupRedirectResolver } from "firebase/auth";
|
|
3
|
+
|
|
4
|
+
import { useAuth } from "../useAuth";
|
|
5
|
+
import { SIGN_IN_WITH_REDIRECT_MUTATION_KEY } from "./mutation-keys";
|
|
6
|
+
import { FirebaseError } from "firebase/app";
|
|
7
|
+
|
|
8
|
+
export type UseSignInWitRedirectMutationVariables = {
|
|
9
|
+
authProvider: AuthProvider;
|
|
10
|
+
popupRedirectResolver?: PopupRedirectResolver;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const useSignInWitRedirectMutation = <TContext = unknown>(
|
|
14
|
+
options: Omit<
|
|
15
|
+
UseMutationOptions<void, FirebaseError, UseSignInWitRedirectMutationVariables, TContext>,
|
|
16
|
+
"mutationKey" | "mutationFn"
|
|
17
|
+
> = {}
|
|
18
|
+
) => {
|
|
19
|
+
const firebaseAuth = useAuth();
|
|
20
|
+
|
|
21
|
+
return useMutation({
|
|
22
|
+
...options,
|
|
23
|
+
mutationFn: async ({ authProvider, popupRedirectResolver }: UseSignInWitRedirectMutationVariables) =>
|
|
24
|
+
signInWithRedirect(firebaseAuth, authProvider, popupRedirectResolver),
|
|
25
|
+
mutationKey: SIGN_IN_WITH_REDIRECT_MUTATION_KEY
|
|
26
|
+
});
|
|
27
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { useMutation, UseMutationOptions } from "@tanstack/react-query";
|
|
2
|
+
import { signOut } from "firebase/auth";
|
|
3
|
+
|
|
4
|
+
import { SIGN_OUT_MUTATION_KEY } from "./mutation-keys";
|
|
5
|
+
import { FirebaseError } from "firebase/app";
|
|
6
|
+
import { useAuth } from "../useAuth";
|
|
7
|
+
|
|
8
|
+
export const useSignOutMutation = <TContext = unknown>(
|
|
9
|
+
options: Omit<UseMutationOptions<void, FirebaseError, void, TContext>, "queryKey" | "queryFn"> = {}
|
|
10
|
+
) => {
|
|
11
|
+
const firebaseAuth = useAuth();
|
|
12
|
+
|
|
13
|
+
return useMutation({
|
|
14
|
+
...options,
|
|
15
|
+
mutationFn: async () => await signOut(firebaseAuth),
|
|
16
|
+
mutationKey: SIGN_OUT_MUTATION_KEY
|
|
17
|
+
});
|
|
18
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { useMutation, UseMutationOptions } from "@tanstack/react-query";
|
|
2
|
+
import { updateProfile, User } from "firebase/auth";
|
|
3
|
+
import { FirebaseError } from "firebase/app";
|
|
4
|
+
import { CREATE_USER_WITH_EMAIL_AND_PASSWORD_MUTATION_KEY } from "./mutation-keys";
|
|
5
|
+
|
|
6
|
+
export type UseUpdateProfileMutationVariables = {
|
|
7
|
+
displayName?: string;
|
|
8
|
+
user: User;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const useUpdateProfileMutation = <TContext = unknown>(
|
|
12
|
+
options: Omit<
|
|
13
|
+
UseMutationOptions<void, FirebaseError, UseUpdateProfileMutationVariables, TContext>,
|
|
14
|
+
"mutationKey" | "mutationFn"
|
|
15
|
+
> = {}
|
|
16
|
+
) => {
|
|
17
|
+
return useMutation({
|
|
18
|
+
...options,
|
|
19
|
+
mutationFn: async ({ displayName, user }: UseUpdateProfileMutationVariables) =>
|
|
20
|
+
await updateProfile(user, { displayName }),
|
|
21
|
+
mutationKey: CREATE_USER_WITH_EMAIL_AND_PASSWORD_MUTATION_KEY
|
|
22
|
+
});
|
|
23
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export * from "./useAddDocMutation";
|
|
2
|
+
export * from "./useBatchWrite";
|
|
3
|
+
export * from "./useCollectionReference";
|
|
4
|
+
export * from "./useCompositeFilter";
|
|
5
|
+
export * from "./useCountQuery";
|
|
6
|
+
export * from "./useDeleteDocMutation";
|
|
7
|
+
export * from "./useDocReference";
|
|
8
|
+
export * from "./useDocReferences";
|
|
9
|
+
export * from "./useGetDocData";
|
|
10
|
+
export * from "./useInfiniteQuery";
|
|
11
|
+
export * from "./useQuery";
|
|
12
|
+
export * from "./useRunTransaction";
|
|
13
|
+
export * from "./useSetDocMutation";
|
|
14
|
+
export * from "./useUpdateDocMutation";
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { useMutation, UseMutationOptions } from "@tanstack/react-query";
|
|
2
|
+
import {
|
|
3
|
+
DocumentData,
|
|
4
|
+
addDoc,
|
|
5
|
+
WithFieldValue,
|
|
6
|
+
CollectionReference,
|
|
7
|
+
getDoc,
|
|
8
|
+
FirestoreDataConverter
|
|
9
|
+
} from "firebase/firestore";
|
|
10
|
+
|
|
11
|
+
import { FirebaseError } from "firebase/app";
|
|
12
|
+
import { useMemo } from "react";
|
|
13
|
+
|
|
14
|
+
export type UseAddDocMutationValues<AppModelType> = {
|
|
15
|
+
data: WithFieldValue<AppModelType>;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export type UseAddDocMutationOptions<
|
|
19
|
+
AppModelType extends DocumentData = DocumentData,
|
|
20
|
+
DbModelType extends DocumentData = DocumentData,
|
|
21
|
+
TContext = unknown
|
|
22
|
+
> = {
|
|
23
|
+
reference: CollectionReference<AppModelType, DbModelType>;
|
|
24
|
+
converter?: FirestoreDataConverter<AppModelType, DbModelType>;
|
|
25
|
+
options?: Omit<
|
|
26
|
+
UseMutationOptions<AppModelType, FirebaseError, UseAddDocMutationValues<AppModelType>, TContext>,
|
|
27
|
+
"mutationFn" | "mutationKey"
|
|
28
|
+
>;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const useAddDocMutation = <
|
|
32
|
+
AppModelType extends DocumentData = DocumentData,
|
|
33
|
+
DbModelType extends DocumentData = DocumentData,
|
|
34
|
+
TContext = unknown
|
|
35
|
+
>({
|
|
36
|
+
reference,
|
|
37
|
+
converter,
|
|
38
|
+
options = {}
|
|
39
|
+
}: UseAddDocMutationOptions<AppModelType, DbModelType, TContext>) => {
|
|
40
|
+
const mutationKey = useMemo(() => [reference.path], [reference.path]);
|
|
41
|
+
|
|
42
|
+
return useMutation({
|
|
43
|
+
...options,
|
|
44
|
+
mutationFn: async ({ data }) => {
|
|
45
|
+
const docRef = await addDoc<AppModelType, DbModelType>(reference, data);
|
|
46
|
+
const docSnap = await getDoc(converter ? docRef.withConverter(converter) : docRef);
|
|
47
|
+
return docSnap.data() as AppModelType;
|
|
48
|
+
},
|
|
49
|
+
mutationKey
|
|
50
|
+
});
|
|
51
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { useMutation, UseMutationOptions } from "@tanstack/react-query";
|
|
2
|
+
import { writeBatch, WriteBatch } from "firebase/firestore";
|
|
3
|
+
|
|
4
|
+
import { FirebaseError } from "firebase/app";
|
|
5
|
+
import { useFirestore } from "../useFirestore";
|
|
6
|
+
|
|
7
|
+
export type UseBatchWriteVariables = (batch: WriteBatch) => Promise<void> | void;
|
|
8
|
+
|
|
9
|
+
export type UseBatchWriteOptions<TContext = unknown> = {
|
|
10
|
+
options?: Omit<UseMutationOptions<void, FirebaseError, UseBatchWriteVariables, TContext>, "mutationFn">;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const useBatchWrite = <TContext = unknown>({ options = {} }: UseBatchWriteOptions<TContext> = {}) => {
|
|
14
|
+
const db = useFirestore();
|
|
15
|
+
|
|
16
|
+
return useMutation({
|
|
17
|
+
...options,
|
|
18
|
+
mutationFn: async (batchWriteFn) => {
|
|
19
|
+
const batch = writeBatch(db);
|
|
20
|
+
await batchWriteFn(batch);
|
|
21
|
+
return batch.commit();
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { collection, CollectionReference, DocumentData, DocumentReference } from "firebase/firestore";
|
|
2
|
+
|
|
3
|
+
import { useMemo } from "react";
|
|
4
|
+
import { useFirestore } from "../useFirestore";
|
|
5
|
+
|
|
6
|
+
export type UseCollectionReferenceOptions<AppModelType, DbModelType extends DocumentData = DocumentData> = {
|
|
7
|
+
reference?: CollectionReference<AppModelType, DbModelType> | DocumentReference<AppModelType, DbModelType>;
|
|
8
|
+
path: string;
|
|
9
|
+
pathSegments?: string[];
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const useCollectionReference = <AppModelType, DbModelType extends DocumentData = DocumentData>({
|
|
13
|
+
path,
|
|
14
|
+
reference,
|
|
15
|
+
pathSegments
|
|
16
|
+
}: UseCollectionReferenceOptions<AppModelType, DbModelType>) => {
|
|
17
|
+
const db = useFirestore();
|
|
18
|
+
|
|
19
|
+
return useMemo(() => {
|
|
20
|
+
return !reference
|
|
21
|
+
? collection(db, path || "", ...(pathSegments || []))
|
|
22
|
+
: reference.type === "collection"
|
|
23
|
+
? collection(reference, path, ...(pathSegments || []))
|
|
24
|
+
: collection(reference, path, ...(pathSegments || []));
|
|
25
|
+
}, [path, reference?.path, pathSegments]);
|
|
26
|
+
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DocumentData,
|
|
3
|
+
QueryCompositeFilterConstraint,
|
|
4
|
+
QueryFilterConstraint,
|
|
5
|
+
WhereFilterOp,
|
|
6
|
+
and,
|
|
7
|
+
documentId,
|
|
8
|
+
or,
|
|
9
|
+
where
|
|
10
|
+
} from "firebase/firestore";
|
|
11
|
+
import { useMemo } from "react";
|
|
12
|
+
|
|
13
|
+
type CompositeFilterDocumentData = DocumentData;
|
|
14
|
+
|
|
15
|
+
export type QueryElement<DbModelType extends CompositeFilterDocumentData = CompositeFilterDocumentData> =
|
|
16
|
+
Partial<QueryCompositeFilterConstraint> & {
|
|
17
|
+
children?: QueryElement[];
|
|
18
|
+
field?: keyof (DbModelType & { documentId?: string[] });
|
|
19
|
+
value?: DbModelType[keyof DbModelType];
|
|
20
|
+
op?: WhereFilterOp;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export type CompositeFilter<DbModelType extends CompositeFilterDocumentData = CompositeFilterDocumentData> =
|
|
24
|
+
QueryCompositeFilterConstraint & {
|
|
25
|
+
children: QueryElement<DbModelType & { documentId?: string[] }>[];
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export type UseCompositeFilter<DbModelType extends CompositeFilterDocumentData = CompositeFilterDocumentData> = {
|
|
29
|
+
query?: CompositeFilter<DbModelType>;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const buildCompositeQuery = <DbModelType extends CompositeFilterDocumentData = CompositeFilterDocumentData>(
|
|
33
|
+
query: QueryElement<DbModelType>
|
|
34
|
+
): QueryFilterConstraint | null => {
|
|
35
|
+
if (query.children) {
|
|
36
|
+
const queryConstraints = query.children
|
|
37
|
+
.map((subQuery) => buildCompositeQuery(subQuery))
|
|
38
|
+
.filter<QueryFilterConstraint>((constraint) => !!constraint);
|
|
39
|
+
|
|
40
|
+
if (queryConstraints.length <= 0) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return (query as CompositeFilter).type === "or" ? or(...queryConstraints) : and(...queryConstraints);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (query.field && query.op) {
|
|
48
|
+
return where(query.field === "documentId" ? documentId() : (query.field as string), query.op, query.value);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return null;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export const useCompositeFilter = <DbModelType extends CompositeFilterDocumentData = CompositeFilterDocumentData>({
|
|
55
|
+
query
|
|
56
|
+
}: UseCompositeFilter<DbModelType>) => {
|
|
57
|
+
return useMemo(() => {
|
|
58
|
+
const queryConstraints =
|
|
59
|
+
query?.children?.map?.((subQuery) => buildCompositeQuery(subQuery))?.filter<QueryFilterConstraint>?.(
|
|
60
|
+
(constraint) => !!constraint
|
|
61
|
+
) ?? [];
|
|
62
|
+
|
|
63
|
+
if (queryConstraints.length <= 0) {
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
return query?.type === "or" ? or(...queryConstraints) : and(...queryConstraints);
|
|
67
|
+
}, [query]);
|
|
68
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DocumentData,
|
|
3
|
+
getCountFromServer,
|
|
4
|
+
Query,
|
|
5
|
+
query,
|
|
6
|
+
QueryCompositeFilterConstraint,
|
|
7
|
+
QueryConstraint,
|
|
8
|
+
QueryNonFilterConstraint
|
|
9
|
+
} from "firebase/firestore";
|
|
10
|
+
|
|
11
|
+
import {
|
|
12
|
+
UseQueryResult,
|
|
13
|
+
useQuery as useReactQuery,
|
|
14
|
+
UseQueryOptions as UseReactQueryOptions
|
|
15
|
+
} from "@tanstack/react-query";
|
|
16
|
+
|
|
17
|
+
type UseCountQueryOptions<
|
|
18
|
+
AppModelType extends DocumentData = DocumentData,
|
|
19
|
+
DbModelType extends DocumentData = DocumentData
|
|
20
|
+
> = {
|
|
21
|
+
options: Omit<UseReactQueryOptions<number, Error, number>, "queryFn"> &
|
|
22
|
+
Required<Pick<UseReactQueryOptions<number, Error, number>, "queryKey">>;
|
|
23
|
+
query: Query<AppModelType, DbModelType>;
|
|
24
|
+
queryConstraints?: QueryConstraint[] | QueryNonFilterConstraint[];
|
|
25
|
+
compositeFilter?: QueryCompositeFilterConstraint;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const useCountQuery = <
|
|
29
|
+
AppModelType extends DocumentData = DocumentData,
|
|
30
|
+
DbModelType extends DocumentData = DocumentData
|
|
31
|
+
>({
|
|
32
|
+
options,
|
|
33
|
+
query: queryReference,
|
|
34
|
+
queryConstraints = [],
|
|
35
|
+
compositeFilter
|
|
36
|
+
}: UseCountQueryOptions<AppModelType, DbModelType>): UseQueryResult<number> => {
|
|
37
|
+
return useReactQuery({
|
|
38
|
+
...options,
|
|
39
|
+
queryFn: async () => {
|
|
40
|
+
const queryToExecute = compositeFilter
|
|
41
|
+
? query(queryReference, compositeFilter, ...(queryConstraints as QueryNonFilterConstraint[]))
|
|
42
|
+
: query(queryReference, ...queryConstraints);
|
|
43
|
+
|
|
44
|
+
const querySnapshot = await getCountFromServer(queryToExecute);
|
|
45
|
+
if (querySnapshot) {
|
|
46
|
+
return querySnapshot.data().count;
|
|
47
|
+
}
|
|
48
|
+
return 0;
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { useMutation, UseMutationOptions } from "@tanstack/react-query";
|
|
2
|
+
import { DocumentData, deleteDoc, WithFieldValue, DocumentReference } from "firebase/firestore";
|
|
3
|
+
|
|
4
|
+
import { FirebaseError } from "firebase/app";
|
|
5
|
+
import { useMemo } from "react";
|
|
6
|
+
|
|
7
|
+
export type UseDeleteDocMutationValues<AppModelType> = {
|
|
8
|
+
data: WithFieldValue<AppModelType>;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type UseDeleteDocMutationOptions<
|
|
12
|
+
AppModelType extends DocumentData = DocumentData,
|
|
13
|
+
DbModelType extends DocumentData = DocumentData,
|
|
14
|
+
TContext = unknown
|
|
15
|
+
> = {
|
|
16
|
+
reference: DocumentReference<AppModelType, DbModelType> | null;
|
|
17
|
+
options?: Omit<UseMutationOptions<void, FirebaseError, void, TContext>, "mutationFn" | "mutationKey">;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const useDeleteDocMutation = <
|
|
21
|
+
AppModelType extends DocumentData = DocumentData,
|
|
22
|
+
DbModelType extends DocumentData = DocumentData,
|
|
23
|
+
TContext = unknown
|
|
24
|
+
>({
|
|
25
|
+
reference,
|
|
26
|
+
options = {}
|
|
27
|
+
}: UseDeleteDocMutationOptions<AppModelType, DbModelType, TContext>) => {
|
|
28
|
+
const mutationKey = useMemo(() => [reference?.path], [reference?.path]);
|
|
29
|
+
|
|
30
|
+
return useMutation({
|
|
31
|
+
...options,
|
|
32
|
+
mutationFn: async () => {
|
|
33
|
+
if (!reference) {
|
|
34
|
+
throw new Error("Reference is undefined");
|
|
35
|
+
}
|
|
36
|
+
await deleteDoc<AppModelType, DbModelType>(reference);
|
|
37
|
+
},
|
|
38
|
+
mutationKey
|
|
39
|
+
});
|
|
40
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { doc, CollectionReference, DocumentData, DocumentReference, Firestore } from "firebase/firestore";
|
|
2
|
+
|
|
3
|
+
import { useEffect, useRef } from "react";
|
|
4
|
+
import { useFirestore } from "../useFirestore";
|
|
5
|
+
|
|
6
|
+
export type UseDocReferenceOptions<AppModelType, DbModelType extends DocumentData = DocumentData> = {
|
|
7
|
+
reference?: CollectionReference<AppModelType, DbModelType> | DocumentReference<AppModelType, DbModelType>;
|
|
8
|
+
path?: string;
|
|
9
|
+
pathSegments?: string[];
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const getDocReference = <AppModelType, DbModelType extends DocumentData = DocumentData>(
|
|
13
|
+
db: Firestore,
|
|
14
|
+
{ path, pathSegments, reference }: UseDocReferenceOptions<AppModelType, DbModelType>
|
|
15
|
+
) => {
|
|
16
|
+
if (!path) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
!reference
|
|
22
|
+
? doc(db, path || "", ...(pathSegments || []))
|
|
23
|
+
: reference.type === "collection"
|
|
24
|
+
? doc(reference, path, ...(pathSegments || []))
|
|
25
|
+
: doc(reference, path, ...(pathSegments || []))
|
|
26
|
+
) as DocumentReference<AppModelType, DbModelType>;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const useDocReference = <AppModelType, DbModelType extends DocumentData = DocumentData>({
|
|
30
|
+
path,
|
|
31
|
+
reference,
|
|
32
|
+
pathSegments
|
|
33
|
+
}: UseDocReferenceOptions<AppModelType, DbModelType>) => {
|
|
34
|
+
const db = useFirestore();
|
|
35
|
+
const ref = useRef<DocumentReference<AppModelType, DbModelType> | null>(
|
|
36
|
+
getDocReference(db, { path, pathSegments, reference })
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
ref.current = getDocReference(db, { path, pathSegments, reference });
|
|
41
|
+
}, [path, reference, pathSegments]);
|
|
42
|
+
|
|
43
|
+
return ref.current;
|
|
44
|
+
};
|