Categories
Vue

Using Firebase in a Vue App with Vuexfire — Unbinding, and Geopoints

Spread the love

The Vuefire library lets us add Firebase database manipulation capabilities right from our Vue app.

In this article, we’ll look at how to use Vuefire and Vuexfire to add support for Cloud Firestore database manipulation into our Vue app.

Unbinding

We can stop syncing the state of a collection or document to our Vuex store with the unbindFirestoreRef method.

For example, we can write:

db.js

import firebase from "firebase/app";
import "firebase/firestore";
export const db = firebase
  .initializeApp({ projectId: "project-id" })
  .firestore();
const { Timestamp, GeoPoint } = firebase.firestore;
export { Timestamp, GeoPoint };

main.js

import Vue from "vue";
import App from "./App.vue";
import { firestorePlugin } from "vuefire";
import { vuexfireMutations, firestoreAction } from "vuexfire";
import Vuex from "vuex";
import { db } from "./db";

Vue.use(Vuex);
Vue.use(firestorePlugin);
Vue.config.productionTip = false;

const store = new Vuex.Store({
  state: {
    books: []
  },
  mutations: {
    ...vuexfireMutations
  },
  actions: {
    bindBooksRef: firestoreAction((context) => {
      return context.bindFirestoreRef("books", db.collection("books"));
    }),

    unbindBooksRef: firestoreAction(({ unbindFirestoreRef }) => {
      unbindFirestoreRef("books");
    })
  },
  getters: {
    books: (state) => {
      return state.books;
    }
  }
});

new Vue({
  store,
  render: (h) => h(App)
}).$mount("#app");

App.vue

<template>
  <div>{{books}}</div>
</template>
<script>
import { mapGetters, mapActions } from "vuex";

export default {
  data() {
    return {};
  },
  methods: {
    ...mapActions(["bindBooksRef"])
  },
  computed: {
    ...mapGetters(["books"])
  },
  mounted() {
    this.bindBooksRef();
  }
};
</script>

We added the unbindBookRef action which calls the unbindFirestoreRef with the collection name string.

By default, when we unbind a collection, the Vuex store state will reset to its initial value.

unbindFirestoreRef(“books”); is the same as unbindFirestoreRef(“books”, true); .

If we don’t want to state to be reset when we unbind, we can pass in false as the 2nd argument:

unbindFirestoreRef("books", false);

We can also reset the state to the value we want if we pass in a function that returns the value we want to reset to:

unbindFirestoreRef('books', () => [{ title: 'foo' }])

If we reset a document, then it’ll be reset to null :

unbindFirestoreRef('book')

Geopoints

We can save geolocation data to our Firebase documents with the GeoPoint constructor.

This is only available with Cloud Firestore only.

For example, we can use it by writing:

main.js

import Vue from "vue";
import App from "./App.vue";
import { firestorePlugin } from "vuefire";
import { vuexfireMutations, firestoreAction } from "vuexfire";
import Vuex from "vuex";
import { db } from "./db";

Vue.use(Vuex);
Vue.use(firestorePlugin);
Vue.config.productionTip = false;

const store = new Vuex.Store({
  state: {
    cities: []
  },
  mutations: {
    ...vuexfireMutations
  },
  actions: {
    bindCitiesRef: firestoreAction((context) => {
      return context.bindFirestoreRef("cities", db.collection("cities"));
    })
  },
  getters: {
    cities: (state) => {
      return state.cities;
    }
  }
});

new Vue({
  store,
  render: (h) => h(App)
}).$mount("#app");

App.vue

<template>
  <div>{{cities}}</div>
</template>
<script>
import { mapGetters, mapActions } from "vuex";
import { db, GeoPoint } from "./db";

export default {
  data() {
    return {};
  },
  methods: {
    ...mapActions(["bindCitiesRef"])
  },
  computed: {
    ...mapGetters(["cities"])
  },
  async mounted() {
    this.bindCitiesRef();
    await db.collection("cities").add({
      name: "Paris",
      location: new GeoPoint(48.9, 2.3)
    });
  }
};
</script>

We just call add to add the entry to our Firestore collection.

The GeoPoint constructor returns an object that has the latitude and longitude properties.

These are also the arguments of the constructor.

Since we called the bindCitiesRef method, the collection’s documents are automatically synced with the Vuex Store.

And we called mapGetters to map the cities getter to our component, so we’ll see the documents in our template.

Conclusion

We can unbind from our store and add GeoPoint instances to our collection and see the updates immediately.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *