@@ -10,14 +10,18 @@ import {
1010} from '@nuxt/kit'
1111// cannot import from firebase/app because the build fails, maybe a nuxt bug?
1212import type { FirebaseApp , FirebaseOptions } from '@firebase/app-types'
13- import type { AppOptions , App as FirebaseAdminApp } from 'firebase-admin/app'
13+ import type { App as FirebaseAdminApp } from 'firebase-admin/app'
1414import { markRaw } from 'vue'
1515import { consola } from 'consola'
1616import {
1717 VueFireNuxtModuleOptions ,
1818 VueFireNuxtModuleOptionsResolved ,
1919} from './module/options'
20- import { FirebaseEmulatorsToEnable , detectEmulators } from './module/emulators'
20+ import {
21+ FirebaseEmulatorsToEnable ,
22+ detectEmulators ,
23+ willUseEmulators ,
24+ } from './module/emulators'
2125
2226const logger = consola . withTag ( 'nuxt-vuefire module' )
2327
@@ -47,6 +51,13 @@ export default defineNuxtModule<VueFireNuxtModuleOptions>({
4751 const runtimeDir = fileURLToPath ( new URL ( './runtime' , import . meta. url ) )
4852 const templatesDir = fileURLToPath ( new URL ( '../templates' , import . meta. url ) )
4953
54+ // we need this to avoid some warnings about missing credentials and ssr
55+ const hasEmulatorsEnabled = await willUseEmulators (
56+ options ,
57+ resolve ( nuxt . options . rootDir , 'firebase.json' ) ,
58+ logger
59+ )
60+
5061 // to handle TimeStamp and GeoPoints objects
5162 addPlugin ( resolve ( runtimeDir , 'payload-plugin' ) )
5263
@@ -55,6 +66,8 @@ export default defineNuxtModule<VueFireNuxtModuleOptions>({
5566 nuxt . options . appConfig . firebaseConfig = markRaw ( options . config )
5667 nuxt . options . appConfig . vuefireOptions = markRaw ( options )
5768
69+ nuxt . options . runtimeConfig . vuefire = { options }
70+
5871 nuxt . options . build . transpile . push ( runtimeDir )
5972 nuxt . options . build . transpile . push ( templatesDir )
6073
@@ -83,24 +96,28 @@ export default defineNuxtModule<VueFireNuxtModuleOptions>({
8396 // NOTE: the order of the plugins is reversed, so we end by adding the app plugin which is used by all other
8497 // plugins
8598
86- if ( options . auth ) {
87- if ( nuxt . options . ssr && ! hasServiceAccount ) {
88- logger . warn (
89- 'You activated both SSR and auth but you are not providing a service account for the admin SDK. See https://vuefire.vuejs.org/nuxt/getting-started.html#configuring-the-admin-sdk.'
90- )
91- }
92-
93- if ( options . appCheck ) {
94- addPlugin ( resolve ( runtimeDir , 'app-check/plugin.client' ) )
95- // TODO: ensure this is the only necessary check. Maybe we need to check if server
99+ if ( options . appCheck ) {
100+ addPlugin ( resolve ( runtimeDir , 'app-check/plugin.client' ) )
101+ // TODO: ensure this is the only necessary check. Maybe we need to check if server
102+ if ( ! hasEmulatorsEnabled ) {
96103 if ( hasServiceAccount ) {
104+ // this is needed by the api endpoint to properly work if no service account is provided, otherwise, the projectId is within the service account
97105 addPlugin ( resolve ( runtimeDir , 'app-check/plugin.server' ) )
98106 } else if ( nuxt . options . ssr ) {
99107 logger . warn (
100108 'You activated both SSR and app-check but you are not providing a service account for the admin SDK. See https://vuefire.vuejs.org/nuxt/getting-started.html#configuring-the-admin-sdk.'
101109 )
102110 }
103111 }
112+ }
113+
114+ if ( options . auth ) {
115+ // TODO: should be fine if emulators are activated
116+ if ( nuxt . options . ssr && ! hasServiceAccount && ! hasEmulatorsEnabled ) {
117+ logger . warn (
118+ 'You activated both SSR and auth but you are not providing a service account for the admin SDK. See https://vuefire.vuejs.org/nuxt/getting-started.html#configuring-the-admin-sdk.'
119+ )
120+ }
104121
105122 // this adds the VueFire plugin and handle SSR state serialization and hydration
106123 addPluginTemplate ( {
@@ -112,7 +129,11 @@ export default defineNuxtModule<VueFireNuxtModuleOptions>({
112129 } ,
113130 } )
114131
115- if ( options . auth && nuxt . options . ssr && hasServiceAccount ) {
132+ if (
133+ options . auth &&
134+ nuxt . options . ssr &&
135+ ( hasServiceAccount || hasEmulatorsEnabled )
136+ ) {
116137 // Add the session handler than mints a cookie for the user
117138 addServerHandler ( {
118139 route : '/api/__session' ,
@@ -143,22 +164,9 @@ export default defineNuxtModule<VueFireNuxtModuleOptions>({
143164 }
144165
145166 // Emulators must be enabled after the app is initialized but before some APIs like auth.signinWithCustomToken() are called
146- const isEmulatorEnabled =
147- typeof options . emulators === 'object'
148- ? options . emulators . enabled
149- : ! ! options . emulators
150167
151- if (
152- // Disable emulators on production unless the user explicitly enables them
153- ( process . env . NODE_ENV !== 'production' ||
154- process . env . VUEFIRE_EMULATORS ) &&
155- isEmulatorEnabled
156- ) {
157- const emulators = await detectEmulators (
158- options ,
159- resolve ( nuxt . options . rootDir , 'firebase.json' ) ,
160- logger
161- )
168+ if ( hasEmulatorsEnabled ) {
169+ const emulators = detectEmulators ( options , hasEmulatorsEnabled , logger )
162170
163171 // expose the detected emulators to the plugins
164172 nuxt . options . runtimeConfig . public . vuefire ??= { }
@@ -189,7 +197,7 @@ export default defineNuxtModule<VueFireNuxtModuleOptions>({
189197 )
190198 }
191199
192- if ( hasServiceAccount ) {
200+ if ( hasServiceAccount || hasEmulatorsEnabled ) {
193201 if ( options . auth ) {
194202 // decodes user token from cookie if any
195203 addPlugin ( resolve ( runtimeDir , 'auth/plugin-user-token.server' ) )
@@ -286,7 +294,7 @@ interface VueFireRuntimeConfig {
286294 * Options passed to the Nuxt VueFire module
287295 * @internal
288296 */
289- options ?: VueFireNuxtModuleOptionsResolved
297+ options ?: VueFireNuxtModuleOptions
290298 }
291299}
292300
0 commit comments