diff --git a/docs/reference/functions/AuthCheck.md b/docs/reference/functions/AuthCheck.md index 06738074..dfb0e3ea 100644 --- a/docs/reference/functions/AuthCheck.md +++ b/docs/reference/functions/AuthCheck.md @@ -8,7 +8,7 @@ > **AuthCheck**(`__namedParameters`): `ReactElement` -Defined in: [src/auth.tsx:257](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L257) +Defined in: [src/auth.tsx:259](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L259) ## Parameters diff --git a/docs/reference/functions/ClaimsCheck.md b/docs/reference/functions/ClaimsCheck.md index 5138d974..fa5ca95e 100644 --- a/docs/reference/functions/ClaimsCheck.md +++ b/docs/reference/functions/ClaimsCheck.md @@ -8,7 +8,7 @@ > **ClaimsCheck**(`__namedParameters`): `Element` -Defined in: [src/auth.tsx:213](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L213) +Defined in: [src/auth.tsx:215](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L215) ## Parameters diff --git a/docs/reference/functions/StorageImage.md b/docs/reference/functions/StorageImage.md index 24370e02..59c9a60b 100644 --- a/docs/reference/functions/StorageImage.md +++ b/docs/reference/functions/StorageImage.md @@ -8,7 +8,7 @@ > **StorageImage**(`props`): `Element` -Defined in: [src/storage.tsx:78](https://github.com/FirebaseExtended/reactfire/blob/main/src/storage.tsx#L78) +Defined in: [src/storage.tsx:82](https://github.com/FirebaseExtended/reactfire/blob/main/src/storage.tsx#L82) ## Parameters diff --git a/docs/reference/functions/useCallableFunctionResponse.md b/docs/reference/functions/useCallableFunctionResponse.md index ddd4987c..3ea2b8d8 100644 --- a/docs/reference/functions/useCallableFunctionResponse.md +++ b/docs/reference/functions/useCallableFunctionResponse.md @@ -8,7 +8,7 @@ > **useCallableFunctionResponse**\<`RequestData`, `ResponseData`\>(`functionName`, `options?`): [`ObservableStatus`](../interfaces/ObservableStatus.md)\<`ResponseData`\> -Defined in: [src/functions.tsx:13](https://github.com/FirebaseExtended/reactfire/blob/main/src/functions.tsx#L13) +Defined in: [src/functions.tsx:14](https://github.com/FirebaseExtended/reactfire/blob/main/src/functions.tsx#L14) Calls a callable function. diff --git a/docs/reference/functions/useSigninCheck.md b/docs/reference/functions/useSigninCheck.md index 32e3e619..895405bc 100644 --- a/docs/reference/functions/useSigninCheck.md +++ b/docs/reference/functions/useSigninCheck.md @@ -8,7 +8,7 @@ > **useSigninCheck**(`options?`): [`ObservableStatus`](../interfaces/ObservableStatus.md)\<[`SigninCheckResult`](../type-aliases/SigninCheckResult.md)\> -Defined in: [src/auth.tsx:134](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L134) +Defined in: [src/auth.tsx:136](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L136) Subscribe to the signed-in status of a user. diff --git a/docs/reference/functions/useStorageDownloadURL.md b/docs/reference/functions/useStorageDownloadURL.md index 898c4931..ced03bbf 100644 --- a/docs/reference/functions/useStorageDownloadURL.md +++ b/docs/reference/functions/useStorageDownloadURL.md @@ -8,7 +8,7 @@ > **useStorageDownloadURL**\<`T`\>(`ref`, `options?`): [`ObservableStatus`](../interfaces/ObservableStatus.md)\<`string` \| `T`\> -Defined in: [src/storage.tsx:29](https://github.com/FirebaseExtended/reactfire/blob/main/src/storage.tsx#L29) +Defined in: [src/storage.tsx:30](https://github.com/FirebaseExtended/reactfire/blob/main/src/storage.tsx#L30) Subscribe to a storage ref's download URL diff --git a/docs/reference/functions/useStorageTask.md b/docs/reference/functions/useStorageTask.md index ccda3ddf..f6cbc13d 100644 --- a/docs/reference/functions/useStorageTask.md +++ b/docs/reference/functions/useStorageTask.md @@ -8,7 +8,7 @@ > **useStorageTask**\<`T`\>(`task`, `ref`, `options?`): [`ObservableStatus`](../interfaces/ObservableStatus.md)\<`T` \| `UploadTaskSnapshot`\> -Defined in: [src/storage.tsx:16](https://github.com/FirebaseExtended/reactfire/blob/main/src/storage.tsx#L16) +Defined in: [src/storage.tsx:17](https://github.com/FirebaseExtended/reactfire/blob/main/src/storage.tsx#L17) Subscribe to the progress of a storage task diff --git a/docs/reference/interfaces/AuthCheckProps.md b/docs/reference/interfaces/AuthCheckProps.md index 37e7b895..c5edcb62 100644 --- a/docs/reference/interfaces/AuthCheckProps.md +++ b/docs/reference/interfaces/AuthCheckProps.md @@ -6,7 +6,7 @@ # Interface: AuthCheckProps -Defined in: [src/auth.tsx:52](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L52) +Defined in: [src/auth.tsx:54](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L54) ## Properties @@ -14,7 +14,7 @@ Defined in: [src/auth.tsx:52](https://github.com/FirebaseExtended/reactfire/blob > **children**: `ReactNode` -Defined in: [src/auth.tsx:54](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L54) +Defined in: [src/auth.tsx:56](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L56) *** @@ -22,7 +22,7 @@ Defined in: [src/auth.tsx:54](https://github.com/FirebaseExtended/reactfire/blob > **fallback**: `ReactNode` -Defined in: [src/auth.tsx:53](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L53) +Defined in: [src/auth.tsx:55](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L55) *** @@ -30,4 +30,4 @@ Defined in: [src/auth.tsx:53](https://github.com/FirebaseExtended/reactfire/blob > `optional` **requiredClaims?**: `Object` -Defined in: [src/auth.tsx:55](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L55) +Defined in: [src/auth.tsx:57](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L57) diff --git a/docs/reference/interfaces/ClaimCheckErrors.md b/docs/reference/interfaces/ClaimCheckErrors.md index 470ca5ab..ce0afa98 100644 --- a/docs/reference/interfaces/ClaimCheckErrors.md +++ b/docs/reference/interfaces/ClaimCheckErrors.md @@ -6,7 +6,7 @@ # Interface: ClaimCheckErrors -Defined in: [src/auth.tsx:65](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L65) +Defined in: [src/auth.tsx:67](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L67) ## Indexable diff --git a/docs/reference/interfaces/ClaimsCheckProps.md b/docs/reference/interfaces/ClaimsCheckProps.md index 4d39e79b..34375923 100644 --- a/docs/reference/interfaces/ClaimsCheckProps.md +++ b/docs/reference/interfaces/ClaimsCheckProps.md @@ -6,7 +6,7 @@ # Interface: ClaimsCheckProps -Defined in: [src/auth.tsx:58](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L58) +Defined in: [src/auth.tsx:60](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L60) ## Properties @@ -14,7 +14,7 @@ Defined in: [src/auth.tsx:58](https://github.com/FirebaseExtended/reactfire/blob > **children**: `ReactNode` -Defined in: [src/auth.tsx:61](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L61) +Defined in: [src/auth.tsx:63](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L63) *** @@ -22,7 +22,7 @@ Defined in: [src/auth.tsx:61](https://github.com/FirebaseExtended/reactfire/blob > **fallback**: `ReactNode` -Defined in: [src/auth.tsx:60](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L60) +Defined in: [src/auth.tsx:62](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L62) *** @@ -30,7 +30,7 @@ Defined in: [src/auth.tsx:60](https://github.com/FirebaseExtended/reactfire/blob > **requiredClaims**: `object` -Defined in: [src/auth.tsx:62](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L62) +Defined in: [src/auth.tsx:64](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L64) #### Index Signature @@ -42,4 +42,4 @@ Defined in: [src/auth.tsx:62](https://github.com/FirebaseExtended/reactfire/blob > **user**: `User` -Defined in: [src/auth.tsx:59](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L59) +Defined in: [src/auth.tsx:61](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L61) diff --git a/docs/reference/interfaces/ClaimsValidator.md b/docs/reference/interfaces/ClaimsValidator.md index feb558fd..436ddd45 100644 --- a/docs/reference/interfaces/ClaimsValidator.md +++ b/docs/reference/interfaces/ClaimsValidator.md @@ -6,11 +6,11 @@ # Interface: ClaimsValidator() -Defined in: [src/auth.tsx:91](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L91) +Defined in: [src/auth.tsx:93](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L93) > **ClaimsValidator**(`claims`): `object` -Defined in: [src/auth.tsx:92](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L92) +Defined in: [src/auth.tsx:94](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L94) ## Parameters diff --git a/docs/reference/interfaces/SignInCheckOptionsBasic.md b/docs/reference/interfaces/SignInCheckOptionsBasic.md index 6c9f2d66..66967bf8 100644 --- a/docs/reference/interfaces/SignInCheckOptionsBasic.md +++ b/docs/reference/interfaces/SignInCheckOptionsBasic.md @@ -6,7 +6,7 @@ # Interface: SignInCheckOptionsBasic -Defined in: [src/auth.tsx:83](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L83) +Defined in: [src/auth.tsx:85](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L85) ## Extends @@ -23,7 +23,7 @@ Defined in: [src/auth.tsx:83](https://github.com/FirebaseExtended/reactfire/blob > `optional` **forceRefresh?**: `boolean` -Defined in: [src/auth.tsx:84](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L84) +Defined in: [src/auth.tsx:86](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L86) *** diff --git a/docs/reference/interfaces/SignInCheckOptionsClaimsObject.md b/docs/reference/interfaces/SignInCheckOptionsClaimsObject.md index 092cde82..09a1eae0 100644 --- a/docs/reference/interfaces/SignInCheckOptionsClaimsObject.md +++ b/docs/reference/interfaces/SignInCheckOptionsClaimsObject.md @@ -6,7 +6,7 @@ # Interface: SignInCheckOptionsClaimsObject -Defined in: [src/auth.tsx:87](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L87) +Defined in: [src/auth.tsx:89](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L89) ## Extends @@ -18,7 +18,7 @@ Defined in: [src/auth.tsx:87](https://github.com/FirebaseExtended/reactfire/blob > `optional` **forceRefresh?**: `boolean` -Defined in: [src/auth.tsx:84](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L84) +Defined in: [src/auth.tsx:86](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L86) #### Inherited from @@ -54,7 +54,7 @@ Defined in: [src/index.ts:26](https://github.com/FirebaseExtended/reactfire/blob > **requiredClaims**: `ParsedToken` -Defined in: [src/auth.tsx:88](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L88) +Defined in: [src/auth.tsx:90](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L90) *** diff --git a/docs/reference/interfaces/SignInCheckOptionsClaimsValidator.md b/docs/reference/interfaces/SignInCheckOptionsClaimsValidator.md index 83517d7a..5ba7f609 100644 --- a/docs/reference/interfaces/SignInCheckOptionsClaimsValidator.md +++ b/docs/reference/interfaces/SignInCheckOptionsClaimsValidator.md @@ -6,7 +6,7 @@ # Interface: SignInCheckOptionsClaimsValidator -Defined in: [src/auth.tsx:98](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L98) +Defined in: [src/auth.tsx:100](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L100) ## Extends @@ -18,7 +18,7 @@ Defined in: [src/auth.tsx:98](https://github.com/FirebaseExtended/reactfire/blob > `optional` **forceRefresh?**: `boolean` -Defined in: [src/auth.tsx:84](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L84) +Defined in: [src/auth.tsx:86](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L86) #### Inherited from @@ -82,4 +82,4 @@ Defined in: [src/index.ts:31](https://github.com/FirebaseExtended/reactfire/blob > **validateCustomClaims**: [`ClaimsValidator`](ClaimsValidator.md) -Defined in: [src/auth.tsx:99](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L99) +Defined in: [src/auth.tsx:101](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L101) diff --git a/docs/reference/type-aliases/SigninCheckResult.md b/docs/reference/type-aliases/SigninCheckResult.md index bb80be74..f6f71bd1 100644 --- a/docs/reference/type-aliases/SigninCheckResult.md +++ b/docs/reference/type-aliases/SigninCheckResult.md @@ -8,4 +8,4 @@ > **SigninCheckResult** = \{ `errors`: \{ \}; `hasRequiredClaims`: `false`; `signedIn`: `false`; `user`: `null`; \} \| \{ `errors`: [`ClaimCheckErrors`](../interfaces/ClaimCheckErrors.md); `hasRequiredClaims`: `boolean`; `signedIn`: `true`; `user`: `User`; \} -Defined in: [src/auth.tsx:69](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L69) +Defined in: [src/auth.tsx:71](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L71) diff --git a/docs/reference/type-aliases/StorageImageProps.md b/docs/reference/type-aliases/StorageImageProps.md index b75fa337..f4dcf98f 100644 --- a/docs/reference/type-aliases/StorageImageProps.md +++ b/docs/reference/type-aliases/StorageImageProps.md @@ -8,7 +8,7 @@ > **StorageImageProps** = `object` -Defined in: [src/storage.tsx:36](https://github.com/FirebaseExtended/reactfire/blob/main/src/storage.tsx#L36) +Defined in: [src/storage.tsx:40](https://github.com/FirebaseExtended/reactfire/blob/main/src/storage.tsx#L40) ## Properties @@ -16,7 +16,7 @@ Defined in: [src/storage.tsx:36](https://github.com/FirebaseExtended/reactfire/b > `optional` **placeHolder?**: `React.ReactNode` -Defined in: [src/storage.tsx:40](https://github.com/FirebaseExtended/reactfire/blob/main/src/storage.tsx#L40) +Defined in: [src/storage.tsx:44](https://github.com/FirebaseExtended/reactfire/blob/main/src/storage.tsx#L44) *** @@ -24,7 +24,7 @@ Defined in: [src/storage.tsx:40](https://github.com/FirebaseExtended/reactfire/b > `optional` **storage?**: `FirebaseStorage` -Defined in: [src/storage.tsx:38](https://github.com/FirebaseExtended/reactfire/blob/main/src/storage.tsx#L38) +Defined in: [src/storage.tsx:42](https://github.com/FirebaseExtended/reactfire/blob/main/src/storage.tsx#L42) *** @@ -32,7 +32,7 @@ Defined in: [src/storage.tsx:38](https://github.com/FirebaseExtended/reactfire/b > **storagePath**: `string` -Defined in: [src/storage.tsx:37](https://github.com/FirebaseExtended/reactfire/blob/main/src/storage.tsx#L37) +Defined in: [src/storage.tsx:41](https://github.com/FirebaseExtended/reactfire/blob/main/src/storage.tsx#L41) *** @@ -40,4 +40,4 @@ Defined in: [src/storage.tsx:37](https://github.com/FirebaseExtended/reactfire/b > `optional` **suspense?**: `boolean` -Defined in: [src/storage.tsx:39](https://github.com/FirebaseExtended/reactfire/blob/main/src/storage.tsx#L39) +Defined in: [src/storage.tsx:43](https://github.com/FirebaseExtended/reactfire/blob/main/src/storage.tsx#L43) diff --git a/example/package-lock.json b/example/package-lock.json index 5ddc5032..fc2d6796 100644 --- a/example/package-lock.json +++ b/example/package-lock.json @@ -21,7 +21,7 @@ "@vitejs/plugin-react": "^6.0.3", "autoprefixer": "^10.4.8", "babel-preset-env": "^1.7.0", - "postcss": "^8.5.16", + "postcss": "^8.5.23", "tailwindcss": "^3.1.7", "typescript": "^4.7.4", "vite": "^8.1.4" @@ -1850,12 +1850,12 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -2132,9 +2132,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "dependencies": { "to-regex-range": "^5.0.1" @@ -2721,9 +2721,9 @@ "dev": true }, "node_modules/nanoid": { - "version": "3.3.15", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.15.tgz", - "integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==", + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", "funding": [ { "type": "github", @@ -2852,9 +2852,9 @@ } }, "node_modules/postcss": { - "version": "8.5.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.16.tgz", - "integrity": "sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg==", + "version": "8.5.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.23.tgz", + "integrity": "sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==", "dev": true, "funding": [ { @@ -2871,7 +2871,7 @@ } ], "dependencies": { - "nanoid": "^3.3.12", + "nanoid": "^3.3.16", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -3274,9 +3274,9 @@ } }, "node_modules/rollup": { - "version": "2.79.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", - "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "version": "2.80.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.80.0.tgz", + "integrity": "sha512-cIFJOD1DESzpjOBl763Kp1AH7UE/0fcdHe6rZXUdQ9c50uvgigvW97u3IcSeBwOkgqL/PXPBktBCh0KEu5L8XQ==", "peer": true, "bin": { "rollup": "dist/bin/rollup" @@ -5400,12 +5400,12 @@ "dev": true }, "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "requires": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" } }, "browserslist": { @@ -5602,9 +5602,9 @@ } }, "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "requires": { "to-regex-range": "^5.0.1" @@ -5967,9 +5967,9 @@ "dev": true }, "nanoid": { - "version": "3.3.15", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.15.tgz", - "integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==" + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==" }, "node-fetch": { "version": "2.6.7", @@ -6048,12 +6048,12 @@ "dev": true }, "postcss": { - "version": "8.5.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.16.tgz", - "integrity": "sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg==", + "version": "8.5.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.23.tgz", + "integrity": "sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==", "dev": true, "requires": { - "nanoid": "^3.3.12", + "nanoid": "^3.3.16", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } @@ -6333,9 +6333,9 @@ } }, "rollup": { - "version": "2.79.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", - "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "version": "2.80.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.80.0.tgz", + "integrity": "sha512-cIFJOD1DESzpjOBl763Kp1AH7UE/0fcdHe6rZXUdQ9c50uvgigvW97u3IcSeBwOkgqL/PXPBktBCh0KEu5L8XQ==", "peer": true, "requires": { "fsevents": "~2.3.2" diff --git a/example/package.json b/example/package.json index cca74ffa..1270b606 100644 --- a/example/package.json +++ b/example/package.json @@ -23,7 +23,7 @@ "@vitejs/plugin-react": "^6.0.3", "autoprefixer": "^10.4.8", "babel-preset-env": "^1.7.0", - "postcss": "^8.5.16", + "postcss": "^8.5.23", "tailwindcss": "^3.1.7", "typescript": "^4.7.4", "vite": "^8.1.4" diff --git a/functions/package-lock.json b/functions/package-lock.json index 4102f969..e1e84993 100644 --- a/functions/package-lock.json +++ b/functions/package-lock.json @@ -1868,21 +1868,21 @@ } }, "node_modules/jsonwebtoken/node_modules/jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz", + "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==", "dependencies": { - "buffer-equal-constant-time": "1.0.1", + "buffer-equal-constant-time": "^1.0.1", "ecdsa-sig-formatter": "1.0.11", "safe-buffer": "^5.0.1" } }, "node_modules/jsonwebtoken/node_modules/jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.3.tgz", + "integrity": "sha512-byiJ0FLRdLdSVSReO/U4E7RoEyOCKnEnEPMjq3HxWtvzLsV08/i5RQKsFVNkCldrCaPr2vDNAOMsfs8T/Hze7g==", "dependencies": { - "jwa": "^1.4.1", + "jwa": "^1.4.2", "safe-buffer": "^5.0.1" } }, @@ -4221,21 +4221,21 @@ }, "dependencies": { "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz", + "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==", "requires": { - "buffer-equal-constant-time": "1.0.1", + "buffer-equal-constant-time": "^1.0.1", "ecdsa-sig-formatter": "1.0.11", "safe-buffer": "^5.0.1" } }, "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.3.tgz", + "integrity": "sha512-byiJ0FLRdLdSVSReO/U4E7RoEyOCKnEnEPMjq3HxWtvzLsV08/i5RQKsFVNkCldrCaPr2vDNAOMsfs8T/Hze7g==", "requires": { - "jwa": "^1.4.1", + "jwa": "^1.4.2", "safe-buffer": "^5.0.1" } }, diff --git a/package-lock.json b/package-lock.json index 22139bbd..845fbc18 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "reactfire", - "version": "4.2.5", + "version": "4.2.6", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "reactfire", - "version": "4.2.5", + "version": "4.2.6", "license": "MIT", "dependencies": { "rxfire": "^6.1.0", diff --git a/package.json b/package.json index 268c9fba..6b6b707f 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "4.2.5", + "version": "4.2.6", "license": "MIT", "type": "module", "main": "dist/index.umd.cjs", diff --git a/src/auth.tsx b/src/auth.tsx index 1bebf526..9fba1a46 100644 --- a/src/auth.tsx +++ b/src/auth.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { user } from 'rxfire/auth'; import { preloadObservable, ReactFireOptions, useAuth, useObservable, ObservableStatus, ReactFireError } from './'; -import { from, of } from 'rxjs'; +import { from, of, defer } from 'rxjs'; import { map, switchMap } from 'rxjs/operators'; import { useSuspenseEnabledFromConfigAndContext } from './firebaseApp'; @@ -44,7 +44,9 @@ export function useIdTokenResult(user: User, forceRefresh = false, options?: Rea } const observableId = `auth:idTokenResult:${user.uid}:forceRefresh=${forceRefresh}`; - const observable$ = from(user.getIdTokenResult(forceRefresh)); + // Wrap in `defer` so the token fetch runs lazily on subscription rather than + // eagerly on every render. + const observable$ = defer(() => from(user.getIdTokenResult(forceRefresh))); return useObservable(observableId, observable$, options); } diff --git a/src/functions.tsx b/src/functions.tsx index 501822b1..e9f1f34b 100644 --- a/src/functions.tsx +++ b/src/functions.tsx @@ -1,4 +1,5 @@ import { httpsCallable as rxHttpsCallable } from 'rxfire/functions'; +import { defer } from 'rxjs'; import { ReactFireOptions, useObservable, ObservableStatus } from './'; import { useFunctions } from '.'; @@ -20,7 +21,9 @@ export function useCallableFunctionResponse( const functions = useFunctions(); const observableId = `functions:callableResponse:${functionName}:${JSON.stringify(options?.data)}:${JSON.stringify(options?.httpsCallableOptions)}`; const obsFactory = rxHttpsCallable(functions, functionName, options?.httpsCallableOptions); - const observable$ = obsFactory(options?.data); + // Wrap in `defer` so the function is invoked lazily on subscription rather than + // on every render (each render otherwise calls the cloud function and discards it). + const observable$ = defer(() => obsFactory(options?.data)); return useObservable(observableId, observable$, options); } diff --git a/src/storage.tsx b/src/storage.tsx index 5a0299da..92f27a51 100644 --- a/src/storage.tsx +++ b/src/storage.tsx @@ -1,5 +1,6 @@ import * as React from 'react'; import { getDownloadURL, fromTask } from 'rxfire/storage'; +import { defer } from 'rxjs'; import { ReactFireOptions, useObservable, ObservableStatus, useStorage } from './'; import { useSuspenseEnabledFromConfigAndContext } from './firebaseApp'; import { ref } from 'firebase/storage'; @@ -28,7 +29,10 @@ export function useStorageTask(task: UploadTask, ref: StorageRefere */ export function useStorageDownloadURL(ref: StorageReference, options?: ReactFireOptions): ObservableStatus { const observableId = `storage:downloadUrl:${ref.toString()}`; - const observable$ = getDownloadURL(ref); + // Wrap in `defer` so the download URL request is created lazily on subscription + // rather than eagerly on every render (which fires a discarded request each time, + // and an unhandled rejection when the object is missing). + const observable$ = defer(() => getDownloadURL(ref)); return useObservable(observableId, observable$, options); } diff --git a/test/auth.test.tsx b/test/auth.test.tsx index 3a66784f..647ef683 100644 --- a/test/auth.test.tsx +++ b/test/auth.test.tsx @@ -9,6 +9,7 @@ import { AuthProvider, useUser, useSigninCheck, + useIdTokenResult, ClaimCheckErrors, ClaimsValidator, } from '../src/index'; @@ -16,7 +17,7 @@ import { baseConfig } from './appConfig'; import { FirebaseApp, initializeApp } from 'firebase/app'; import { randomString } from './test-utils'; -import { getAuth, GoogleAuthProvider, signInWithCredential, signInWithCustomToken, signOut, connectAuthEmulator, UserCredential } from 'firebase/auth'; +import { getAuth, GoogleAuthProvider, signInWithCredential, signInWithCustomToken, signOut, connectAuthEmulator, UserCredential, User } from 'firebase/auth'; describe('Authentication', () => { let app: FirebaseApp; @@ -388,4 +389,22 @@ describe('Authentication', () => { await findByTestId('signed-out'); }); }); + + describe('useIdTokenResult', () => { + it('defers the token fetch so it does not re-run on every render', async () => { + const getIdTokenResult = vi.fn().mockResolvedValue({ claims: {} }); + const fakeUser = { uid: randomString(), getIdTokenResult } as unknown as User; + + const { result, rerender } = renderHook(() => useIdTokenResult(fakeUser, false)); + + await waitFor(() => expect(result.current.status).toEqual('success')); + + // The request is created lazily inside `defer` and useObservable subscribes + // once, so re-rendering must not trigger additional token fetches. + rerender(); + rerender(); + + expect(getIdTokenResult).toHaveBeenCalledTimes(1); + }); + }); }); diff --git a/test/functions.test.tsx b/test/functions.test.tsx index 10ef5a23..41f4b288 100644 --- a/test/functions.test.tsx +++ b/test/functions.test.tsx @@ -7,6 +7,17 @@ import { renderHook, waitFor } from '@testing-library/react'; import { randomString } from './test-utils'; import * as React from 'react'; +// `functions.tsx` calls `httpsCallable` (via rxfire) to create the callable used inside +// `defer`. Wrapping it in `vi.fn` (calling through to the real implementation by default) +// lets the regression test below count invocations without touching the emulator. +vi.mock('firebase/functions', async (importOriginal) => { + const actual = await importOriginal(); + return { + ...actual, + httpsCallable: vi.fn(actual.httpsCallable), + }; +}); + describe('Functions', () => { const app = initializeApp(baseConfig); const functions = getFunctions(app); @@ -46,5 +57,35 @@ describe('Functions', () => { await waitFor(() => expect(result.current.status).toEqual('success')); expect(result.current.data).toEqual(testText.toUpperCase()); }); + + it('defers the function call so it does not re-invoke on every render', async () => { + const testText = randomString(); + const mockedHttpsCallable = vi.mocked(httpsCallable); + const originalImpl = mockedHttpsCallable.getMockImplementation()! as typeof httpsCallable; + + // Wrap the real callable so we can count invocations of the cloud function + // itself, not just how many times `httpsCallable` is called to create it. + const realCallable = originalImpl<{ text: string }, string>(functions, 'capitalizeText'); + const callSpy = vi.fn((data?: { text: string } | null) => realCallable(data)); + mockedHttpsCallable.mockImplementation(() => callSpy as unknown as ReturnType); + + try { + const { result, rerender } = renderHook( + () => useCallableFunctionResponse<{ text: string }, string>('capitalizeText', { data: { text: testText } }), + { wrapper: Provider } + ); + + await waitFor(() => expect(result.current.status).toEqual('success')); + + // The request is created lazily inside `defer` and useObservable subscribes + // once, so re-rendering must not trigger additional cloud function calls. + rerender(); + rerender(); + + expect(callSpy).toHaveBeenCalledTimes(1); + } finally { + mockedHttpsCallable.mockImplementation(originalImpl); + } + }); }); }); diff --git a/vite.config.ts b/vite.config.ts index 85660256..30d83cb9 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -12,6 +12,12 @@ console.log(`ReactFire v${version}`); const externals = [ 'react', + // Externalize the useSyncExternalStore shim so the consumer's bundler resolves it. + // Bundling this CJS module into the ESM output makes rolldown emit a dynamic require() + // that throws ("dynamic usage of require is not supported") when a reactfire data hook + // loads client-side in a Next.js App Router (strict ESM) context. Externalizing keeps + // the shim's React 16/17 fallback intact while removing the require from our dist. + 'use-sync-external-store/shim', 'firebase', 'firebase/app', 'firebase/firestore',