@@ -10,14 +10,18 @@ import {
10
10
} from '@nuxt/kit'
11
11
// cannot import from firebase/app because the build fails, maybe a nuxt bug?
12
12
import 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'
14
14
import { markRaw } from 'vue'
15
15
import { consola } from 'consola'
16
16
import {
17
17
VueFireNuxtModuleOptions ,
18
18
VueFireNuxtModuleOptionsResolved ,
19
19
} from './module/options'
20
- import { FirebaseEmulatorsToEnable , detectEmulators } from './module/emulators'
20
+ import {
21
+ FirebaseEmulatorsToEnable ,
22
+ detectEmulators ,
23
+ willUseEmulators ,
24
+ } from './module/emulators'
21
25
22
26
const logger = consola . withTag ( 'nuxt-vuefire module' )
23
27
@@ -47,6 +51,13 @@ export default defineNuxtModule<VueFireNuxtModuleOptions>({
47
51
const runtimeDir = fileURLToPath ( new URL ( './runtime' , import . meta. url ) )
48
52
const templatesDir = fileURLToPath ( new URL ( '../templates' , import . meta. url ) )
49
53
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
+
50
61
// to handle TimeStamp and GeoPoints objects
51
62
addPlugin ( resolve ( runtimeDir , 'payload-plugin' ) )
52
63
@@ -55,6 +66,8 @@ export default defineNuxtModule<VueFireNuxtModuleOptions>({
55
66
nuxt . options . appConfig . firebaseConfig = markRaw ( options . config )
56
67
nuxt . options . appConfig . vuefireOptions = markRaw ( options )
57
68
69
+ nuxt . options . runtimeConfig . vuefire = { options }
70
+
58
71
nuxt . options . build . transpile . push ( runtimeDir )
59
72
nuxt . options . build . transpile . push ( templatesDir )
60
73
@@ -83,24 +96,28 @@ export default defineNuxtModule<VueFireNuxtModuleOptions>({
83
96
// NOTE: the order of the plugins is reversed, so we end by adding the app plugin which is used by all other
84
97
// plugins
85
98
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 ) {
96
103
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
97
105
addPlugin ( resolve ( runtimeDir , 'app-check/plugin.server' ) )
98
106
} else if ( nuxt . options . ssr ) {
99
107
logger . warn (
100
108
'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.'
101
109
)
102
110
}
103
111
}
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
+ }
104
121
105
122
// this adds the VueFire plugin and handle SSR state serialization and hydration
106
123
addPluginTemplate ( {
@@ -112,7 +129,11 @@ export default defineNuxtModule<VueFireNuxtModuleOptions>({
112
129
} ,
113
130
} )
114
131
115
- if ( options . auth && nuxt . options . ssr && hasServiceAccount ) {
132
+ if (
133
+ options . auth &&
134
+ nuxt . options . ssr &&
135
+ ( hasServiceAccount || hasEmulatorsEnabled )
136
+ ) {
116
137
// Add the session handler than mints a cookie for the user
117
138
addServerHandler ( {
118
139
route : '/api/__session' ,
@@ -143,22 +164,9 @@ export default defineNuxtModule<VueFireNuxtModuleOptions>({
143
164
}
144
165
145
166
// 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
150
167
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 )
162
170
163
171
// expose the detected emulators to the plugins
164
172
nuxt . options . runtimeConfig . public . vuefire ??= { }
@@ -189,7 +197,7 @@ export default defineNuxtModule<VueFireNuxtModuleOptions>({
189
197
)
190
198
}
191
199
192
- if ( hasServiceAccount ) {
200
+ if ( hasServiceAccount || hasEmulatorsEnabled ) {
193
201
if ( options . auth ) {
194
202
// decodes user token from cookie if any
195
203
addPlugin ( resolve ( runtimeDir , 'auth/plugin-user-token.server' ) )
@@ -286,7 +294,7 @@ interface VueFireRuntimeConfig {
286
294
* Options passed to the Nuxt VueFire module
287
295
* @internal
288
296
*/
289
- options ?: VueFireNuxtModuleOptionsResolved
297
+ options ?: VueFireNuxtModuleOptions
290
298
}
291
299
}
292
300
0 commit comments