Skip to content

Introduction

Vuefire is a small and pragmatic solution to create realtime bindings between a Firebase RTDB or a Firebase Cloud Firestore and your Vue application. Making it straightforward to always keep your local data in sync with remote databases.

Why VueFire

While Firebase SDK does provide an API to keep your local data in sync with any changes happening in the remote database, it is more tedious than you can imagine, and it involves many edge cases. Here is the code you need to write to keep your local state in sync with Firebase without using Vuefire. Let's take the example of binding a collection as an array, both with the RTDB and with Cloud Firestore:

js
// get Firestore database instance
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)
  },
})

WARNING

  • In the RTDB example, we are omitting the unsubscribe part because it requires to save the return of every listener created to later on call this.todosRef.off with every single one of them.
  • In the Firestore example, the code above is not taking into account Firestore references which considerably increases the complexity of binding and is handled transparently by Vuefire

Now let's look at the equivalent code with vuefire:

js
import { initializeApp } from 'firebase/app'
import { getFirestore, collection } from 'firebase/firestore'
import { createApp } from 'vue'
import { useCollection } from 'vuefire'

const firebase = initializeApp({ projectId: 'MY PROJECT ID' })
const db = getFirestore(firebase)

createApp({
  setup() {
    const todosRef = collection(db, 'todos')
    const todos = useCollection(todosRef)

    return { todos }
  }
})

And that's it! You can use todos anywhere, it will be always in sync with your remote database. Let's dive deeper and learn about all the features added by Vuefire: Getting started

Released under the MIT License.