Seems like @nuxtjs/firebase is not going to support firebase v9 modular syntax, and there might not be support for firebase v10.
So the best way forward is to use Firebase directly without depending on a nuxt plugin.
Install Firebase.
npm install firebase
Edit nuxt.config.js
- load
firebaseClient
on client side only
const config = { plugins: [ { src: '~/plugins/firebaseClient', mode: 'client' }, ]}export default config
Create plugins/firebaseClient.js
- load firebase and analytics by default
- load auth, firestore, etc. dynamically when required
import { initializeApp, getApps } from "firebase/app"import { getAnalytics } from "firebase/analytics";const firebaseConfig = { apiKey: "AIza******", authDomain: "*****.firebaseapp.com", projectId: "*****", storageBucket: "*****.appspot.com", messagingSenderId: "9613*****", appId: "1:9613*****:web:5ec9*****", measurementId: "G-C7*****"}const firebaseApp = initializeApp(firebaseConfig);// only load analytics at productionlet analytics = nullif (process.env.NODE_ENV == 'production') { analytics = getAnalytics(firebaseApp);}export default async ({ app, store }, inject) => { const fireModule = { firestore: { } } const fire = { app, analytics, // dynamic load auth when required async getApp() { return this.app }, async getAuth() { if (!this.auth) { const { getAuth, onAuthStateChanged } = await import("firebase/auth") const firebaseApp = await this.getApp() this.auth = getAuth(firebaseApp) onAuthStateChanged(this.auth, async (authUser) => { const claims = authUser ? (await authUser.getIdTokenResult(true)).claims : null if (authUser) { // I only run app check when user signin await fire.getAppCheck() } // perform your action here // await store.dispatch('onAuthStateChangedAction', { authUser, claims }) }) } return this.auth }, async getFirestore() { if (!this.firestore) { // switch to firebase/firestore/lite if onSnapshot is not used for the entire application const { getFirestore, doc, collection, getDoc, Timestamp, GeoPoint, deleteField } = await import("firebase/firestore") // simulate similar syntax with @nuxtjs/firebase fireModule.firestore.Timestamp = Timestamp fireModule.firestore.GeoPoint = GeoPoint fireModule.firestore.FieldValue = { delete: deleteField } const firebaseApp = await this.getApp() const db = getFirestore(firebaseApp, {}) db.getItem = async (collectionName, docId) => { const docSnap = await getDoc(doc(collection(db, collectionName), docId)) if (docSnap.exists()) { const item = docSnap.data() item.id = docSnap.id return item } } this.firestore = db } return this.firestore }, async getFunctions() { if (!this.functions) { const { getFunctions } = await import('firebase/functions') const firebaseApp = await this.getApp() this.functions = getFunctions(firebaseApp) } return this.functions }, async getAppCheck() { if (!this.appCheck) { const { initializeAppCheck, ReCaptchaV3Provider } = await import("firebase/app-check"); const firebaseApp = await this.getApp() this.appCheck = initializeAppCheck(firebaseApp, { // site key provider: new ReCaptchaV3Provider('6Lel******'), // Optional argument. If true, the SDK automatically refreshes App Check // tokens as needed. isTokenAutoRefreshEnabled: true }); } return this.appCheck }, } // simulate similar syntax with @nuxtjs/firebase inject('fire', fire) inject('fireModule', fireModule)}
Usage in page or component.
<script>import { collection, doc, query, where, limit, getDocs, setDoc } from "firebase/firestore";export default { props: ['id'], async mounted() { const id = this.id // since we are loading dynamically, await this.firestore() syntax is required const db = await this.$fire.getFirestore() // else, you could preload/assign fire.firestore in plugins/firebaseClient.js // const db = this.$fire.firestore // load single document using helper function const place = await db.getItem('place', id) // query const snapshot = await getDocs(query(collection(db, 'place'), where('parent_ids', 'array-contains', id), where('active', '==', true), limit(9))) const places = await snapshot.docs.map(doc => { const item = doc.data() item.id = doc.id return item }) // update with merge let ref = doc(collection(db, 'place'), id) const data = { modified: this.$fireModule.firestore.Timestamp.now(), } await setDoc(ref, data, { merge: true }) }}</script>
NOTE: You can load firebase and analytics dynamically as well.
NOTE: JavaScript Dynamic Import with Tree Shaking (via async).
References: