### Install project dependencies Source: https://github.com/vuejs/vuefire/blob/main/playground/README.md Run this command to install all required project dependencies. ```sh pnpm install ``` -------------------------------- ### Start development server Source: https://github.com/vuejs/vuefire/blob/main/playground/README.md Launches the development server with hot-reload capabilities. ```sh pnpm dev ``` -------------------------------- ### Install VueFire and Firebase Source: https://github.com/vuejs/vuefire/blob/main/docs/guide/getting-started.md Commands to install the required dependencies using different package managers. ```sh pnpm i vuefire firebase ``` ```sh yarn add vuefire firebase ``` ```sh npm i vuefire firebase ``` -------------------------------- ### Initialize Firebase and Database Reference Source: https://github.com/vuejs/vuefire/blob/main/examples/vue-2/rtdb.html Initializes the Firebase app and gets a reference to the 'todos' node in the Realtime Database. This setup is common for both API approaches. ```javascript let db = firebase.initializeApp({ databaseURL: 'https://vuefiredemo.firebaseio.com', }).database() let todosRef = db.ref('todos') ``` -------------------------------- ### Initialize Firebase App References Source: https://github.com/vuejs/vuefire/blob/main/docs/guide/getting-started.md Setup Firebase app and export database or firestore references. ```js import { initializeApp } from 'firebase/app' import { getDatabase, ref as dbRef } from 'firebase/database' // ... other firebase imports export const firebaseApp = initializeApp({ // your application settings }) // used for the databas refs const db = getDatabase(firebaseApp) // here we can export reusable database references export const todosRef = dbRef(db, 'todos') ``` ```js import { initializeApp } from 'firebase/app' import { getFirestore, collection } from 'firebase/firestore' // ... other firebase imports export const firebaseApp = initializeApp({ // your application settings }) // used for the firestore refs const db = getFirestore(firebaseApp) // here we can export reusable database references export const todosRef = collection(db, 'todos') ``` -------------------------------- ### Install VueFire and Firebase Source: https://github.com/vuejs/vuefire/blob/main/README.md Install VueFire and the Firebase package using npm. Ensure you have Vue version 2.7 or higher. ```bash npm install vuefire firebase ``` -------------------------------- ### Sync RTDB Collection Manually Source: https://github.com/vuejs/vuefire/blob/main/docs/guide/index.md This example demonstrates the manual setup required to keep a local array in sync with a Firebase Realtime Database collection without using VueFire. It involves setting up listeners for child added, removed, and changed events, and manually managing array mutations. Unsubscribing from listeners requires saving and calling off for each one. ```js import { initializeApp } from 'firebase/app' import { getDatabase } from 'firebase/database' import { createApp } from 'vue' const firebase = initializeApp({ databaseURL: 'https://MY-DATABASE.firebaseio.com' }) const db = getDatabase(firebase) createApp({ // setup the reactive todos property data: () => ({ todos: [] }), created() { const todosRef = db.ref('todos') // setup adding childs and save the callback to remove it later this.todosRef.on( 'child_added', (snapshot, previousKey) => { this.todos.splice( // this function is omitted for simplicity reasons // it would find the position the new element should // be inserted at findIndexByKey(this.todos, previousKey) + 1, 0, // get the actual value snapshot.val() ) }, // we are omitting this function for simplicity reasons onErrorHandler ) // do the same for items being removed this.todosRef.on( 'child_removed', snapshot => { // remove the child from the array this.todos.splice(findIndexByKey(this.todos, snapshot.key), 1) }, onErrorHandler ) // do the same for items being modified this.todosRef.on( 'child_changed', snapshot => { // replace the child with the new value this.todos.splice( findIndexByKey(this.todos, snapshot.key), 1, snapshot.val() ) }, onErrorHandler ) // and last but not least handle elements being moved // this is useful when ordering items this.todosRef.on( 'child_moved', (snapshot, previousKey) => { // retrieve the item being moved const record = this.todos.splice( findIndexByKey(this.todos, snapshot.key), 1 )[0] // add it to the place it should be this.todos.splice( findIndexByKey(this.todos, previousKey) + 1, 0, // we could also use snapshot.val() record ) }, onErrorHandler ) }, }) ``` -------------------------------- ### Prepare and Run Nuxt Module Development Source: https://github.com/vuejs/vuefire/blob/main/packages/nuxt/README.md Use these commands to generate type stubs and start the playground in development mode. ```bash npm run dev:prepare ``` ```bash npm run dev ``` -------------------------------- ### Setup VueFire for Vue 2 Source: https://github.com/vuejs/vuefire/blob/main/docs/guide/getting-started.md Initialize VueFire using vue-demi for compatibility with Vue 2.7. ```ts import { createApp } from 'vue-demi' import { VueFire } from 'vuefire' import App from './App.vue' // the file we created above with `database`, `firestore` and other exports import { firebaseApp } from './firebase' const app = createApp(App) app.use(VueFire, { firebaseApp }) app.mount('#app') ``` -------------------------------- ### Replace a document using set Source: https://github.com/vuejs/vuefire/blob/main/docs/guide/old_writing-data.md Replaces an entire document. The RTDB example uses .key while the Firestore example uses id. ```js // we first create a copy that excludes `.key` // this exclusion is automatic because `.key` is non-enumerable const user = { ...this.user } user.lastName = newLastName db.ref('users/' + this.user['.key']) .set(user) .then(() => { console.log('user updated!') }) // we can also use `$firebaseRefs.user` to refer to the bound user reference this.$firebaseRefs.user.set(user) ``` ```js // we first create a copy that excludes `id` // this exclusion is automatic because `id` is non-enumerable const user = { ...this.user } user.lastName = newLastName db.collection('users') .doc(this.user.id) .set(user) .then(() => { console.log('user updated!') }) // we can also use `$firestoreRefs.user` to refer to the bound user reference this.$firestoreRefs.user.set(user) ``` -------------------------------- ### Install VueFire in Nuxt Source: https://github.com/vuejs/vuefire/blob/main/docs/nuxt/getting-started.md Use these commands to add the Firebase and VueFire dependencies to your project. ```bash npm install firebase npx nuxi@latest module add vuefire ``` -------------------------------- ### Nuxt Module Installation for Vuefire Source: https://context7.com/vuejs/vuefire/llms.txt Install the necessary packages for Vuefire in a Nuxt application using npm. This includes the core Firebase SDK and the Nuxt module itself. For Server-Side Rendering (SSR) support, additional packages like firebase-admin are required. ```bash npm install firebase npx nuxi@latest module add vuefire # For SSR, also install: npm install firebase-admin firebase-functions @firebase/app-types ``` -------------------------------- ### Use useCollection in Pinia Setup Store Source: https://github.com/vuejs/vuefire/blob/main/docs/cookbook/subscriptions-external.md Integrate `useCollection` directly within Pinia setup stores to manage Firebase collections. Remember to follow the Firebase API for data updates and handle server-side rendering data loading. ```typescript import { defineStore } from 'pinia' export const useTodoStore = defineStore('todos', () => { const todos = useCollection(todoListRef) return { todos } }) ``` -------------------------------- ### Configure Options API support Source: https://github.com/vuejs/vuefire/blob/main/docs/guide/getting-started.md Install the required VueFire modules during app initialization to enable Options API support for Firebase services. ```js import { createApp } from 'vue' import { VueFire, VueFireDatabaseOptionsAPI } from 'vuefire' const app = createApp(App) app.use(VueFire, { // ... modules: [ // Add any modules you want to use here VueFireDatabaseOptionsAPI(), ], }) ``` ```js import { createApp } from 'vue' import { VueFire, VueFireFirestoreOptionsAPI } from 'vuefire' const app = createApp(App) app.use(VueFire, { // ... modules: [ // Add any modules you want to use here VueFireFirestoreOptionsAPI(), ], }) ``` -------------------------------- ### Install SSR Dependencies Source: https://github.com/vuejs/vuefire/blob/main/docs/nuxt/getting-started.md Required peer dependencies when using Server-Side Rendering with Firebase Admin. ```sh pnpm install firebase-admin firebase-functions @firebase/app-types ``` ```sh yarn add firebase-admin firebase-functions @firebase/app-types ``` ```sh npm install firebase-admin firebase-functions @firebase/app-types ``` -------------------------------- ### Renamed Import for Vuefire Plugin Source: https://github.com/vuejs/vuefire/blob/main/docs/guide/upgrading-from-v1.md In module environments, explicit installation is required. The plugin is now imported as `databasePlugin` and aliased to `VueFire`. ```diff import Vue from 'vue' - import VueFire from 'vuefire' + import { databasePlugin as VueFire } from 'vuefire' // explicit installation required in module environments Vue.use(VueFire) ``` -------------------------------- ### Install VueFireAppCheck module Source: https://github.com/vuejs/vuefire/blob/main/docs/guide/app-check.md Register the VueFireAppCheck module within the VueFire plugin configuration. ```ts import { VueFire, VueFireAppCheck } from 'vuefire' app.use(VueFire, { firebaseApp: createFirebaseApp(), modules: [ // ... other modules VueFireAppCheck({ // app check options }), ], }) ``` -------------------------------- ### Handle Pending Promises with Suspense Source: https://github.com/vuejs/vuefire/blob/main/docs/guide/ssr.md Alternatively, use `` to enable `await` within the `setup()` function, allowing you to directly await `usePendingPromises()` for server-side data loading. ```vue ``` -------------------------------- ### Register VueFire Options API Modules Source: https://github.com/vuejs/vuefire/blob/main/docs/guide/options-api-realtime-data.md Install the necessary modules in the Vue app instance to enable the firebase and firestore options. ```ts import { VueFireFirestoreOptionsAPI, VueFireDatabaseOptionsAPI } from 'vuefire' app.use(VueFire, { modules: [ // to use the `firestore` option VueFireFirestoreOptionsAPI(), // to use the `firebase` option VueFireDatabaseOptionsAPI(), ] }) ``` ```ts app.use(VueFire, { modules: [ VueFireFirestoreOptionsAPI({ // this would be the same behavior as VueFire v2 reset: true, wait: false, }), VueFireDatabaseOptionsAPI({ // this would be the same behavior as VueFire v2 reset: true, wait: false, }), ] }) ``` -------------------------------- ### Define Vue Router Data Loader with useCollection Source: https://github.com/vuejs/vuefire/blob/main/docs/guide/ssr.md Define a data loader for Vue Router using `defineLoader` to fetch data once on the server. This example uses `useCollection` and awaits its promise before returning the data. ```vue ``` -------------------------------- ### Accessing Firebase Services with Composables Source: https://github.com/vuejs/vuefire/blob/main/docs/guide/other-firebase-services.md Use these composables within setup functions or injectable contexts to access Firebase services. ```vue ``` -------------------------------- ### Sync Firestore Collection Manually Source: https://github.com/vuejs/vuefire/blob/main/docs/guide/index.md This example shows the manual approach to synchronize a local array with a Cloud Firestore collection. It uses `onSnapshot` to listen for changes and processes document changes (added, modified, removed) to update the local array. Handling Firestore references and their listeners adds significant complexity. ```js import { initializeApp } from 'firebase/app' import { getFirestore } from 'firebase/firestore' import { createApp } from 'vue' const firebase = initializeApp({ projectId: 'MY PROJECT ID' }) const db = getFirestore(firebase) createApp({ // setup the reactive todos property data: () => ({ todos: [] }), created() { // unsubscribe can be called to stop listening for changes const unsubscribe = db.collection('todos').onSnapshot(ref => { ref.docChanges().forEach(change => { const { newIndex, oldIndex, doc, type } = change if (type === 'added') { this.todos.splice(newIndex, 0, doc.data()) // if we want to handle references we would do it here } else if (type === 'modified') { // remove the old one first this.todos.splice(oldIndex, 1) // if we want to handle references we would have to unsubscribe // from old references' listeners and subscribe to the new ones this.todos.splice(newIndex, 0, doc.data()) } else if (type === 'removed') { this.todos.splice(oldIndex, 1) // if we want to handle references we need to unsubscribe // from old references } }) }, onErrorHandler) }, }) ``` -------------------------------- ### Define Auth Providers Source: https://github.com/vuejs/vuefire/blob/main/docs/guide/auth.md Export auth providers in a standard script block to ensure they are available for use within component setup scripts. ```vue ``` -------------------------------- ### Initialize Firestore and References Source: https://github.com/vuejs/vuefire/blob/main/examples/firestore.html Sets up the Firebase Firestore instance and defines collection/document references for the Todo app. Enables persistence for offline support. ```javascript let db = firebase .initializeApp({projectId: 'vue-fire-store', databaseURL: 'https://vue-fire-store.firebaseio.com', }) .firestore() firebase.firestore().enablePersistence() let todosRef = db.collection('todos') let unFinishedTodos = todosRef.where('finished', '==', false) let finishedTodos = todosRef.where('finished', '==', true) let configRef = db.collection('configs').doc('jORwjIykFo2NmkdzTkhU') ``` -------------------------------- ### Initialize Firestore and Define API Implementations Source: https://github.com/vuejs/vuefire/blob/main/examples/vue-2/firestore.html Sets up the Firebase application, enables persistence, and defines both Options API and Composition API structures for managing Todo data. ```javascript let db = firebase .initializeApp({ projectId: 'vue-fire-store', databaseURL: 'https://vue-fire-store.firebaseio.com', }) .firestore() firebase.firestore().enablePersistence() let todosRef = db.collection('todos') let unFinishedTodos = todosRef.where('finished', '==', false) let finishedTodos = todosRef.where('finished', '==', true) let configRef = db.collection('configs').doc('jORwjIykFo2NmkdzTkhU') const OptionAPI = { data: () => ({ todos: [], tweets: [], moments: [], nested: [], config: null, newTodoText: '', }), firestore: { todos: unFinishedTodos, moments: db.collection('moments'), nested: db.collection('nested'), tweets: db.collection('tweets'), config: configRef, }, beforeCreate() { console.log('Using Options API version') }, methods: { addTodo: function () { if (this.newTodoText) { todosRef.add({ finished: false, text: this.newTodoText, created: firebase.firestore.FieldValue.serverTimestamp(), }) this.newTodoText = '' } }, updateTodoText: function (todo, newText) { todosRef.doc(todo.id).update({ text: newText }) }, removeTodo: function (todo) { todosRef.doc(todo.id).delete() }, toggleTodos: function () { console.log(this.$firestoreRefs.todos === unFinishedTodos) this.$bind( 'todos', this.$firestoreRefs.todos === unFinishedTodos ? finishedTodos : unFinishedTodos ) }, }, } const CompositionAPI = { setup() { console.log('Using Composition API version') const todos = VueDemi.ref([]) const tweets = VueDemi.ref([]) const moments = VueDemi.ref([]) const nested = VueDemi.ref([]) const config = VueDemi.ref(null) const newTodoText = VueDemi.ref('') let currentRef = unFinishedTodos function addTodo() { if (newTodoText.value) { todosRef.add({ finished: false, text: newTodoText.value, created: firebase.firestore.FieldValue.serverTimestamp(), }) newTodoText.value = '' } } function updateTodoText(todo, newText) { todosRef.doc(todo.id).update({ text: newText }) } function removeTodo(todo) { todosRef.doc(todo.id).delete() } function toggleTodos() { currentRef = currentRef === unFinishedTodos ? finishedTodos : unFinishedTodos Vuefire.firestoreBind(todos, currentRef) } Vuefire.firestoreBind(todos, currentRef) Vuefire.firestoreBind(moments, db.collection('moments')) Vuefire.firestoreBind(nested, db.collection('nested')) Vuefire.firestoreBind(tweets, db.collection('tweets')) Vuefire.firestoreBind(config, configRef) return { todos, tweets, moments, nested, config, newTodoText, addTodo, removeTodo, updateTodoText, toggleTodos, } }, } let params = new URLSearchParams(location.search) Vue.use(Vuefire.firestorePlugin, { wait: true }) let vm = VueDemi.createApp( params.get('composition') != null ? CompositionAPI : OptionAPI ).mount('#app') ``` -------------------------------- ### Initialize Firebase and Define Todo Logic Source: https://github.com/vuejs/vuefire/blob/main/examples/rtdb.html Sets up the Firebase database reference and defines the component logic for managing todos using both Options and Composition APIs. ```javascript let db = firebase .initializeApp({ databaseURL: 'https://vuefiredemo.firebaseio.com', }) .database() let todosRef = db.ref('todos') const OptionsAPI = { data: () => ({ newTodoText: '', todos: [], }), firebase: { todos: todosRef.limitToLast(25), }, methods: { addTodo: function () { if (this.newTodoText) { todosRef.push({ text: this.newTodoText, }) this.newTodoText = '' } }, updateTodoText: function (todo, newText) { todosRef.child(todo['.key']).child('text').set(newText) }, removeTodo: function (todo) { todosRef.child(todo['.key']).remove() }, }, } const CompositionAPI = { setup() { const newTodoText = Vue.ref('') const todos = Vue.ref([]) Vuefire.rtdbBind(todos, todosRef.limitToLast(25)) function addTodo() { if (newTodoText.value) { todosRef.push({ text: newTodoText.value, }) newTodoText.value = '' } } function updateTodoText(todo, newText) { todosRef.child(todo['.key']).child('text').set(newText) } function removeTodo(todo) { todosRef.child(todo['.key']).remove() } return { newTodoText, todos, addTodo, updateTodoText, removeTodo } }, } let vm = Vue.createApp( params.get('composition') != null ? CompositionAPI : OptionAPI ) .use(Vuefire.rtdbPlugin, { wait: true }) .mount('#app') ``` -------------------------------- ### Build for production Source: https://github.com/vuejs/vuefire/blob/main/playground/README.md Performs type-checking, compilation, and minification for production deployment. ```sh pnpm build ``` -------------------------------- ### Handle Primitive Values in Realtime Database Source: https://github.com/vuejs/vuefire/blob/main/docs/guide/realtime-data.md Shows how to push primitive values to Realtime Database and how `useDatabaseList` returns them as objects with `$value` and `id` properties for key tracking. ```js import { ref as databaseRef, push } from 'firebase/database' const numbersRef = databaseRef(db, 'numbers') // add some numbers push(numbersRef, 24) push(numbersRef, 7) push(numbersRef, 10) const numberList = useDatabaseList(numbersRef) // [{ $value: 24, id: '...' }, { $value: 7, id: '...' }, { $value: 10, id: '...' }] // note the order might be different ``` -------------------------------- ### Vue App Initialization Source: https://github.com/vuejs/vuefire/blob/main/examples/firestore.html Creates and mounts the Vue application, conditionally selecting between the Options API and Composition API based on URL parameters. It also configures Vuefire with persistence enabled. ```javascript let params = new URLSearchParams(location.search) let vm = Vue.createApp( params.get('composition') != null ? CompositionAPI : OptionAPI ) .use(Vuefire.firestorePlugin, { wait: true }) .mount('#app') ``` -------------------------------- ### Configure Admin SDK Credentials Source: https://github.com/vuejs/vuefire/blob/main/docs/nuxt/environment-variables.md Set the path to the service account JSON file for SSR development. ```text GOOGLE_APPLICATION_CREDENTIALS=service-account.json ``` -------------------------------- ### Configure Firebase App Check Source: https://context7.com/vuejs/vuefire/llms.txt Integrates App Check with reCAPTCHA V3 provider in the Vue application setup. ```typescript // main.ts import { createApp } from 'vue' import { VueFire, VueFireAppCheck } from 'vuefire' import { ReCaptchaV3Provider } from 'firebase/app-check' import { initializeApp } from 'firebase/app' const firebaseApp = initializeApp({ /* config */ }) const app = createApp(App) app.use(VueFire, { firebaseApp, modules: [ VueFireAppCheck({ provider: new ReCaptchaV3Provider('your-recaptcha-v3-site-key'), isTokenAutoRefreshEnabled: true, // Use debug token in development (add to Firebase Console) debug: process.env.NODE_ENV !== 'production', }), ], }) ``` -------------------------------- ### Vue App Initialization with URL Parameter Source: https://github.com/vuejs/vuefire/blob/main/examples/vue-2/rtdb.html Initializes the Vue application, dynamically choosing between Composition API and Options API based on a URL parameter. It also configures Vuefire with `wait: true`. ```javascript let params = new URLSearchParams(location.search) Vue.use(Vuefire.rtdbPlugin, { wait: true }) let vm = VueDemi.createApp( params.get('composition') != null ? CompositionAPI : OptionAPI ).mount('#app') ``` -------------------------------- ### Configure Admin SDK Credentials via JSON Content Source: https://github.com/vuejs/vuefire/blob/main/docs/nuxt/environment-variables.md Provide the service account file content directly as a single-line string for non-Firebase/Google Cloud deployments. ```text GOOGLE_APPLICATION_CREDENTIALS='{"type":"service_account","project_id":"...","private_key_id":"...","private_key":"-----BEGIN PRIVATE KEY-----\n[redacted]\n-----END PRIVATE KEY-----\n"}' ``` -------------------------------- ### Using Reactive Sources with VueFire Composables Source: https://github.com/vuejs/vuefire/blob/main/docs/guide/realtime-data.md Demonstrates different ways to provide reactive data sources to `useDocument`. `shallowRef` can offer better performance than `ref` for refs. A getter function is the lightest option. ```ts const asRef = shallowRef(dbRef(db, 'contacts/' + route.params.id)) useDocument(asRef) const asComputed = computed(() => dbRef(db, 'contacts/' + route.params.id)) useDocument(asComputed) // a getter is the lightest option useDocument(() => dbRef(db, 'contacts/' + route.params.id)) ``` -------------------------------- ### Connect VueFire to Vuex in components Source: https://github.com/vuejs/vuefire/blob/main/docs/cookbook/vuex.md Use toRef to bind a Vuex state property to a VueFire document subscription within a component setup. ```ts import { doc } from 'firebase/firestore' import { toRef } from 'vue' import { useStore } from 'vuex' import { useDocument } from 'vuefire' const store = useStore() const userDataRef = doc(firestore, 'users', userId) const user = toRef(store.state, 'user') useDocument(userDataRef, { target: user }) ``` -------------------------------- ### Initializing Firebase Services Source: https://github.com/vuejs/vuefire/blob/main/docs/guide/other-firebase-services.md Perform service initialization alongside the main Firebase App configuration. ```ts import { initializeApp } from 'firebase/app' import { initializeAnalytics } from 'firebase/analytics' export const firebaseApp = initializeApp({ // config }) initializeAnalytics(firebaseApp) ``` -------------------------------- ### Deploy Static Site with Firebase CLI Source: https://github.com/vuejs/vuefire/blob/main/docs/nuxt/deployment.md Deploy your generated static Nuxt application to Firebase Hosting using the Firebase CLI. ```sh firebase deploy ``` -------------------------------- ### Run VueFire composables in a detached scope Source: https://github.com/vuejs/vuefire/blob/main/docs/cookbook/vuex.md Execute VueFire composables within the detached effect scope to allow subscription management outside of setup(). ```ts scope.run(() => { useDocument(userDataRef, { target: user }) }) ``` -------------------------------- ### VueFire SSR Module for Vitesse Source: https://github.com/vuejs/vuefire/blob/main/docs/guide/ssr.md Configure the VueFire SSR module for the Vitesse template. This setup initializes Firebase and handles state hydration on both client and server. ```typescript // src/modules/vuefire.ts import { initializeApp } from 'firebase/app' import { VueFire useSSRInitialState } from 'vuefire' import type { UserModule } from '~/types' export const install: UserModule = ({ isClient, initialState, app }) => { const firebaseApp = initializeApp({ // your config }) app.use(VueFire, { firebaseApp }) if (isClient) { // reuse the initial state on the client useSSRInitialState(initialState.vuefire, firebaseApp) } else { // on the server we ensure all the data is retrieved in this object initialState.vuefire = useSSRInitialState( // let `useSSRInitialState` create the initial object for us undefined, // this is necessary to work with concurrent requests firebaseApp, ) } } ``` -------------------------------- ### Initialize VueFire Auth with Custom Dependencies Source: https://github.com/vuejs/vuefire/blob/main/docs/guide/auth.md Use VueFireAuthWithDependencies to manually configure Auth dependencies, such as persistence and error maps, for non-browser environments. ```ts import { VueFire, VueFireAuthWithDependencies } from 'vuefire' import { browserLocalPersistence, debugErrorMap, indexedDBLocalPersistence, prodErrorMap, } from 'firebase/auth' app.use(VueFire, { firebaseApp: createFirebaseApp(), modules: [ // ... other modules VueFireAuthWithDependencies({ dependencies: { errorMap: process.env.NODE_ENV !== 'production' ? debugErrorMap : prodErrorMap, persistence: [ indexedDBLocalPersistence, browserLocalPersistence, ] } }), ], }) ``` -------------------------------- ### Generate Nuxt App for Static Deployment Source: https://github.com/vuejs/vuefire/blob/main/docs/nuxt/deployment.md Use this command to generate your Nuxt application for static site deployment. Ensure SSR is enabled in `nuxt.config.ts`. ```sh nuxt generate ``` -------------------------------- ### Programmatic Realtime Database Binding Source: https://github.com/vuejs/vuefire/blob/main/docs/guide/options-api-realtime-data.md Use $databaseBind to bind a data property to a Firebase Realtime Database reference. This is useful when the reference needs to change dynamically, for example, based on component props. No manual unbinding is required. ```javascript // UserProfile.vue const users = dbRef(db, 'users') export default { props: ['id'], data() { return { user: null, } }, watch: { id: { // call it upon creation too immediate: true, handler(id) { this.$databaseBind('user', dbRef(users, id)) }, }, }, } ``` -------------------------------- ### Bind RTDB Collection with VueFire Source: https://github.com/vuejs/vuefire/blob/main/docs/guide/index.md This example demonstrates how to bind a Firebase Realtime Database collection to a Vue.js application using VueFire's `useDatabaseList` composable. It simplifies real-time synchronization by directly integrating with Vue's reactivity system. ```js import { initializeApp } from 'firebase/app' import { getDatabase, ref as dbRef } from 'firebase/firebase' import { createApp } from 'vue' import { useDatabaseList } from 'vuefire' const firebase = initializeApp({ databaseURL: 'https://MY-DATABASE.firebaseio.com' }) const db = getDatabase(firebase) createApp({ // setup the reactive todos property setup() { ``` -------------------------------- ### Configure Default Reset and Wait Settings Source: https://github.com/vuejs/vuefire/blob/main/docs/cookbook/migration-v2-v3.md Adjust global `reset` and `wait` settings for `VueFireFirestoreOptionsAPI` and `VueFireDatabaseOptionsAPI` to mimic the behavior of VueFire v2. ```ts app.use(VueFire, { modules: [ VueFireFirestoreOptionsAPI({ // same behavior as vuefire v2 reset: true, wait: false, }), VueFireDatabaseOptionsAPI({ // same behavior as vuefire v2 reset: true, wait: false, }), ] }) ``` -------------------------------- ### Auto-imported Composables in Nuxt with Vuefire Source: https://context7.com/vuejs/vuefire/llms.txt In Nuxt, Vuefire composables like `useFirestore`, `useCurrentUser`, and `useCollection` are auto-imported, eliminating the need for explicit imports. This example shows how to use these composables to access Firestore data and the current user within a Vue component. ```vue // pages/todos.vue - Auto-imported composables // No imports needed - composables are auto-imported by Nuxt const db = useFirestore() const user = useCurrentUser() const todos = useCollection(collection(db, 'todos')) ``` -------------------------------- ### Activate Debugging Utilities Source: https://github.com/vuejs/vuefire/blob/main/docs/nuxt/environment-variables.md Enable AppCheck debug mode and Firebase emulators during local builds or commands. ```bash VUEFIRE_APPCHECK_DEBUG=true VUEFIRE_EMULATORS=true pnpm run build ``` -------------------------------- ### Configure nuxt.config.js Source: https://github.com/vuejs/vuefire/blob/main/docs/nuxt/getting-started.md Register the module and provide your Firebase project credentials. ```ts export default defineNuxtConfig({ modules: [ // ... other modules 'nuxt-vuefire', ], vuefire: { config: { apiKey: '...', authDomain: '...', projectId: '...', appId: '...', // there could be other properties depending on the project }, }, }) ``` -------------------------------- ### Build Nuxt App for Serverless Deployment Source: https://github.com/vuejs/vuefire/blob/main/docs/nuxt/deployment.md Build your Nuxt application for serverless deployment on Firebase using a specific Nitro preset. This command is used for the Blaze plan. ```sh NITRO_PRESET=firebase nuxt build ``` -------------------------------- ### Upload files with useStorageFile Source: https://github.com/vuejs/vuefire/blob/main/docs/guide/storage.md Use the useStorageFile composable to handle file uploads and track progress reactively. ```vue ``` -------------------------------- ### Enable VueFire Auth Module Source: https://github.com/vuejs/vuefire/blob/main/docs/nuxt/auth.md Configure nuxt.config.ts to enable the VueFire authentication module. ```typescript export default defineNuxtConfig({ // ... vuefire: { // ensures the auth module is enabled auth: { enabled: true }, config: { // ... } }, }) ``` -------------------------------- ### SSR Configuration with Vite-SSG Source: https://context7.com/vuejs/vuefire/llms.txt Handles Firebase initialization for SSR and custom state serialization using devalue. ```typescript // src/modules/vuefire.ts (Vitesse template) import { initializeApp } from 'firebase/app' import { VueFire, useSSRInitialState } from 'vuefire' import type { UserModule } from '~/types' export const install: UserModule = ({ isClient, initialState, app }) => { const firebaseApp = initializeApp({ apiKey: import.meta.env.VITE_FIREBASE_API_KEY, // ... other config }) app.use(VueFire, { firebaseApp }) if (isClient) { // Hydrate state on client useSSRInitialState(initialState.vuefire, firebaseApp) } else { // Collect state on server initialState.vuefire = useSSRInitialState(undefined, firebaseApp) } } ``` ```typescript // src/main.ts - Custom state serialization import devalue from 'devalue' import { ViteSSG } from 'vite-ssg' import { devalueCustomParsers, devalueCustomStringifiers } from 'vuefire' import App from './App.vue' export const createApp = ViteSSG( App, { routes }, ({ app, initialState }) => { // ... setup }, { transformState(state) { return import.meta.env.SSR ? devalue.stringify(state, devalueCustomStringifiers) : devalue.parse(state, devalueCustomParsers) }, } ) ``` -------------------------------- ### Configure VueFire Plugin Source: https://context7.com/vuejs/vuefire/llms.txt Initialize the Firebase app and register the VueFire plugin with the Vue application instance. ```typescript // main.ts import { createApp } from 'vue' import { VueFire, VueFireAuth } from 'vuefire' import { initializeApp } from 'firebase/app' import App from './App.vue' const firebaseApp = initializeApp({ apiKey: 'YOUR_API_KEY', authDomain: 'YOUR_PROJECT.firebaseapp.com', projectId: 'YOUR_PROJECT_ID', storageBucket: 'YOUR_PROJECT.appspot.com', messagingSenderId: 'YOUR_SENDER_ID', appId: 'YOUR_APP_ID' }) const app = createApp(App) app.use(VueFire, { firebaseApp, modules: [ VueFireAuth(), ], }) app.mount('#app') ``` -------------------------------- ### Configure Options API modules Source: https://context7.com/vuejs/vuefire/llms.txt Registers Firestore and Realtime Database Options API modules during Vue application initialization. ```typescript // main.ts - Enable Options API modules import { createApp } from 'vue' import { VueFire, VueFireFirestoreOptionsAPI, VueFireDatabaseOptionsAPI } from 'vuefire' import { initializeApp } from 'firebase/app' const firebaseApp = initializeApp({ /* config */ }) const app = createApp(App) app.use(VueFire, { firebaseApp, modules: [ VueFireFirestoreOptionsAPI(), VueFireDatabaseOptionsAPI(), ], }) ``` -------------------------------- ### Configure Global Firestore and Database Options Source: https://context7.com/vuejs/vuefire/llms.txt Sets global converters and serializers to transform data globally, and demonstrates using withConverter for type-safe Firestore operations. ```typescript import { globalFirestoreOptions, globalDatabaseOptions, firestoreDefaultConverter, databaseDefaultSerializer } from 'vuefire' // Custom Firestore converter (adds metadata to all documents) globalFirestoreOptions.converter = { toFirestore: firestoreDefaultConverter.toFirestore, fromFirestore: (snapshot, options) => { const data = firestoreDefaultConverter.fromFirestore(snapshot, options) if (!data) return null // Add custom properties return { ...data, _metadata: snapshot.metadata, _ref: snapshot.ref, } }, } // Custom Database serializer globalDatabaseOptions.serialize = (snapshot) => { const data = databaseDefaultSerializer(snapshot) // Add timestamp conversion or other transformations return { ...data, _key: snapshot.key, } } // Using withConverter for type-safe documents import { collection, doc } from 'firebase/firestore' interface User { id: string name: string email: string role: 'admin' | 'user' } const userConverter = { toFirestore: (user: User) => ({ name: user.name, email: user.email, role: user.role, }), fromFirestore: (snapshot, options): User | null => { const data = firestoreDefaultConverter.fromFirestore(snapshot, options) if (!data) return null return { id: snapshot.id, name: data.name, email: data.email, role: data.role, } }, } // Use converter with collection/document const usersRef = collection(db, 'users').withConverter(userConverter) const users = useCollection(usersRef) // Typed as User[] const userRef = doc(db, 'users', 'user123').withConverter(userConverter) const user = useDocument(userRef) // Typed as User | null ``` -------------------------------- ### Customize Auth Dependencies Source: https://github.com/vuejs/vuefire/blob/main/docs/nuxt/auth.md Configure VueFire authentication options in `nuxt.config.ts`, including error maps, popup redirect resolver, and persistence. ```typescript export default defineNuxtConfig({ // ... vuefire: { auth: { errorMap: 'debug', // disable the poupup redirect resolver dependency popupRedirectResolver: false, persistence: ['indexedDBLocal'] }, }, }) ``` -------------------------------- ### Initialize VueFire Auth Module Source: https://github.com/vuejs/vuefire/blob/main/docs/guide/auth.md Register the VueFireAuth module within the VueFire plugin configuration to enable automatic Auth module injection. ```ts import { VueFire, VueFireAuth } from 'vuefire' app.use(VueFire, { firebaseApp: createFirebaseApp(), modules: [ // ... other modules VueFireAuth(), ], }) ``` -------------------------------- ### Watch User Auth State in App Component Source: https://github.com/vuejs/vuefire/blob/main/docs/nuxt/auth.md Use `onMounted` and `watch` to monitor user authentication state changes and navigate accordingly. Recommended for layouts or `app.vue`. ```vue ``` -------------------------------- ### Implement declarative and programmatic bindings Source: https://context7.com/vuejs/vuefire/llms.txt Uses the Options API to bind Firestore collections and Realtime Database references, including programmatic unbinding. ```vue ``` -------------------------------- ### Options API Todo App Implementation Source: https://github.com/vuejs/vuefire/blob/main/examples/firestore.html Implements the Todo app functionality using Vue 2 Options API. It includes data properties, firestore bindings, and methods for managing todos. ```javascript const OptionAPI = { data: () => ({ todos: [], tweets: [], moments: [], nested: [], config: null, newTodoText: '', }), firestore: { todos: unFinishedTodos, moments: db.collection('moments'), nested: db.collection('nested'), tweets: db.collection('tweets'), config: configRef, }, beforeCreate() { console.log('Using Options API version') }, methods: { addTodo: function () { if (this.newTodoText) { todosRef.add({ finished: false, text: this.newTodoText, created: firebase.firestore.FieldValue.serverTimestamp(), }) this.newTodoText = '' } }, updateTodoText: function (todo, newText) { todosRef.doc(todo.id).update({ text: newText }) }, removeTodo: function (todo) { todosRef.doc(todo.id).delete() }, toggleTodos: function () { console.log(this.$firestoreRefs.todos === unFinishedTodos) this.$bind( 'todos', this.$firestoreRefs.todos === unFinishedTodos ? finishedTodos : unFinishedTodos ) }, }, } ``` -------------------------------- ### Awaiting Database Binding Completion Source: https://github.com/vuejs/vuefire/blob/main/docs/guide/options-api-realtime-data.md You can await the Promise returned by $databaseBind to execute code after the binding is established. This is useful for performing actions that depend on the bound data being available. ```javascript this.$databaseBind('user', dbRef(users, this.id)).then(user => { // user will be an object if this.user was set to anything but an array // and it will point to the same property declared in data: // this.user === user }) this.$databaseBind('documents', query(documents, orderByChild('creator'), equalTo(this.id))).then(documents => { // documents will be an array if this.documents was initially set to an array // and it will point to the same property declared in data: // this.documents === documents }) ``` -------------------------------- ### Set Global Database Options Source: https://github.com/vuejs/vuefire/blob/main/docs/guide/global-options.md Configure global options for database serialization. This affects all database-related bindings. ```typescript import { globalDatabaseOptions } from 'vuefire' globalDatabaseOptions.serialize = ... ``` -------------------------------- ### Configure App Check with reCAPTCHA Source: https://github.com/vuejs/vuefire/blob/main/docs/guide/app-check.md Initialize App Check using the ReCaptchaV3Provider. Ensure App Check is enabled in the Firebase Console before implementation. ```ts import { VueFire, VueFireAppCheck } from 'vuefire' import { ReCaptchaV3Provider } from 'firebase/app-check' app.use(VueFire, { firebaseApp: createFirebaseApp(), modules: [ // ... other modules VueFireAppCheck({ provider: new ReCaptchaV3Provider('...') isTokenAutoRefreshEnabled: true, }), ], }) ``` -------------------------------- ### Manual SSR Key for Database List Source: https://github.com/vuejs/vuefire/blob/main/docs/guide/ssr.md Provide a manual `ssrKey` when using `useDatabaseList` with a query reference. This is necessary when VueFire cannot automatically infer a unique key, such as with Firestore Queries. ```typescript useDatabaseList(queryRef, { ssrKey: 'my-quiz' }) ``` -------------------------------- ### Handle Pending Promises with onServerPrefetch Source: https://github.com/vuejs/vuefire/blob/main/docs/guide/ssr.md When using VueFire composables in Pinia stores, manually call `usePendingPromises()` within `onServerPrefetch()` in any component that consumes the data to ensure it's loaded on the server. ```vue ```