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.
Timestamps
We can add a timestamp to our document with the Timestamp.fromDate
method.
This is only available when we use Vuexfire with Cloud Firestore.
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: {
events: []
},
mutations: {
...vuexfireMutations
},
actions: {
bindEventsRef: firestoreAction((context) => {
return context.bindFirestoreRef("events", db.collection("events"));
})
},
getters: {
events: (state) => {
return state.events;
}
}
});
new Vue({
store,
render: (h) => h(App)
}).$mount("#app");
App.vue
<template>
<div>{{events}}</div>
</template>
<script>
import { mapGetters, mapActions } from "vuex";
import { db, Timestamp } from "./db";
export default {
data() {
return {};
},
methods: {
...mapActions(["bindEventsRef"])
},
computed: {
...mapGetters(["events"])
},
async mounted() {
this.bindEventsRef();
await db.collection("events").add({
name: "event",
date: Timestamp.fromDate(new Date("2029-09-14"))
});
}
};
</script>
We call the Timestamp.fromDate
method to add the timestamp.
And we called bindEventsRef
to sync the events
collection with the events
state in our store.
We then get the events
state with a getter.
Then our events
state has something like:
[ { "name": "event", "date": { "seconds": 1884038400, "nanoseconds": 0 } } ]
We can also call toDate
to turn the Timestamp
object back to a human-readable date:
<template>
<div>
<div v-for="e of events" :key="e.id">{{e.date.toDate()}}</div>
</div>
</template>
<script>
import { mapGetters, mapActions } from "vuex";
import { db, Timestamp } from "./db";
export default {
data() {
return {};
},
methods: {
...mapActions(["bindEventsRef"])
},
computed: {
...mapGetters(["events"])
},
async mounted() {
this.bindEventsRef();
await db.collection("events").add({
name: "event",
date: Timestamp.fromDate(new Date("2029-09-14"))
});
}
};
</script>
References
We can store references of another document in a document.
For example, we can write:
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"));
})
},
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";
import { db } from "./db";
export default {
data() {
return {};
},
methods: {
...mapActions(["bindBooksRef"])
},
computed: {
...mapGetters(["books"])
},
async mounted() {
this.bindBooksRef();
await db.collection("books").add({
title: "foo",
author: db.collection("authors").doc("james-smith")
});
}
};
</script>
We just get the collection with db.collection
.
Then with what it returns, we call doc
with the ID of the authors
document as the argument to reference it.
Conclusion
We can add documents to our Firebase database collections and they’ll be automatically reflected in our Vue app if we bind the Vuex state to our collection.