今回のチュートリアルではNuxt.jsを使っていますが、全部フロントエンドで動いているのでVue.jsアプリでも同様に動きます。
TL;DR
サンプルコードはGithubにあります。
VuexFireを使ってNuxt.jsアプリでFirestoreからデータを取得しページに表示させます。また、ページ上のフォームからFirestoreにデータを追加します。
はじめに
前回の記事でVuex.jsとFirebaseのCloud Functionsを使ってSSRアプリを作ってみました。
そのアプリをベースに、今回はVuexFireを使ってFirestoreを導入してみます。
FirestoreはFirebaseの提供するNoSQLデータベースです。現在はβ版ですが、今後Firebase Realtime Databaseに代わりFirebaseのデータベースサービスになっていくようです。
Step 1: Firestore でコレクションを作ってみましょう
コレクションはRDBで言うところのテーブルです。ちなみにドキュメントはRDBのレコードに相当します。
作成するものは以下の通りです。
コレクション:users
ドキュメント:users: { name: "test", email: "test@test.com" }
Cloud Firestore with Vue.jsで簡単なメモアプリを実装する by @rubytomato@github のFirebaseにプロジェクトを作成する にとても丁寧に説明されていたので、そちらを参考にして作ってみてください。
Step 2: パッケージをインストールしてみましょう
私のFirebaseプロジェクト構成は以下の通りです。Nuxt.jsのプロジェクトはsrc
の中にあります。
<proj>
L src
L plugins
L components
L package.json
L ...
L functions
L public
src
に移動してfirebase
とvuexfire
をインストールします。
cd src/ && yarn add firebase vuexfire@next
Step 3: コンフィグファイルを作成してみましょう
serviceAccountKey.json
ファイルを作成します。今回は<proj>
フォルダ内に作成します。
<proj>
フォルダに移動して、ファイルを作成しましょう
cd ../ && vi serviceAccountKey.json
{
"apiKey": "<API_KEY>",
"authDomain": "<PROJECT_ID>.firebaseapp.com",
"databaseURL": "https://<DATABASE_NAME>.firebaseio.com",
"projectId": "<PROJECT_ID>",
"storageBucket": "<BUCKET>.appspot.com",
"messagingSenderId": "<SENDER_ID>"
}
API_KEYなどの情報は https://console.firebase.google.com/u/0/project/プロジェクト名/settings/general/ で確認することができます。
Step 4: firebaseプラグインを作ってみましょう
src
フォルダに移動して、firebase.js
をplugins
フォルダに作成します。
cd src/ && vi plugins/firebase.js
import firebase from 'firebase'
import 'firebase/firestore'
const serviceAccount = require('~/../serviceAccountKey.json')
firebase.initializeApp({ ...serviceAccount })
const db = firebase.firestore()
const settings = { timestampsInSnapshots: true }
db.settings(settings)
export { db }
コンフィグファイルを元にfirebaseをイニシャライズし、dbをエクスポートしています。
settings
を省略したところ、Browserのコンソールで追加するよう警告されました。
Step 5: プラグインをNuxt.jsで使えるように設定ファイルを編集しましょう
src
フォルダにいることを確認してください。nuxt.config.js
を編集してpluginを使えるよう設定します。
vi nuxt.config.js
module.exports = {
...
plugins: ['~/plugins/firebase'],
...
}
Step 6: Vuex用のstoreファイルを作成してみましょう
src
フォルダにいることを確認してください。store
フォルダの中にindex.js
を作成して編集していきます。
vi store/index.js
import Vuex from 'vuex'
import { firebaseMutations, firebaseAction } from 'vuexfire'
const createStore = () => {
return new Vuex.Store({
state: {
users: [],
},
mutations: {
...firebaseMutations
},
actions: {
setUsersRef: firebaseAction(({ bindFirebaseRef }, ref) => {
bindFirebaseRef('users', ref)
})
},
getters: {
getUsers: (state) => {
return state.users
},
},
})
}
export default createStore
ここで特別なところは以下のvuexfire
を使っているところです。
import { firebaseMutations, firebaseAction } from 'vuexfire'
mutations
actions.setUsersRef
でもたったこれだけです。
Step 7: ページに表示させてみましょう
src
フォルダにいることを確認してください。pages/users.vue
を編集して、Step 1で作ったコレクションを表示させてみましょう。
<template>
<div>
<h1>firestore contents here</h1>
<ul>
<li v-for="(user, userIdx) in users" :key="userIdx">
<ul>
<li>name: {{ user.name }}</li>
<li>email: {{ user.email }}</li>
</ul>
</li>
</ul>
</div>
</template>
<script>
import { db } from '~/plugins/firebase.js'
import { mapGetters } from 'vuex'
export default {
created: function () {
this.$store.dispatch('setUsersRef', db.collection('users'))
},
computed: {
...mapGetters({ users: 'getUsers' })
},
}
</script>
<style>
</style>
created
でFirestoreのusersをバインドし、computedにてVuex経由でusersをフェッチしてテンプレートで表示させています。
src
フォルダ内でyarn dev
を実行してみてください。サーバーが無事に起動したら http://localhost:3000/users をブラウザで開いてみてください。無事にコレクションが表示されましたか?おめでとうございます!
前回の記事から続けてくださっている場合、エラーが出るかもしれません。このコミットを追加して、再度yarn dev
を実行してみてください。
Step 8: ページからコレクションを追加してみましょう
pages/users.vue
にフォームみたいなものを足してみましょう。
<template>
<div>
<h1>firestore contents here</h1>
<ul>
<li v-for="(user, userIdx) in users" :key="userIdx">
<ul>
<li>name: {{ user.name }}</li>
<li>email: {{ user.email }}</li>
</ul>
</li>
</ul>
+ <div class="form">
+ <h1>I know, but this is the form!</h1>
+ <div>
+ Name: <input type="text" name="name" v-model="name">
+ </div>
+ <div>
+ email: <input type="text" name="email" v-model="email">
+ </div>
+ <div>
+ <button @click="submit">Submit</button>
+ </div>
+ </div>
</div>
</template>
<script>
import { db } from '~/plugins/firebase.js'
import { mapGetters } from 'vuex'
export default {
created: function () {
this.$store.dispatch('setUsersRef', db.collection('users'))
},
computed: {
...mapGetters({ users: 'getUsers' })
},
+ data: function () {
+ return {
+ name: '',
+ email: '',
+ }
+ },
+ methods: {
+ submit: function () {
+ const user = {
+ name: this.name,
+ email: this.email,
+ }
+ const usersRef = db.collection('users')
+ usersRef.add(user)
+ this.name = ''
+ this.email = ''
+ }
+ },
}
</script>
<style>
</style>
const usersRef = db.collection('users')
でFirestoreのusersを参照し、そこにuserを追加しています。
実際にフォームに入力してみると、入力値がFirebase, Vuexを経由してフォームの上のリストに追加される様子がわかります。
同様に、Firebase ConsoleをみてみるとFirestoreにもデータが追加されていることがわかります。
おわりに
無事にFirestoreの第一歩が踏み出せたことを祈っています。次のステップとしてはFirestoreのセキュリティ設定などになってくるかと思います。Pros/ConsありますがServerlessは楽ですね。
読んでいただきありがとうございました。