Web Developer's Struggle Memories

日々の業務から思ったこと、学んだことを書き連ねていきます。

Riot.js + Firebaseで簡単なチャットアプリを作ってみた

リアルタイムでのデータ同期が特徴のバックエンドサービスFirebaseを利用してみたく、 ちょうどRiot.jsを使ってアプリも作ってみたかったので、勢いでチャットアプリを作ってみた。

今回はトランスコンパイルではなくプリコンパイルしてるので、.tagファイルを読み込むのではなく、 コンパイル後の.jsファイルを読み込む。作成したデモサイトはこちら。 ソースもGithubに上げているので、参考になれば。

ログイン認証や投稿者名などもなく、ただテキストを入力・送信・表示するような簡単なもの。Riot.js特有の落とし穴に何度かハマったが、 これはこれで勉強になった。

Firebaseの用意

Firebaseのホームページにてアカウントを作成。
作成後は以下のURLをコピー。

f:id:kito0039:20160202171114p:plain

ソースコード

今回はFirebaseの使い方については割愛。
まずはhtmlファイル。

index.html

<!DOCTYPE html>
<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <title>Riot Chat</title>
   </head>
   <body>
      <app></app>
      <!-- riot.js part -->
      <script src="//cdn.jsdelivr.net/riot/2.3/riot.min.js"></script>
      <script src="./js/chat.js"></script>
      <!-- firebase part-->
      <script src="https://cdn.firebase.com/js/client/2.1.1/firebase.js"></script>
      <script>
      var messages = [];
      var obj_fire = new Firebase("https://sweltering-inferno-××××.firebaseio.com");

      // get messages
      obj_fire.child('messages').on('child_added', function(data_snapshot) {
         data_snapshot.forEach(function(obj) {
            messages.push({'message': obj.val()});
         });
         riot.update();
      });

      // delayed process for message requesting
      delay = window.setTimeout(function() {
        riot.mount('app',{
          title: 'Riot chat',
          items: messages,
          data_store: obj_fire
        });
      }, 1000);
      </script>
   </body>
</html>

先ほどコピーしたURLをnew Firebase("URL")のURL部分に記述する。基本的にFirebaseの処理部分はhtml内で行う。 まだデザインBootstrap雨を使って簡単にデザインを当てた。 上記で遅延処理をしているのは、最初の画面表示の際にデータを取得するのに若干のタイムラグがあったため。 (何か良い方法ご存知の方、情報をご提供いただけますと幸いです!)

続いてタグファイル。

chat.tag

<app>
   <h3>{ opts.title }</h3>
   <form name="form_message" onSubmit={ send } >
      <p>Please enter the text box</p>
      <input type="text" name="input_message" onkeyup={ input }>
      <input disabled={ !text } type="submit" value="Send Message">
   </form>
   <ul>
      <li each="{ items }"><label>{ message }</label></li>
   </ul>


   <!-- javascript part -->
   this.text = "";
   this.disabled = true;
   this.items = opts.items;

   // input text-box check
   input(e) {
      this.text = e.target.value;
   }

   // add message
   send(e) {
      opts.data_store.child('messages').push({'messages': this.text});

      this.text = '';
      document.form_message.input_message.value = '';
   }
</app>

公式サイトのtodoアプリとほとんどソースは変わらないかと。ただ、formからメッセージを送信するところで、 Firebaseに登録する処理をしなければ成らないため、htmlからインスタンスdata_storeという名前でマウントし、opts変数で受け取っている。

感想

Firebaseはかなり使い勝手が良く、DBも不要なためこれから結構使いそう。ユーザ認証の機能やバリデーションの機能、Analyticsも備わっており、 またデータもjson形式でやり取りできるのでホンマに扱いやすい。もちろん無料枠では制限内での利用になるが、 十分過ぎるほど機能があるのでオススメ。

Riot.js使って初めて何かを作ったが、外部ファイルを読み込んだりするとコンパイルできないので、ちょっと工夫が必要だった。 また、riot.updateメソッドを呼ばないと、リアルタイムにデータを同期してくれないので注意。クセはあるが分かりやすいのでまだ使ってみたい。

では。