始めに
明けましておめでとうございます.(執筆時:2020/1/1)
年末年始は一緒にゆっくりする友達もいないのでやったことない技術分野にチャレンジしています.
前回までの記事は
- vue cli4でプロジェクトを作ってgithub pagesに公開する + travisでCI/CD
- フロントエンド素人大学院生が爆速でVue.jsでポートフォリオを作った話
- フロントエンド素人大学院生が爆速でVue.jsでポートフォリオを作った話【Cardデザイン】
です.
最終的に作ったもの(再掲)
実際に作ったポートフォリオはこちら
github pagesで公開しています.
また,ソースコードはこちら
今回のゴール
前回までで,【表示させたいコンテンツ】を【cardコンポーネント】に表示することが出来るようになりました.
しかし,【表示させたいコンテンツ】はソースコードにハードコーディングしてしまっていて,美しくありません.
このままでは,【表示させたいコンテンツ】をちょっとだけ編集したいときに,ソースコードを編集して,masterブランチにマージして,本番環境でbuildして...ってめんどくさいです.
そこで,【表示させたいコンテンツ】はどこかから動的に取ってくるような仕組みにしようと思います.
そのような仕組みを作るのに便利なのが,FirebaseというgoogleのBaasです.(本当はただただFirebaseを使ってみたいだけ)
Firebaseには枚挙に暇がないくらい便利なものがたくさんあるのですが,
今回はその中でも,Cloud Firestoreを使います.
Cloud FirestoreはいわゆるNoSQLデータベースというものを提供してくれます.
Cloud Firestoreに【表示させたいコンテンツ】を保存させておき,Vue.jsで取得して表示させる仕組みを作っていきましょう.
ちなみに,本記事の環境は,
- vue cli4でプロジェクトを作ってgithub pagesに公開する + travisでCI/CD
- フロントエンド素人大学院生が爆速でVue.jsでポートフォリオを作った話
- フロントエンド素人大学院生が爆速でVue.jsでポートフォリオを作った話【Cardデザイン】
で作った環境を前提としています.
参考
Cloud FireStoreとVue.jsでデーターベース通信を行う
事前準備
Firebaseにアプリを作成
Firebaseを使うにあたって,まずはFirebaseにアプリを登録する必要があります.
Firebaseへアクセスし,[使ってみる]
ボタンを押してください.
(Firebase自体を初めて使う人は,登録作業が必要になるかもしれません.)
遷移した先のページで,[プロジェクトの追加]ボタンを押してください.
そして,画面の誘導にしたがってプロジェクトの作成を行ってください.
無事プロジェクトが作成できたら,次のような画面になると思います,
次は,上記画面の,</>を押してWebアプリを追加していきます.
このとき,アプリのニックネームは適当に好きな名前を登録し,Firebase Hostingにはチェックを入れないでください
手順2で,何やらコードが現れますが後でも見れるので一旦無視して登録を完了してください.
すると,先ほど作ったアプリケーションがコンソールのTopページに現れるはずです.
そこで,そのアプリケーションをクリックし,歯車マークをおし設定画面を開いてください.
設定画面の下の方に,Firebase SDK snippetというセクションがあり,なにやらコードのようなものが書いてあると思います.
これをソースコードのしかるべき部分に書く必要があるのですが,それは後で書くとして,今はこのFirebase SDK snippetがこの手順で見れることだけ知っておいてください.
Firestoreの作成
次に,先に【表示させたいコンテンツ】をFirestoreに登録しておきましょう.
ちなみに,Firestoreでのデータの構造は,
コレクション > ドキュメント > フィールド
になっています.
- フィールドはキーと値のセット
- ドキュメントは複数のフィールドを持つ
- コレクションは複数のドキュメントを持つ
という感じです.
一応,ドキュメントの中にサブコレクションという物を入れ子にすることもできますが,今回は出てきません.
では,左側のサイドバーから,Databaseというところをクリックしてください.
すると,オレンジ色のヘッダーに[データベースの作成]というボタンがあるので,そこをクリックしてください.
このようなポップアップが出てきますが,下のテストモードで開始をチェックし,次へを押してください.
次のポップアップのリージョンはデフォルトのままでOKです.
しばらく待つと,このような画面になります.(一部黒抜きしてます.)
この画面の,[コレクションを開始]ボタンを押してください.
コレクションIDは,プロジェクト内で一意であればなんでも良いです.
今回は,profileItemsとします.
次の画面では,コレクションを追加するためのフォームが出てきます.
ここのドキュメントIDもユニークである必要がありますが,ここは自動IDで構わないでしょう.
画像のように,適当にtitle, description, commentフィールドを作ってください.
同様に数回ドキュメントを追加してみてください.
このようにドキュメントが複数あればOKです.
これで読み取る用のデータの作成は終わりました,
プロジェクトにfirebaseを追加.
次に,Vue.jsでFirebaseを操作できるように,プロジェクトにfirebaseを追加します.
プロジェクトの直下で,
npm install firebase
をしてインストールしてください.
次に,Firebaseの設定用ファイルを作成します.
touch src/firebase.js
でsrc/firebase.jsを作り,以下の内容を書き込んでください.
(//ここにFirebase SDK snippetを入れる.はまだ無視して大丈夫です.)
// Your web app's Firebase configurationimportfirebasefrom'firebase/app'import'firebase/firestore'varfirebaseConfig={//ここにFirebase SDK snippetを入れる.}// Initialize Firebasefirebase.initializeApp(firebaseConfig)exportdefaultfirebaseさて,次は実際に
varfirebaseConfig={//ここにFirebase SDK snippetを入れる.}の部分を書き込む必要があります.
これは,Firebaseでアプリを作成の最後の部分で見たFirebase SDK snippetを使います.
先ほどFirebase SDK snippetを見たページに移動してください.
今回は,この[構成]と書かれた方にチェックして出てくるコードを使います.
このページの
varfirebaseConfig={apiKey:/*
いろいろな項目
*/measurementID:xxxxxxx}をコピペして,そのまま
varfirebaseConfig={//ここにFirebase SDK snippetを入れる.}と置換してください.
Firestoreからデータを取得する.
とりあえず,下準備が整ったので,実際にFirestoreからデータを取得してみようと思います.
前回までで作成した,src/views/page1.vueを持ちます.
<template><divclass="page1 container"id="page1"><h1>This is Page1</h1><divclass="card-deck row"><divv-for="(item, key) in profileItems"v-bind:key="key"class="col-xs-12 col-md-4"><profile-itemv-bind="item"/></div></div></div></template><script>importProfileItemfrom'../components/ProfileItem.vue'exportdefault{components:{ProfileItem},data(){return{profileItems:[{title:'title1',description:'description1',comment:'comment1'},{title:'title2',description:'description2',comment:'comment2'},{title:'title3',description:'description3',comment:'comment3'},{title:'title4',description:'description4',comment:'comment4'},{title:'title5',description:'description5',comment:'comment5'},{title:'title6',description:'description6',comment:'comment6'}]}}}</script><stylescoped>.page1{height:1000px;background-color:aqua;}</style>この,profileItemsに格納されているデータを,ソースコードに直書きするのではなく.Firestoreから取得するようにします.
まずは,<script>部で,先ほど作成したfirebase.jsを読み込みます.
ついでに,profileItemsを空にしておきましょう.
<script>importProfileItemfrom'../components/ProfileItem.vue'importfirebasefrom'../firebase.js'exportdefault{components:{ProfileItem},data(){return{profileItems:[]}}}</script>では,実際にデータの取得処理を書いていきますがその前に公式のドキュメントへのリンクを貼っておきます.
Cloud Firestore を使ってみる
Cloud Firestore でデータを取得する
まず,操作したいコレクションを指定してコレクション操作のためのインスタンスを作る必要があります.
firebase.firestore().collection('<コレクション名>')今回は,profileitemsという名前でコレクションを作っているので次のように書きます.
firebase.firestore().collection('profileitems')これを,<script>部に書いて,methodsから利用できるようにしましょう.
<script>importProfileItemfrom'../components/ProfileItem.vue'importfirebasefrom'../firebase.js'exportdefault{components:{ProfileItem},data(){return{profileItems:[]}},computed:{tableDatabase:()=>firebase.firestore().collection('profileitems')}}</script>これで,methodsからthis.tableDatabaseとすることでprofileitemsのデータベースにアクセスできるようになりました.
次に,profileitemsコレクションには,複数のドキュメントがあるので,それらを全て取得する方法を見てみましょう.
letcitiesRef=db.collection('cities');letallCities=citiesRef.get().then(snapshot=>{snapshot.forEach(doc=>{console.log(doc.id,'=>',doc.data());});}).catch(err=>{console.log('Error getting documents',err);});このように書いてますね.
ちなみに,公式ドキュメントでは既にdbが定義されていますが,これはここでいうfirebase.firestore()だと思って大丈夫です.
どうやら,
this.tableDatabase.get()で全てのコレクションが取得でき,それらに対してforEachを回してあげれば良さそうです.
ところで,公式のドキュメントには,snapshotとかいうのが使われていますね.これは,その関数を実行した時点でのデータが格納されているようです.
さらに.docにはそれぞれのドキュメントのデータが格納され,doc.data()でそのドキュメントに格納されているフィールドが取得できそうです.
というわけで,このようなmethodがかけそうです.
methods:{listenData:function(){returnnewPromise(resolve=>{resolve(this.tableDatabase.get().then(snapshot=>{snapshot.forEach(doc=>{this.profileItems.push(doc.data())})}))})}}これで,listenData()を実行するとそれぞれのドキュメントがprofileItemsに格納されます.listenData()は,ページの読み込み時に一回だけ実行されて欲しいので,
created(){this.listenData()}としましょう.
従って,<script>部は,以下のようになります.
<script>importProfileItemfrom'../components/ProfileItem.vue'importfirebasefrom'../firebase.js'exportdefault{components:{ProfileItem},data(){return{profileItems:[]}},computed:{tableDatabase:()=>firebase.firestore().collection('profileitems')},methods:{listenData:function(){returnnewPromise(resolve=>{resolve(this.tableDatabase.get().then(snapshot=>{snapshot.forEach(doc=>{this.profileItems.push(doc.data())})}))})}},created(){this.listenData()}}</script>これで,
npm run serve
をしてhttp://localhost:8080/にアクセスすると,先ほどFirestoreに登録したデータが表示されるはずです.
これで今回の作業はほとんど完成ですが,あとは先ほどのfirebase.jsをリファクタリングします.
firebase.jsって公開されてもいいの?
最初はfirebase.jsってapiKeyとか含んでるのにパブリックなrepositoryで管理するのはまずいと思い,travisCIに環境変数として登録しておいて,デプロイ時に展開されるようにしてました.
でもよく考えるとどうせgithub pagesにアクセスするときに晒されるじゃんって思ったり.そもそも公式ではhtmlにべたがきするように指示してあったり...
どうすべきか悩んでいたら
Firebase apiKey ってさらしていいの? ほんとに?
を見つけました.
一応問題ないみたいですね.
終わりに
今回の最終的なソースコードはこちら
