Using Firebase in a Vue App with Vuexfire — Unbinding, and Geopoints
Tags: vue, webdev, programming, javascript
Published: 2021-01-26 01:24:14

**Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62**

**Subscribe to my email list now at http://jauyeung.net/subscribe/**


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.