react-query-firebase 2.6.0 → 2.6.2

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/package.json CHANGED
@@ -74,5 +74,5 @@
74
74
  "docs:build": "vitepress build docs",
75
75
  "docs:preview": "vitepress preview docs"
76
76
  },
77
- "version": "2.6.0"
77
+ "version": "2.6.2"
78
78
  }
@@ -1,10 +1,10 @@
1
1
  import React, { useEffect, useMemo } from "react";
2
2
  import { FirebaseContext } from "./FirebaseContext";
3
- import auth, { connectAuthEmulator } from "@react-native-firebase/auth";
4
- import analytics, { setAnalyticsCollectionEnabled, setConsent } from "@react-native-firebase/analytics";
5
- import remoteConfig from "@react-native-firebase/remote-config";
6
- import firestore, { connectFirestoreEmulator } from "@react-native-firebase/firestore";
7
- import firebase from "@react-native-firebase/app";
3
+ import { connectAuthEmulator, getAuth } from "@react-native-firebase/auth";
4
+ import { setAnalyticsCollectionEnabled, setConsent, getAnalytics } from "@react-native-firebase/analytics";
5
+ import { getRemoteConfig } from "@react-native-firebase/remote-config";
6
+ import { connectFirestoreEmulator, getFirestore } from "@react-native-firebase/firestore";
7
+ import { getApp } from "@react-native-firebase/app";
8
8
  /**
9
9
  * FirebaseContextProvider component configures and provides Firebase services to its children.
10
10
  * Initializes Firebase app and enables optional Firebase services such as Firestore, Auth, Analytics,
@@ -29,9 +29,9 @@ import firebase from "@react-native-firebase/app";
29
29
  * ```
30
30
  */
31
31
  export const FirebaseContextProvider = ({ emulators, children, authEnabled = true, firestoreEnabled = true, analyticsEnabled = true, consentSettings = {}, remoteConfigEnabled = true, remoteConfigSettings, remoteConfigDefaults = {}, firestoreSettings }) => {
32
- const internalFirebase = useMemo(() => firebase, []);
32
+ const internalFirebase = useMemo(() => getApp(), []);
33
33
  useEffect(() => {
34
- setConsent(analytics(), {
34
+ setConsent(getAnalytics(internalFirebase), {
35
35
  ad_personalization: false,
36
36
  ad_storage: false,
37
37
  ad_user_data: false,
@@ -41,23 +41,23 @@ export const FirebaseContextProvider = ({ emulators, children, authEnabled = tru
41
41
  security_storage: false,
42
42
  ...consentSettings
43
43
  });
44
- }, [consentSettings]);
44
+ }, [consentSettings, internalFirebase]);
45
45
  const internalFirestore = useMemo(() => {
46
46
  if (firestoreEnabled) {
47
47
  if (emulators?.firestore?.host && emulators?.firestore?.port) {
48
- connectFirestoreEmulator(firestore(), emulators.firestore.host, emulators.firestore.port);
48
+ connectFirestoreEmulator(getFirestore(internalFirebase), emulators.firestore.host, emulators.firestore.port);
49
49
  }
50
- const localFirestore = firestore();
50
+ const localFirestore = getFirestore(internalFirebase);
51
51
  if (firestoreSettings) {
52
52
  localFirestore.settings(firestoreSettings);
53
53
  }
54
54
  return localFirestore;
55
55
  }
56
56
  return null;
57
- }, [emulators?.firestore, firestoreEnabled, firestoreSettings]);
57
+ }, [emulators?.firestore, firestoreEnabled, internalFirebase, firestoreSettings]);
58
58
  const internalAuth = useMemo(() => {
59
59
  if (authEnabled) {
60
- const localAuth = auth();
60
+ const localAuth = getAuth(internalFirebase);
61
61
  if (emulators?.auth?.host) {
62
62
  connectAuthEmulator(localAuth, emulators?.auth?.host, {
63
63
  disableWarnings: true
@@ -66,16 +66,16 @@ export const FirebaseContextProvider = ({ emulators, children, authEnabled = tru
66
66
  return localAuth;
67
67
  }
68
68
  return null;
69
- }, [emulators?.auth, authEnabled]);
69
+ }, [emulators?.auth, authEnabled, internalFirebase]);
70
70
  const internalAnalytics = useMemo(() => {
71
71
  if (analyticsEnabled) {
72
- return analytics();
72
+ return getAnalytics(internalFirebase);
73
73
  }
74
74
  return null;
75
- }, [analyticsEnabled]);
75
+ }, [analyticsEnabled, internalFirebase]);
76
76
  const internalRemoteConfig = useMemo(() => {
77
77
  if (remoteConfigEnabled) {
78
- const localRemoteConfig = remoteConfig();
78
+ const localRemoteConfig = getRemoteConfig(internalFirebase);
79
79
  if (remoteConfigSettings) {
80
80
  localRemoteConfig.settings.fetchTimeMillis = remoteConfigSettings.fetchTimeMillis;
81
81
  localRemoteConfig.settings.minimumFetchIntervalMillis = remoteConfigSettings.minimumFetchIntervalMillis;
@@ -84,7 +84,7 @@ export const FirebaseContextProvider = ({ emulators, children, authEnabled = tru
84
84
  return localRemoteConfig;
85
85
  }
86
86
  return null;
87
- }, [remoteConfigEnabled, remoteConfigSettings, remoteConfigDefaults]);
87
+ }, [remoteConfigEnabled, remoteConfigSettings, remoteConfigDefaults, internalFirebase]);
88
88
  const contextValue = useMemo(() => ({
89
89
  firebase: internalFirebase,
90
90
  auth: internalAuth,
@@ -1,14 +1,15 @@
1
1
  import React, { PropsWithChildren, useEffect, useMemo } from "react";
2
2
  import { FirebaseContext, FirebaseContextValue } from "./FirebaseContext";
3
- import auth, { connectAuthEmulator } from "@react-native-firebase/auth";
4
- import analytics, {
3
+ import { connectAuthEmulator, getAuth } from "@react-native-firebase/auth";
4
+ import {
5
5
  FirebaseAnalyticsTypes,
6
6
  setAnalyticsCollectionEnabled,
7
- setConsent
7
+ setConsent,
8
+ getAnalytics
8
9
  } from "@react-native-firebase/analytics";
9
- import remoteConfig, { FirebaseRemoteConfigTypes } from "@react-native-firebase/remote-config";
10
- import firestore, { connectFirestoreEmulator } from "@react-native-firebase/firestore";
11
- import firebase, { ReactNativeFirebase } from "@react-native-firebase/app";
10
+ import { FirebaseRemoteConfigTypes, getRemoteConfig } from "@react-native-firebase/remote-config";
11
+ import { connectFirestoreEmulator, getFirestore } from "@react-native-firebase/firestore";
12
+ import { ReactNativeFirebase, getApp } from "@react-native-firebase/app";
12
13
 
13
14
  /**
14
15
  * @inline
@@ -164,10 +165,10 @@ export const FirebaseContextProvider: React.FC<FirebaseContextProviderProps> = (
164
165
  remoteConfigDefaults = {},
165
166
  firestoreSettings
166
167
  }) => {
167
- const internalFirebase = useMemo(() => firebase, []);
168
+ const internalFirebase = useMemo(() => getApp(), []);
168
169
 
169
170
  useEffect(() => {
170
- setConsent(analytics(), {
171
+ setConsent(getAnalytics(internalFirebase), {
171
172
  ad_personalization: false,
172
173
  ad_storage: false,
173
174
  ad_user_data: false,
@@ -177,15 +178,19 @@ export const FirebaseContextProvider: React.FC<FirebaseContextProviderProps> = (
177
178
  security_storage: false,
178
179
  ...consentSettings
179
180
  });
180
- }, [consentSettings]);
181
+ }, [consentSettings, internalFirebase]);
181
182
 
182
183
  const internalFirestore = useMemo(() => {
183
184
  if (firestoreEnabled) {
184
185
  if (emulators?.firestore?.host && emulators?.firestore?.port) {
185
- connectFirestoreEmulator(firestore(), emulators.firestore.host, emulators.firestore.port);
186
+ connectFirestoreEmulator(
187
+ getFirestore(internalFirebase),
188
+ emulators.firestore.host,
189
+ emulators.firestore.port
190
+ );
186
191
  }
187
192
 
188
- const localFirestore = firestore();
193
+ const localFirestore = getFirestore(internalFirebase);
189
194
  if (firestoreSettings) {
190
195
  localFirestore.settings(firestoreSettings);
191
196
  }
@@ -193,11 +198,11 @@ export const FirebaseContextProvider: React.FC<FirebaseContextProviderProps> = (
193
198
  }
194
199
 
195
200
  return null;
196
- }, [emulators?.firestore, firestoreEnabled, firestoreSettings]);
201
+ }, [emulators?.firestore, firestoreEnabled, internalFirebase, firestoreSettings]);
197
202
 
198
203
  const internalAuth = useMemo(() => {
199
204
  if (authEnabled) {
200
- const localAuth = auth();
205
+ const localAuth = getAuth(internalFirebase);
201
206
  if (emulators?.auth?.host) {
202
207
  connectAuthEmulator(localAuth, emulators?.auth?.host, {
203
208
  disableWarnings: true
@@ -206,18 +211,18 @@ export const FirebaseContextProvider: React.FC<FirebaseContextProviderProps> = (
206
211
  return localAuth;
207
212
  }
208
213
  return null;
209
- }, [emulators?.auth, authEnabled]);
214
+ }, [emulators?.auth, authEnabled, internalFirebase]);
210
215
 
211
216
  const internalAnalytics = useMemo(() => {
212
217
  if (analyticsEnabled) {
213
- return analytics();
218
+ return getAnalytics(internalFirebase);
214
219
  }
215
220
  return null;
216
- }, [analyticsEnabled]);
221
+ }, [analyticsEnabled, internalFirebase]);
217
222
 
218
223
  const internalRemoteConfig = useMemo(() => {
219
224
  if (remoteConfigEnabled) {
220
- const localRemoteConfig = remoteConfig();
225
+ const localRemoteConfig = getRemoteConfig(internalFirebase);
221
226
  if (remoteConfigSettings) {
222
227
  localRemoteConfig.settings.fetchTimeMillis = remoteConfigSettings.fetchTimeMillis;
223
228
  localRemoteConfig.settings.minimumFetchIntervalMillis = remoteConfigSettings.minimumFetchIntervalMillis;
@@ -226,7 +231,7 @@ export const FirebaseContextProvider: React.FC<FirebaseContextProviderProps> = (
226
231
  return localRemoteConfig;
227
232
  }
228
233
  return null;
229
- }, [remoteConfigEnabled, remoteConfigSettings, remoteConfigDefaults]);
234
+ }, [remoteConfigEnabled, remoteConfigSettings, remoteConfigDefaults, internalFirebase]);
230
235
 
231
236
  const contextValue = useMemo(
232
237
  () => ({
@@ -1,6 +1,7 @@
1
1
  import { UseMutationOptions } from "@tanstack/react-query";
2
2
  import { FirebaseFirestoreTypes, WithFieldValue } from "@react-native-firebase/firestore";
3
3
  import { ReactNativeFirebase } from "@react-native-firebase/app";
4
+ import { AppModel } from "../../types";
4
5
  /**
5
6
  * @inline
6
7
  */
@@ -13,7 +14,7 @@ export type UseAddDocMutationValues<AppModelType> = {
13
14
  /**
14
15
  * @inline
15
16
  */
16
- export type UseAddDocMutationOptions<AppModelType extends FirebaseFirestoreTypes.DocumentData = FirebaseFirestoreTypes.DocumentData, TContext = unknown> = {
17
+ export type UseAddDocMutationOptions<AppModelType extends AppModel = AppModel, TContext = unknown> = {
17
18
  /**
18
19
  * Reference to a collection where document must be added
19
20
  */
@@ -47,4 +48,4 @@ export type UseAddDocMutationOptions<AppModelType extends FirebaseFirestoreTypes
47
48
  * };
48
49
  * ```
49
50
  */
50
- export declare const useAddDocMutation: <AppModelType extends FirebaseFirestoreTypes.DocumentData = FirebaseFirestoreTypes.DocumentData, TContext = unknown>({ collectionReference, options }: UseAddDocMutationOptions<AppModelType, TContext>) => import("@tanstack/react-query").UseMutationResult<AppModelType, ReactNativeFirebase.NativeFirebaseError, UseAddDocMutationValues<AppModelType>, TContext>;
51
+ export declare const useAddDocMutation: <AppModelType extends AppModel = AppModel, TContext = unknown>({ collectionReference, options }: UseAddDocMutationOptions<AppModelType, TContext>) => import("@tanstack/react-query").UseMutationResult<AppModelType, ReactNativeFirebase.NativeFirebaseError, UseAddDocMutationValues<AppModelType>, TContext>;
@@ -33,7 +33,7 @@ export const useAddDocMutation = ({ collectionReference, options = {} }) => {
33
33
  mutationFn: async ({ data }) => {
34
34
  const docRef = await addDoc(collectionReference, data);
35
35
  const docSnap = await getDoc(docRef);
36
- return docSnap.data();
36
+ return { ...docSnap.data(), uid: docRef.id };
37
37
  }
38
38
  });
39
39
  };
@@ -3,6 +3,7 @@ import { FirebaseFirestoreTypes, addDoc, WithFieldValue, getDoc } from "@react-n
3
3
 
4
4
  import { ReactNativeFirebase } from "@react-native-firebase/app";
5
5
  import { useMemo } from "react";
6
+ import { AppModel } from "../../types";
6
7
 
7
8
  /**
8
9
  * @inline
@@ -17,10 +18,7 @@ export type UseAddDocMutationValues<AppModelType> = {
17
18
  /**
18
19
  * @inline
19
20
  */
20
- export type UseAddDocMutationOptions<
21
- AppModelType extends FirebaseFirestoreTypes.DocumentData = FirebaseFirestoreTypes.DocumentData,
22
- TContext = unknown
23
- > = {
21
+ export type UseAddDocMutationOptions<AppModelType extends AppModel = AppModel, TContext = unknown> = {
24
22
  /**
25
23
  * Reference to a collection where document must be added
26
24
  */
@@ -64,10 +62,7 @@ export type UseAddDocMutationOptions<
64
62
  * };
65
63
  * ```
66
64
  */
67
- export const useAddDocMutation = <
68
- AppModelType extends FirebaseFirestoreTypes.DocumentData = FirebaseFirestoreTypes.DocumentData,
69
- TContext = unknown
70
- >({
65
+ export const useAddDocMutation = <AppModelType extends AppModel = AppModel, TContext = unknown>({
71
66
  collectionReference,
72
67
  options = {}
73
68
  }: UseAddDocMutationOptions<AppModelType, TContext>) => {
@@ -79,7 +74,7 @@ export const useAddDocMutation = <
79
74
  mutationFn: async ({ data }) => {
80
75
  const docRef = await addDoc<AppModelType>(collectionReference, data);
81
76
  const docSnap = await getDoc(docRef);
82
- return docSnap.data() as AppModelType;
77
+ return { ...docSnap.data(), uid: docRef.id } as AppModelType;
83
78
  }
84
79
  });
85
80
  };
@@ -34,12 +34,13 @@ export const useGetRealtimeDocData = ({ path, pathSegments, reference, onError }
34
34
  ? onSnapshot(ref, {
35
35
  next: async (snapshot) => {
36
36
  setIsFetching(false);
37
- setDoc(snapshot.data() || null);
37
+ setDoc({ ...snapshot.data(), uid: snapshot.id });
38
38
  setError(null);
39
39
  setIsError(false);
40
40
  },
41
41
  error: (e) => {
42
42
  setIsError(true);
43
+ setDoc(null);
43
44
  setError(e);
44
45
  onError?.(e);
45
46
  }
@@ -78,12 +78,13 @@ export const useGetRealtimeDocData = <AppModelType extends AppModel = AppModel>(
78
78
  ? onSnapshot<AppModelType>(ref, {
79
79
  next: async (snapshot) => {
80
80
  setIsFetching(false);
81
- setDoc(snapshot.data() || null);
81
+ setDoc({ ...snapshot.data(), uid: snapshot.id } as AppModelType);
82
82
  setError(null);
83
83
  setIsError(false);
84
84
  },
85
85
  error: (e) => {
86
86
  setIsError(true);
87
+ setDoc(null);
87
88
  setError(e);
88
89
  onError?.(e);
89
90
  }
@@ -34,7 +34,7 @@ export const useInfiniteQuery = ({ options, collectionReference, queryConstraint
34
34
  const docs = [];
35
35
  if (querySnapshot) {
36
36
  querySnapshot.forEach((doc) => {
37
- docs.push(doc.data());
37
+ docs.push({ ...doc.data(), uid: doc.id });
38
38
  });
39
39
  }
40
40
  return docs;
@@ -105,7 +105,7 @@ export const useInfiniteQuery = <AppModelType extends AppModel = AppModel, TQuer
105
105
 
106
106
  if (querySnapshot) {
107
107
  querySnapshot.forEach((doc) => {
108
- docs.push(doc.data());
108
+ docs.push({ ...doc.data(), uid: doc.id });
109
109
  });
110
110
  }
111
111
  return docs;
@@ -33,7 +33,7 @@ export const useQuery = ({ options, collectionReference, queryConstraints = [],
33
33
  const docs = [];
34
34
  if (querySnapshot) {
35
35
  querySnapshot.forEach((doc) => {
36
- docs.push(doc.data());
36
+ docs.push({ ...doc.data(), uid: doc.id });
37
37
  });
38
38
  }
39
39
  return docs;
@@ -80,7 +80,7 @@ export const useQuery = <AppModelType extends AppModel = AppModel>({
80
80
 
81
81
  if (querySnapshot) {
82
82
  querySnapshot.forEach((doc) => {
83
- docs.push(doc.data());
83
+ docs.push({ ...doc.data(), uid: doc.id });
84
84
  });
85
85
  }
86
86
  return docs;
@@ -13,7 +13,7 @@ import { getDocSnap } from "./getDocSnap";
13
13
  export const getDocData = async ({ db, reference, path, pathSegments }) => {
14
14
  const docSnap = await getDocSnap({ db, reference, path, pathSegments });
15
15
  if (docSnap && docSnap?.exists) {
16
- return docSnap.data();
16
+ return { ...docSnap.data(), uid: docSnap.id };
17
17
  }
18
18
  return null;
19
19
  };
@@ -26,7 +26,7 @@ export const getDocData = async <AppModelType extends AppModel = AppModel>({
26
26
  const docSnap = await getDocSnap<AppModelType>({ db, reference, path, pathSegments });
27
27
 
28
28
  if (docSnap && docSnap?.exists) {
29
- return docSnap.data() as AppModelType;
29
+ return { ...docSnap.data(), uid: docSnap.id } as AppModelType;
30
30
  }
31
31
 
32
32
  return null;
@@ -31,17 +31,29 @@ export const useEnsureDoc = ({ reference, path, pathSegments, defaults, options
31
31
  return useQuery({
32
32
  ...options,
33
33
  queryFn: async () => {
34
- const existingDocSnap = await getDocSnap({ db, path, pathSegments, reference });
35
- if (existingDocSnap?.exists) {
36
- return { ...existingDocSnap.data(), uid: existingDocSnap.id };
34
+ const createDoc = async () => {
35
+ const docRef = getDocRef({ db, reference, path, pathSegments });
36
+ if (!docRef) {
37
+ throw new Error(`Cannot fetch document reference using data: ${reference?.path}, ${path}, ${pathSegments?.join("/")}`);
38
+ }
39
+ await setDoc(docRef, defaults);
40
+ const docSnap = await getDoc(docRef);
41
+ return { ...docSnap.data(), uid: docSnap.id };
42
+ };
43
+ try {
44
+ const existingDocSnap = await getDocSnap({ db, path, pathSegments, reference });
45
+ if (existingDocSnap?.exists) {
46
+ return { ...existingDocSnap.data(), uid: existingDocSnap.id };
47
+ }
48
+ return createDoc();
37
49
  }
38
- const docRef = getDocRef({ db, reference, path, pathSegments });
39
- if (!docRef) {
40
- throw new Error(`Cannot fetch document reference using data: ${reference?.path}, ${path}, ${pathSegments?.join("/")}`);
50
+ catch (e) {
51
+ // permission denied error may arise because of a security rule
52
+ if (e.code === "permission-denied") {
53
+ return createDoc();
54
+ }
55
+ throw e;
41
56
  }
42
- await setDoc(docRef, defaults);
43
- const docSnap = await getDoc(docRef);
44
- return { ...docSnap.data(), uid: docSnap.id };
45
57
  }
46
58
  });
47
59
  };
@@ -1,5 +1,5 @@
1
1
  import { useQuery, UseQueryOptions } from "@tanstack/react-query";
2
- import { getDoc, setDoc } from "firebase/firestore";
2
+ import { FirestoreError, getDoc, setDoc } from "firebase/firestore";
3
3
 
4
4
  import { AppModel } from "../../types";
5
5
  import { GetDocDataOptions } from "./utils/getDocData";
@@ -58,22 +58,35 @@ export const useEnsureDoc = <AppModelType extends AppModel = AppModel>({
58
58
  return useQuery({
59
59
  ...options,
60
60
  queryFn: async () => {
61
- const existingDocSnap = await getDocSnap({ db, path, pathSegments, reference });
61
+ const createDoc = async () => {
62
+ const docRef = getDocRef({ db, reference, path, pathSegments });
63
+ if (!docRef) {
64
+ throw new Error(
65
+ `Cannot fetch document reference using data: ${reference?.path}, ${path}, ${pathSegments?.join("/")}`
66
+ );
67
+ }
62
68
 
63
- if (existingDocSnap?.exists) {
64
- return { ...(existingDocSnap.data() as AppModelType), uid: existingDocSnap.id };
65
- }
69
+ await setDoc<AppModelType, AppModelType>(docRef, defaults);
70
+ const docSnap = await getDoc(docRef);
71
+ return { ...(docSnap.data() as AppModelType), uid: docSnap.id };
72
+ };
66
73
 
67
- const docRef = getDocRef({ db, reference, path, pathSegments });
68
- if (!docRef) {
69
- throw new Error(
70
- `Cannot fetch document reference using data: ${reference?.path}, ${path}, ${pathSegments?.join("/")}`
71
- );
72
- }
74
+ try {
75
+ const existingDocSnap = await getDocSnap({ db, path, pathSegments, reference });
76
+
77
+ if (existingDocSnap?.exists) {
78
+ return { ...(existingDocSnap.data() as AppModelType), uid: existingDocSnap.id };
79
+ }
73
80
 
74
- await setDoc<AppModelType, AppModelType>(docRef, defaults);
75
- const docSnap = await getDoc(docRef);
76
- return { ...(docSnap.data() as AppModelType), uid: docSnap.id };
81
+ return createDoc();
82
+ } catch (e) {
83
+ // permission denied error may arise because of a security rule
84
+ if ((e as FirestoreError).code === "permission-denied") {
85
+ return createDoc();
86
+ }
87
+
88
+ throw e;
89
+ }
77
90
  }
78
91
  });
79
92
  };