React.js + firebaseでリアルタイムチャットアプリ作った。

f:id:anoChick:20161211183939p:plain

https://nekojima.anochick.com

でーきた。 特徴としては↓

  • リアルタイムチャット(勝手に更新が反映される)
  • チャンネルの作成が自由にできる。
  • 無限にふぁぼれる
  • 完全匿名

です。

f:id:anoChick:20161211190537g:plain

ふぁぼり放題です。

作り方の解説

anoninoni.hateblo.jp

こっちでも雑に書いてはいたんですが、もうちょっと丁寧に記述します。

react-boilerplateを使う。

github.com 開発環境を整えるのが大変なので、ボイラープレートを使いました。 詳細はリンク先みていただくとわかるかと思うんですが、

  • React.js
  • Redux
  • ES6
  • webpack
  • ServiceWorker
  • Mocha
  • enzyme
  • eslint
  • CLI

などなど、モダンなフロントエンド開発に使うものがいっぱい入ってます。

ただ、Angularと比べると非公式なものなので、結構バギー。 私の場合webpackのcss生成の記述がおかしくなってて手動で対応したりしてました。 あとeslintがめちゃめちゃ厳しいです... サンプルプログラムの時点で結構eslint:disabledの記述があったので、付き合い方が難しそう。

Material UIを使う

www.material-ui.com

UIframeworkをなににしようか悩んだんですが、やっぱり王道のMaterial-UIにしました。理由としては

  • バイルフレンドリーに書きやすい
  • 今回作るものがシンプル
  • よく使われているから安心

という感じです。

グリッドシステムも特に使わず、できるだけ純粋なMaterial-UIで書きました。

firebaseのリアルタイムDBを使う(reactfire)

これを使ってみたくてこのチャットを作り始めたみたいなところあります。 "データベース"のくせにリアルタイム更新と、プッシュ機能も持ってるのですごいです。

チャンネル内の情報なんかは

const ref = firebase.database().ref('channels/default');
this.bindAsArray(ref, 'channel');

と記述するだけで、そのコンポーネントのstate.channelにバインドされます。 バインドされた状態のstateにsetState()で変更を加えるだけで、DBに更新が走り、 バインドしている全クライアントに対してプッシュされます。 すごい!

普通にjavascriptで使う場合は

  firebase.database().ref('channels/default').on('eventname', function(snapshot) {
    var mes = $('<span>',{class:'message'}).text(snapshot.val().message);
    $('#message-box').append(mes);
  });

のような記述で動きます。

ちなみに、このリアルタイムDBはユーザ認証を用いたパーミッション機能があるのですが、 今回は認証なしで動いているため、誰でも自由に書き換えができます

一応サニタイズは行われるぽいのですが、バリデーションのかけようがないのが気になってる。

雑感(やってみて)

  • やっぱりSPAは夢があって楽しい
  • サーバ側はどうしようかもうちょっと考えたい
    • GraphQLとかちょっと手を出してみる予定
  • firebaseDB面白いけど使う場面がかなり限られる
  • とはいえfirebaseのホスティングhttpsカスタムドメイン対応しているのですごく良い!

あとServiceWorkerについてなんですが、キャッシュとしての効力が強すぎるのと、扱い方が難しそうだったのでオフにしてます。また別途勉強したい。