Nuxt3从.env读取Firebase配置时Auth报错的解决求助
问题现象
在Nuxt3项目中,通过nuxt.config.ts的runtimeConfig.public.firebase从前端目录的.env文件读取配置,在firebase-manual.ts插件中用useRuntimeConfig()获取配置。Firestore与Storage在两种配置方式(.env读取/硬编码)下均正常工作,但Firebase Authentication仅在硬编码配置时可用。控制台打印显示两种方式的配置信息一致,却抛出auth/api-key-not-valid错误。
核心原因
Nuxt3处理嵌套的runtimeConfig对象时,可能存在隐式的序列化/反序列化转换,导致Firebase Auth验证所需的apiKey在前端运行时出现格式异常(比如被转为非字符串类型、包含不可见字符)。虽然控制台输出看起来正常,但Firebase Auth对apiKey的格式校验远严格于Firestore和Storage。
解决步骤
1. 修改nuxt.config.ts:拆分Firebase配置项
避免在runtimeConfig.public中直接嵌套firebase对象,改为单独声明每个配置字段:
dotenv.config({ path: path.resolve(__dirname, './.env') }) import * as dotenv from 'dotenv' import { defineNuxtConfig } from 'nuxt/config' import * as path from 'path' console.log('Firebase config in nuxt.config.ts:', { apiKey: process.env.FIREBASE_API_KEY, authDomain: process.env.FIREBASE_AUTH_DOMAIN, // ... 其他配置项 }) export default defineNuxtConfig({ head: { script: [ { src: `https://maps.googleapis.com/maps/api/js?key=${process.env.GOOGLE_MAPS_API_KEY}&callback=initMap`, async: true, defer: true, }, ], }, env: { GOOGLE_MAPS_API_KEY: process.env.GOOGLE_MAPS_API_KEY, }, modules: ['@unocss/nuxt'], css: ['./assets/css/main.css'], build: { postcss: { postcssOptions: { plugins: { 'postcss-import': {}, 'unocss/postcss': {}, autoprefixer: {}, }, }, }, }, runtimeConfig: { public: { googleMapsApiKey: process.env.GOOGLE_MAPS_API_KEY, // 单独声明每个Firebase配置项 firebaseApiKey: process.env.FIREBASE_API_KEY, firebaseAuthDomain: process.env.FIREBASE_AUTH_DOMAIN, firebaseProjectId: process.env.FIREBASE_PROJECT_ID, firebaseStorageBucket: process.env.FIREBASE_STORAGE_BUCKET, firebaseMessagingSenderId: process.env.FIREBASE_MESSAGING_SENDER_ID, firebaseAppId: process.env.FIREBASE_APP_ID, firebaseMeasurementId: process.env.FIREBASE_MEASUREMENT_ID, }, }, plugins: ['~/plugins/firebase-manual.ts'], })
2. 修改firebase-manual.ts:手动组合配置对象
在插件中从runtimeConfig取出单独的配置项,手动组合成Firebase初始化对象:
import { getApps, initializeApp } from 'firebase/app' import { getAuth } from 'firebase/auth' import { getFirestore } from 'firebase/firestore' import { getStorage } from 'firebase/storage' export default defineNuxtPlugin((nuxtApp) => { const config = useRuntimeConfig() // 手动构建Firebase配置对象 const firebaseConfig = { apiKey: config.public.firebaseApiKey, authDomain: config.public.firebaseAuthDomain, projectId: config.public.firebaseProjectId, storageBucket: config.public.firebaseStorageBucket, messagingSenderId: config.public.firebaseMessagingSenderId, appId: config.public.firebaseAppId, measurementId: config.public.firebaseMeasurementId, } // 验证apiKey类型和内容 console.log('API Key Type:', typeof firebaseConfig.apiKey) console.log('Firebase Config:', firebaseConfig) const apps = getApps() const firebaseApp = apps.length === 0 ? initializeApp(firebaseConfig) : apps[0] const auth = getAuth(firebaseApp) const firestore = getFirestore(firebaseApp) const storage = getStorage(firebaseApp) nuxtApp.provide('firebase', { firebaseApp, auth, firestore, storage }) })
3. 额外校验环节
- 检查
.env文件:确保FIREBASE_API_KEY没有多余空格或引号,格式应为FIREBASE_API_KEY=your_actual_api_key(不要加引号) - 重启Nuxt开发服务器:确保环境变量被重新加载
- 确认插件中打印的
apiKey类型为string,且内容与硬编码时完全一致
原理说明
Firestore和Storage对配置的容错性较高,即使配置对象存在隐式转换也能正常初始化;但Firebase Auth的apiKey验证会严格检查字符串的完整性、格式和类型。通过拆分配置项并手动组合,避免了Nuxt对嵌套对象的序列化处理,确保apiKey以原始字符串形式传递给Firebase初始化方法。
内容的提问来源于stack exchange,提问作者Ali Guliyev

