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 to add support for Cloud Firestore database manipulation into our Vue app.
Getting Data
We can get data in various ways with Vuefire.
We can call the this.$bind
method with a collection.
For example, we can write:
Book.vue
<template>
<div>{{book.title}}</div>
</template>
<script>
import { db } from "./db";
const books = db.collection("books");
export default {
props: ["id"],
data() {
return {
book: {}
};
},
watch: {
id: {
immediate: true,
async handler(id) {
const book = await this.$bind("book", books.doc(id));
console.log(book);
}
}
}
};
</script>
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 };
We make the watcher for the id
prop async so that we can use await
to get the resolved value from this.$bind
.
this.$bind
returns a promise so we can do that.
book
has the resolved value from the Cloud Firestore.
We can do the same for collections.
For example, we can write:
App.vue
<template>
<div id="app">{{book.title}}</div>
</template>
<script>
import { db } from "./db";
const books = db.collection("books");
export default {
name: "App",
data() {
return {
title: "title",
book: {}
};
},
async mounted() {
const [book] = await this.$bind(
"books",
books.where("title", "==", this.title)
);
this.book = book;
console.log(book);
}
};
</script>
We call the where
method to search for an entry with the title
instead of getting a document by ID.
The resolved value is destructured so that we can get the entry and display it in the template.
.key
/ id
The id
property of a document isn’t enuerable.
So Object.keys
won’t include the key in the array of keys.
But we can access it with the id
property directly.
For example, we can write:
<template>
<div id="app">
<div v-for="b of books" :key="b.id">{{b.id}} - {{b.title}}</div>
</div>
</template>
<script>
import { db } from "./db";
export default {
name: "App",
data() {
return {
books: []
};
},
firestore: {
books: db.collection("books")
}
};
</script>
to get the id
from books
entries in our template.
Geopoints
Geopoints is something we can store with the Cloud Firestore.
For example, we can write:
<template>
<div id="app">
<div v-for="b of books" :key="b.id">{{b}}</div>
</div>
</template>
<script>
import { db, GeoPoint } from "./db";
export default {
name: "App",
data() {
return {
books: []
};
},
firestore: {
books: db.collection("cities")
},
async mounted() {
await db.collection("cities").add({
name: "London",
location: new GeoPoint(51.3, 0)
});
}
};
</script>
to add a GeoPoint
instance with the latitude and longitude as its arguments.
Then the object created in the cities
collection should have something like:
{ "name": "London", "location": { "latitude": 51.3, "longitude": 0 } }
We have the latitude
and longitude
properties in the entry.
Timestamps
We can also save timestamps with the Timestamp.fromDate
method that comes with Vuefire.
It’s also available with Firestore only.
To use it, we can write:
<template>
<div id="app">
<div v-for="b of books" :key="b.id">{{b}}</div>
</div>
</template>
<script>
import { db, Timestamp } from "./db";
export default {
name: "App",
data() {
return {
books: []
};
},
firestore: {
books: db.collection("events")
},
async mounted() {
await db.collection("events").add({
name: "parade",
date: Timestamp.fromDate(new Date("2029-07-14"))
});
}
};
</script>
We pass in a Date
instance into the fromDate
method.
Then we get something like:
{ "name": "parade", "date": { "seconds": 1878681600, "nanoseconds": 0 } }
added to the events
collection.
seconds
is the UNIX timestamp in seconds.
Conclusion
We can save various items to Firebases’ Cloud Firestore in our Vue app with Vuefire.