Firebase has been consistently popular among JavaScript and Vue developers for years now, but how do you actually set it all up and connect Vue + Firebase together?
Well, the good news is that it's relatively simple. In fact, you can get an official plugin for integrating Firebase into a Vue project from the Vue team, called VueFire.
Huzzah!
Rather than leave you to figure out how that works, in this tutorial, I'll show you how to use this plugin to seamlessly integrate your project by building a simple number generator.
Note: Examples of this project are written with both the Options API and Composition API.
This tutorial assumes you're already familiar with the basics of Vue. (If not, check out this free video from my complete Vue Developer course).
For a simple project, you can follow the instructions for new projects here. Alternatively, you can use StackBlitz to create a new Vue project on the web.
You don't need to install packages like Pinia or the Vue Router. A reasonably minimal project is all that's required.
First things first, we need to create a Firebase project, which is free and straightforward to do, but it does require that you have a Google Account since Google owns Firebase.
Once you've got an account, follow these steps:
For a detailed guide, check out these instructions.
New projects can be created by navigating to the Firebase console. On this page, you can select to create a new project.
Next, you need to assign a name to your new project.
Lastly, you may be asked to enable Google Analytics. You can choose to enable this option if you wish, but we won't be using it.
Firebase offers two databases called Firestore and Realtime Database. Firestore is the recommended solution for most projects, and it's what we'll be using in this tutorial.
On the sidebar, navigate to Build > Firestore.
Then, on the page, click the Create Database button.
Up next, you're asked to select a mode. During the initial development phase of an app, you should choose test mode.
Lastly, you'll be asked to select a physical location.
Top tip: In most cases, you will want to choose a location closest to your users for the fastest response times.
On the Project Overview page for an app, you can select the Web option to register a new app for your Firebase project.
Next, give your web app a nickname.
Once you've done that, you may be given instructions for installing the SDK.
In the code snippet, there's a variable called firebaseConfig
. Copy the value of this variable, as you're going to need it in a moment.
Now that you have a Firebase project, it's time to install the necessary packages for integrating it into a Vue project.
yarn add vuefire firebase
# or
npm install vuefire firebase
Two packages are being installed called firebase
and vuefire
.
firebase
- Firebase's official SDK for communicating between your JS and Firebase appvuefire
- Vue's official package for smoothly integrating Firebase into Vue. Since Firebase is framework agnostic, this package wraps a few of Firebase's APIs into a Vue-friendly APIAfter installing the packages, the Firebase app needs to be initialized.
For a clean codebase, it's best to outsource this logic into a separate file, so in the src directory, add a file called firebase.js with the following code:
import { initializeApp } from "firebase/app";
export const firebaseApp = initializeApp({
apiKey: "xxxx",
authDomain: "xxxx",
projectId: "xxxx",
storageBucket: "xxxx",
messagingSenderId: "xxxx",
appId: "xxxx",
});
In the above code snippet, we're importing the initializeApp
function from the Firebase package.
Initializing Firebase in a Vue application is like initializing any other Firebase app, but notice that we're exporting the firebaseApp
variable.
Important Note: Be sure to use the configuration details provided during the web app registration. The object passed into the
initializeApp
function should contain your Firebase configuration.
Next, we must register the VueFire
plugin from the VueFire package, which adds an API for interacting with firebase.
import { VueFire, VueFireFirestoreOptionsAPI } from "vuefire";
If you're using the options API, you must import the VueFireFirestoreOptionsAPI
function to extend the plugin's support for the options API. (Developers using the composition API do not need additional modules).
During the app initialization, you can register the plugin with the use
function.
import { firebaseApp } from "./firebase";
const app = createApp(App);
app.use(VueFire, {
firebaseApp,
modules: [VueFireFirestoreOptionsAPI()],
});
app.mount("#app");
The second argument can be used to configure the plugin. This is where you can provide a copy of your Firebase app that was exported from the firebase.js file.
For the options API, an array called modules
must be added with a list of modules to support.
Want to know something cool? Firebase is not a single product. Instead, it's a suite of services, such as authentication, database, and file storage.
In this example, we're adding support for the Firestore service by adding the VueFireFirestoreOptionsAPI
module.
Developers new to Firebase will come across two words in the documentation, which are documents and collections.
Understanding terminology is half the battle of learning a new technology, so let's quickly review these terms before moving forward.
It's common to want to interact with a collection in multiple components, so before inserting data into a database, you must reference a specific collection.
To save time, you can grab a reference to a collection and export that reference. This way, you don't have to grab a reference in each component.
In the firebase.js file, you can grab a reference with the following code:
import { getFirestore, collection } from "firebase/firestore";
export const db = getFirestore(firebaseApp);
export const numbersRef = collection(db, "numbers");
First, we must grab a reference to the database with the getFirestore
function, which accepts an instance of the Firebase app.
Next, we can use the collection
function to retrieve a reference. Two arguments must be supplied, which are the database reference and the name of the collection.
In this example, we're grabbing a collection called numbers
. If this collection doesn't exist in your database, that's completely fine. Firebase creates collections that don't exist whenever you reference them.
At this point, we're using Firebase's SDK to prepare the references. We're not using Vue's APIs just yet.
Documents can be created by using the addDoc
function. This function accepts a reference to a collection and the object to insert as a document.
<script setup>
import { addDoc } from "firebase/firestore";
import { numbersRef } from "@/firebase";
async function createDocument() {
const newDocument = { num: Math.round(Math.random() * 100) };
await addDoc(numbersRef, newDocument);
}
</script>
In the above example, we're importing the numbersRef
from the firebase.js file. By grabbing the reference, we can skip grabbing the collection from the component.
Next, we're creating an object called newDocument
. It's very straightforward, as all we're doing is storing a random number in a property called num
.
The addDoc
function gets called with the collection referene and new object. All database operations are asynchronous. You can use async/await syntax for readable code.
Here's what the same operation would look like with the options API.
<script>
import { addDoc } from "firebase/firestore";
import { numbersRef } from "@/firebase";
export default {
methods: {
async createDocument() {
const newDocument = { num: Math.round(Math.random() * 100) };
await addDoc(numbersRef, newDocument);
},
},
};
</script>
Retrieving documents from a collection is super simple, as the VueFire package has a composable called useCollection
for retrieving all documents under a collection.
import { useCollection } from "vuefire";
import { numbersRef } from "@/firebase";
const documents = useCollection(numbersRef);
All you need to pass in is a reference to the collection. You can loop through the documents like any other array in your template with the v-for
directive.
<p v-for="doc in documents" :key="doc.id">{{ doc.num }}</p>
In addition to the properties in your document, you can grab the document's ID with the id
property.
For those using the options API, the process is slightly different.
import { numbersRef } from "@/firebase";
export default {
data() {
return {
documents: [],
};
},
firestore: {
documents: numbersRef,
},
};
Firstly, you must have a data property for storing the documents. Secondly, you must add a special property to the component configuration called firestore
. Within this object, we must add a data property that'll store the array of documents.
In this example, we're using a property called documents
. The value of this property must be the collection reference.
Updating documents can be performed with the updateDoc
function.
Before updating a document, you must grab a reference to a specific document. Luckily, the doc
function performs this same operation. It has three arguments.
import { updateDoc, doc } from "firebase/firestore";
import { useCollection } from "vuefire";
import { db, numbersRef } from "@/firebase";
async function updateDocument(id) {
const newDocument = { num: Math.round(Math.random() * 100) };
const docRef = doc(db, "numbers", id);
await updateDoc(docRef, newDocument);
}
In the above example, we're accepting the ID of the document as an argument. After grabbing the document, we're updating it with the updateDoc
function. This function accepts the document reference and updated object.
Here's the same example with the options API.
import { updateDoc, doc } from "firebase/firestore";
import { db } from "@/firebase";
export default {
methods: {
async updateDocument(id) {
const newDocument = { num: Math.round(Math.random() * 100) };
const docRef = doc(db, "numbers", id);
await updateDoc(docRef, newDocument);
},
},
};
Documents can be deleted with the deleteDoc
function. Similar to the updateDoc
function, a reference to the document must be passed in. This action can be performed with the doc
function.
import { deleteDoc, doc } from "firebase/firestore";
import { db } from "@/firebase";
async function deleteDocument(id) {
await deleteDoc(doc(db, "numbers", id));
}
Here's the same action with the options API.
import { deleteDoc, doc } from "firebase/firestore";
import { db } from "@/firebase";
export default {
methods: {
async deleteDocument(id) {
await deleteDoc(doc(db, "numbers", id));
},
},
};
If you're curious for an example of these functions, check out this demo.
A few things are worth noting:
Integrating Firebase with Vue is incredibly easy, and it's definitely worth doing.
Not bad right?
If you want a deep dive into Vue and learn how to build full-stack applications with Firebase, check out my complete Vue Developer Bootcamp course.
This is a bold statement but I can guarantee you that it's the most comprehensive and up-to-date Vue course that you can find.
You'll learn Vue from scratch (including all new Vue 3 features), build your own professional Vue.js apps (ex: an entire Spotify clone app) and learn everything you need to know to get hired as a Vue.js developer this year.
The best part? You can start taking the course for free right here.