12周ぐらい回って誰もが飽きているNuxt.jsとFirebaseの組み合わせですが、いくら記事を読んでもやっぱり自分で書いてみないとわからないものがあるわけで、散々出回っているgetting-started記事だけど自らの記録という意味も含めて書いてみます。
Nuxt.js
Nuxt.js は Vue アプリケーションを作成するフレームワークです。ユニバーサルアプリケーション、静的に生成されるアプリケーション、シングルページアプリケーションの中から作成するアプリケーションを選ぶことができます。
よくNuxt.jsを説明するときにサーバーサイドレンダリングについて言及されることが多いけど、javascriptを使ってサーバーサイドレンダリングするメリットがよくわかってない。それならLLでもよくないですか??
Firebase
モバイルアプリケーションやWebアプリケーションのためのGoogleのバックエンドサービス。これによってサーバーレスアーキテクチャを実現出来たりする。認証やDB、ホスティングなど様々なサービスがある。
つまり?
LLでもいいのではという疑問が出たが、Nuxt.jsとFirebaseを使うことで、モバイルアプリエンジニアやフロントエンドエンジニアでも、サーバーサイドやインフラの知識をそれほど必要としないでバックエンド開発が出来る。
今回作ったもの
Nuxt.jsとFirebase Cloud Firestoreを使って一行日記を記録出来るシンプルなWebアプリケーション。
開発環境
macOS Sierra 10.12.6
Node v10.8.0
Yarn 1.9.4(最新の1.12.3にしたらエラーとなったので…)
まずNuxt.js
インストール
プロジェクト名は"one-liner-diary"としました。
$ yarn create nuxt-app one-liner-diary --edge
$ cd one-liner-diary
$ yarn run dev
ブラウザでlocalhostにアクセスするとロゴの画面が表示されます。
超簡単。というか最近はどのフレームワークやライブラリでも初心者に優しいのがありがたい。
新しい画面を追加してみる
pages以下に新しいVueファイルnewdawn.vueを追加。
layouts/default.vueのサイドナビゲーションにもその画面へのリンクを追加します。
ファイル名がそのままルーティングになるのがわかりやすいです。
yarn run dev
でホットリロードされて、サイドナビゲーションから新しい画面に遷移出来ます。簡単だ…。
Vuexを使って一行日記を実装
ここは主題ではないので省略。VuexとVuetifyを使って簡単な日記機能を実装。
以下がそのコミットです。
store/index.jsを追加すると自動でVuexが有効になるのが便利。
躓いた点としては、Vuetifyで以下のESLintのエラーが出たので、そのルールだけ除外しました。
error Require self-closing on Vue.js custom components (<v-text-field>) vue/html-self-closing
次にFirebase Cloud Firestore
FirebaseのデータベースにはRealtime DatabaseとCloud Firestoreがある。今回はまだベータ版だがCloud Firestoreを使ってみました。どちらもNoSQLデータベース。
まずFirebaseのプロジェクトがない場合はプロジェクトを登録します。
その後、FirebaseコンソールからFirestoreのデータベースを作ります。
Firestoreはコレクションとドキュメントから構成される。なんとなくjsonっぽいのでjavascriptとも相性がいいのだろう。
コンソールからいくつかデータを登録しておきます。
次にfirebaseとvuexfireをインストール。これでVuex経由でFirestoreを操作出来るようになります。
$ yarn add firebase vuexfire@next
FirebaseコンソールにはAPIキーの情報があるので、それをソースコードにコピペ。
参考URLの記事にも書かれていたけど、settingsを記述しないとブラウザで警告が出ます。
調べたところAPIキーは隠さなくてもいいらしい(しかし自分はjsonに分けてコミットから外した)。
const config = {
apiKey: "APIキー",
authDomain: ...
databaseURL: ...
}
export default config
import firebase from 'firebase'
import config from '@/config'
if (!firebase.apps.length) {
firebase.initializeApp(config)
}
const db = firebase.firestore()
const settings = { timestampsInSnapshots: true }
db.settings(settings);
export { db }
import Vuex from 'vuex'
import { firebaseMutations, firebaseAction } from 'vuexfire'
const store = () => {
return new Vuex.Store({
state: () => ({
notes: [],
}),
mutations: {
...firebaseMutations
},
actions: {
setNotesRef: firebaseAction(({ bindFirebaseRef }, ref) => {
bindFirebaseRef('notes', ref)
}),
saveNote ({ commit, state }, note) {
let notes = state.notes
notes.push({ content: note })
commit('setNotes', notes)
},
},
getters: {
getNotes: (state) => {
return state.notes
},
},
})
}
export default store
<template>
<v-layout
justify-center
align-center
row
wrap>
<v-flex
xs12
mb-2>
<v-text-field
v-model="newNote"
label="日記を書こう!"
@keyup.enter="saveNote"
></v-text-field>
<v-btn
color="success"
@click="saveNote">
Send
</v-btn>
</v-flex>
<v-flex
v-for="(note, i) in notes"
:key="i"
xs12
mb-2>
<v-card>
<v-card-text>
{{ note.content }}
</v-card-text>
</v-card>
</v-flex>
</v-layout>
</template>
<script>
import { mapGetters } from 'vuex'
import { db } from '../plugins/firebase'
export default {
data () {
return {
newNote: '',
}
},
computed: {
...mapGetters({ notes: 'getNotes' })
},
mounted () {
this.$store.dispatch('setNotesRef', db.collection('notes'))
},
methods: {
saveNote () {
if (!this.newNote.length) {
return
}
const newNote = { content: this.newNote }
this.newNote = ''
db.collection('notes').add(newNote)
},
},
}
</script>
なんか中途半端な順番でデータが追加されているけど、とりあえずブラウザからFirestoreへのデータ登録は出来ました。
Firebase AuthenticationでGoogle認証
も書くつもりだったのだが力尽きたので次の記事に続きます。
追記
書きました。
参考URL
https://qiita.com/potato4d/items/cfddeb8732fec63cb29c
https://qiita.com/cyokodog@github/items/eeedc5c94477602ec9f3
https://qiita.com/wataruoguchi/items/8fdda8e9754658be06be