Firebaseでリアルタイムチャットを構築する


##完成物
今回はwebサービスのFirebaseを使い、サクッとリアルタイムチャットを作ります。
![chat-1.gif](https://qiita-image-store.s3.amazonaws.com/0/88163/aa6b75df-119d-6825-f8aa-c56b79f0f625.gif "chat-1.gif")

##Firebaseとは
Firebaseは、チャットなど端末同志のやり取りにリアルタイム性を持たせたい時によく使われるアプリケーションのバックエンドサービスです。
端末とサーバー間、端末同士でのデータ同期などのバックエンドで行う処理をAPI提供をしています。



##Firebaseに登録する
FirebaseのWEBサイトにアクセスして会員登録を行います。
https://www.firebase.com/login/

![スクリーンショット 2015-11-30 6.09.46.png](https://qiita-image-store.s3.amazonaws.com/0/88163/8bc8e77b-1e74-69d6-7a26-5f01ee16aa25.png "スクリーンショット 2015-11-30 6.09.46.png")



##アプリケーションを登録する
ログインが完了したらこちらから新規アプリケーションを作成します。

![スクリーンショット 2015-11-30 6.10.51.png](https://qiita-image-store.s3.amazonaws.com/0/88163/ab20cd9d-93f9-c6c3-5069-b7cb46a1e3d5.png "スクリーンショット 2015-11-30 6.10.51.png")

APP NAMEをクリックすると以下の様なページに行き、データベースの中身を見たり様々な設定をすることが出来ます。

![スクリーンショット 2015-11-30 6.14.00.png](https://qiita-image-store.s3.amazonaws.com/0/88163/5ef873f7-398f-0046-4902-cb74c5f98292.png "スクリーンショット 2015-11-30 6.14.00.png")



##クライアントサイドの作成

###Firebaseライブラリを読み込む


```
<script src="https://cdn.firebase.com/js/client/2.3.2/firebase.js"></script>
```

###データベースと接続する

＜YOUR-FIREBASE-APP＞を自分が作成したアプリケーション名ｊに変更します。

```javascript
var myFirebaseRef = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com/");
```

###データ保存
データベースに対して、push関数でデータを保存します。

```javascript
myFirebaseRef.child('messages').push({
  'message': 'こんにちは'
});
```

###データの取得
データベースに何らかのデータ変更があった場合にリアルタイムにコールバック関数が実行されます。

```javascript
myFirebaseRef.on('child_added', function(dataSnapshot) {
  //データベースに変更があった場合のコールバック処理
});
```

##ソースコード
```html
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <script src="https://cdn.firebase.com/js/client/2.3.2/firebase.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
    <link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
    <div class="panel-default">
        <div class="panel-heading">
            <p>リアルタイムチャットサンプル</p>
        </div>
        <div id="scroller" class="panel-body">
            <ul id='messages'>
            </ul>
        </div>
        <div class="panel-footer">
            <input type='text' class="form-control" id="nameInput" placeholder="ユーザー名を入力してください">
        </div>
        <div class="panel-footer">
            <input type='text' class="form-control" id="messageInput" placeholder="メッセージ内容を入力してください">
        </div>
    </div>
</body>
    <script src="chat.js"></script>
</html>

```
```css
ul,li{
    padding: 0;
    margin: 0;
    list-style-type: none;
	text-align: left;
}
#scroller {
    height: 500px;
    overflow: auto;
}

/*******************************
* 左からの吹き出し
********************************/
.left_balloon {
    position: relative;
    background: #f1f0f0;
    border: 0px solid #777;
    margin: 5px 10px;
    padding: 5px 10px;
    border-radius: 15px;
    width: 400px;
    clear: both;
}

/*******************************
* 右からの吹き出し
********************************/
.right_balloon {
    color: #fff;
    position: relative;
    background: #0084ff;
    border: 0px solid #777;
    margin: 5px 10px;
    padding: 5px 10px;
    border-radius: 15px;
    width: 400px;
    clear: both;
    float: right;
}

/*******************************
* 割り込みを解除
********************************/
.clear_balloon{
  clear: both;
}



.sender_name{
    margin-bottom: -5px;
    padding-left: 20px;
    color: rgba(0, 0, 0, .40);
}
.sender_name.me{
    float: right;
    padding: 0 20px 0 0;
}

```
```javascript
// データベースと接続する
var messagesRef = new Firebase('https://qiita.firebaseio.com/');

var messageField = $('#messageInput');
var nameField = $('#nameInput');
var messageList = $('#messages');

// ENTERキーを押した時に発動する
messageField.keypress(function (e) {
    if (e.keyCode == 13) {
        //フォームに入力された情報
        var username = nameField.val();
        var message = messageField.val();

        //データベースに保存する
        messagesRef.push({name:username, text:message});
        messageField.val('');

        $('#scroller').scrollTop($('#messages').height());
    }
});

// データベースにデータが追加されたときに発動する
messagesRef.limitToLast(10).on('child_added', function (snapshot) {
    //取得したデータ
    var data = snapshot.val();
    var username = data.name || "anonymous";
    var message = data.text;

    //取得したデータの名前が自分の名前なら右側に吹き出しを出す
    if ( username == nameField.val() ) {

        var messageElement = $("<il><p class='sender_name me'>" + username + "</p><p class='right_balloon'>" + message + "</p><p class='clear_balloon'></p></il>");

    } else {

        var messageElement = $("<il><p class='sender_name'>" + username + "</p><p class='left_balloon'>" + message + "</p><p class='clear_balloon'></p></il>");

    }
    //HTMLに取得したデータを追加する
    messageList.append(messageElement)

    //一番下にスクロールする
    messageList[0].scrollTop = messageList[0].scrollHeight;
});

```

以下が作成したチャットになります。
一番右のダッシュボードを見るとリアルタイムにデータの追加がされているのが分かります。

![chat-1.gif](https://qiita-image-store.s3.amazonaws.com/0/88163/aa6b75df-119d-6825-f8aa-c56b79f0f625.gif "chat-1.gif")


##さいごに
今回は一番シンプルなものを作りましたが、いずれはサーバーサイドの言語を使ってユーザー認証を付けたものを作りたいと思います。
この記事の内容に間違いや質問があればコメントをしていただけたらと思います！