トポロジ・ラボ(研究開発部)です。
今回はCloud Firestore(Firebase)とVue.jsを利用して1時間でチャットサービスを作ろうで説明しなかったコードの詳細についての解説編となります。デザインはBootstrapを使って簡単に整えていますが、その部分に関しては省略させていただきます。
以下が前回作成したコードになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Chat Service</title> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css" integrity="sha384-Smlep5jCw/wG7hdkwQ/Z5nLIefveQRIY9nfy6xoR1uRYBtpZgI6339F5dgvm/e9B" crossorigin="anonymous"> </head> <body> <div id="app" class="container"> 名前: <input type="text" class="form-control" style="width:250px" v-model="name"> 内容: <input type="text" class="form-control" style="width:400px" v-model="content"><br> <button class="btn btn-primary" @click="send">送信</button> <p v-for="(message, index) in sorted_messages" :key="index">{{message.name}} > {{message.content}}</p> </div> <script defer src="/__/firebase/5.3.0/firebase-app.js"></script> <script defer src="/__/firebase/5.3.0/firebase-firestore.js"></script> <script defer src="/__/firebase/init.js"></script> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/js/bootstrap.min.js" integrity="sha384-o+RDsa0aLu++PJvFqy8fFScvbHFLtbvScb8AjopnFD+iEQ7wo/CG0xlczd+2O/em" crossorigin="anonymous"></script> <script src="https://Vuejs.org/js/Vue.js" charset="utf-8"></script> <script src="https://unpkg.com/vue-firestore"></script> <script> document.addEventListener('DOMContentLoaded', function() { var db = firebase.firestore(); db.settings({ timestampsInSnapshots: true }); var app = new Vue({ el: '#app', data: { name:"", content:"" }, firestore: { messages: db.collection("messages"), }, methods: { send:function() { date = new Date() var message = { name: this.name, content: this.content, timestamp: "" + date.getFullYear() + ("0"+date.getMonth()+1).slice(-2) + ("0"+date.getDate()).slice(-2) + ("0"+date.getHours()).slice(-2) + ("0"+date.getMinutes()).slice(-2) + ("0"+date.getSeconds()).slice(-2) }; this.$firestore.messages.add(message); this.content = "" }, }, computed: { sorted_messages () { const list = this.messages.slice() list.sort((a, b) => { a = a["timestamp"] b = b["timestamp"] return a === b ? 0 : a > b ? -1 : 1 }); return list } }, }) }) </script> </body> </html> |
解説では適宜コード内にコメントを追加して説明します。
HTMLの表示部分
1 2 3 4 5 6 7 8 9 10 11 |
<div id="app" class="container"> <!-- 入力欄 --> 名前: <input type="text" class="form-control" style="width:250px" v-model="name"> 内容: <input type="text" class="form-control" style="width:400px" v-model="content"><br> <!-- 送信ボタン --> <button class="btn btn-primary" @click="send">送信</button> <!-- 送信済みメッセージリスト --> <p v-for="(message, index) in sorted_messages" :key="index">{{message.name}} > {{message.content}}</p> </div> |
HTMLの表示部分は名前と内容の入力欄、送信ボタン、送信済みメッセージリストの3つで構成されています。
入力欄ではVue.jsのv-modelを使うことで双方向データバインディングを作成しています。双方向データバインディングを使うことで入力された値をscript内のVueインスタンスのdataオブジェクトとして簡単に扱うことができ、逆にscript内でdataオブジェクトに変更した場合も簡単に表示に反映させることができます。
送信ボタンの @click="send" はVue.jsのメソッドイベントハンドラになっています。クリックされたときにVueインスタンスのsendメソッドを実行しろという簡単な記述になっています。
最後に送信済みメッセージのリスト表示部分です。
ライブラリ読み込み部分
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<!-- Firebaseのライブラリ読み込みと初期化 --> <script defer src="/__/firebase/5.3.0/firebase-app.js"></script> <script defer src="/__/firebase/5.3.0/firebase-firestore.js"></script> <script defer src="/__/firebase/init.js"></script> <!-- bootstrapに関するライブラリ --> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/js/bootstrap.min.js" integrity="sha384-o+RDsa0aLu++PJvFqy8fFScvbHFLtbvScb8AjopnFD+iEQ7wo/CG0xlczd+2O/em" crossorigin="anonymous"></script> <!-- Vue.jsとVuejs,Firebaseを連携するライブラリの読み込み --> <script src="https://Vuejs.org/js/Vue.js" charset="utf-8"></script> <script src="https://unpkg.com/vue-firestore"></script> |
Cloud Firebaseのライブラリ読み込み時に、Firebase Hostingを使う場合はコードにあるように”/__”ではじまる予約済みのURLを使用して読み込みと初期化ができます。こうすることで、Hostingしたプロジェクトの設定に合わせて簡単に初期化することができます。(Firebase Hostingを使わず、独自のサーバーを利用する場合は自分で初期化の処理を書かなければいけません。)
また、Vue.jsの基本的なライブラリと次に説明するVue.jsとCloud Firestoreを自然に連携できるようになるvue-firestoreを読み込んでいます。
Vueインスタンス部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
var app = new Vue({ el: '#app', // 入力欄 data: { name:"", content:"" }, // Firestoreのデータ firestore: { messages: db.collection("messages"), }, // 送信ボタンのメソッド methods: { send:function() { date = new Date() // 入力欄の値にタイムスタンプを追加してFirestoreに追加 var message = { name: this.name, content: this.content, timestamp: "" + date.getFullYear() + ("0"+date.getMonth()+1).slice(-2) + ("0"+date.getDate()).slice(-2) + ("0"+date.getHours()).slice(-2) + ("0"+date.getMinutes()).slice(-2) + ("0"+date.getSeconds()).slice(-2) }; this.$firestore.messages.add(message) this.content = "" }, }, // 送信済みメッセージを送信時刻順に並び替え(算出プロパティ) computed: { sorted_messages () { const list = this.messages.slice() list.sort((a, b) => { a = a["timestamp"] b = b["timestamp"] return a === b ? 0 : a > b ? -1 : 1 }); return list } }, }) |
vue-firestoreを使うことで、Vueインスタンスのdataオブジェクトのように、Cloud Firestoreのデータも扱えるようになります。上記のコードのように宣言方法もほとんど同じです。
Cloud Firestoreへのデータ追加方法は送信ボタンのメソッド内にある this.$firestore.messages.add(message) この部分で、簡単に追加することができます。Cloud Firestoreの読み込み方法はVueインスタンスのdataと全く同じように扱えます。実際に送信済みメッセージを時刻順に並べ替えている部分 const list = this.messages.slice() のようにdataと同様に利用できます。
まとめ
Cloud FirestoreとVue.jsを使うことで、今までは実装が大変だった異なるデバイス間のデータの同期の仕組みや、そのための実装が簡単に行えることがわかりました。今回はFirebaseのサービスの内、Cloud Firestoreの他にHostingも使いましたが、それ以外にもウェブアプリやスマートフォンアプリ開発のために便利なサービスが沢山あります。これを機にFirebaseやVue.jsを使って開発をしてみようと思って頂ければ幸いです。