Firebase 入門 - Cloud Messagingを使ってみる。

Firebaseの Cloud Messaging を試してみます。
# Cloud Messaging
Firebase Cloud Messaging(FCM)は メッセージを配信するソリューションです。
iOSアプリやAndroidアプリの場合はプッシュ通知を実装する場合に利用できます。Web Push対応したChrome等のブラウザがインストールさてれいればサイトからのプッシュ通知としても実装する事ができます。<br>今回は Web Push を試してみることにしました。

1. ブラウザで firebase console を開く <br>
https://console.firebase.google.com/?hl=ja
1. 左上にあるプロジェクト名の隣の歯車アイコンを押して プロジェクトの設定を開きます。<br>![スクリーンショット 2017-03-13 20.40.24.png](https://qiita-image-store.s3.amazonaws.com/0/100147/5d0e3cad-6963-6b51-ed20-328c7d19dcfe.png)
1. クラウドメッセージングタブを選択して、送信者IDを確認してください。あとで FCM送信者ID として使用するので覚えておきます。<br>![スクリーンショット 2017-03-13 20.42.19.png](https://qiita-image-store.s3.amazonaws.com/0/100147/8b6662ca-e6e9-8cc5-ab42-92e474edcced.png)

1. 適当なプロジェクトディレクトリを作って初期化する
    
    ```
    mkdir web-push-sample 
    firebase init
    ```
1. 今回はサンプルなので Hosting を選び、2で作成したプロジェクトを選択する 
残りの選択は全て Yes で。```firebase.json``` や ```public``` ディレクトリが作成される。
1. publicディレクトリに images ディレクトリを作り icon.png を追加する。
![icon.png](https://qiita-image-store.s3.amazonaws.com/0/100147/74ccd561-7841-8531-9e52-b2ee38baf886.png)<br> icon.png 

1. Service Workerを追加する。<br> publicディレクトリに ```firebase-messaging-sw.js```というファイル名で下記のコードのファイルを作る。※FCMを利用する場合ファイル名 ```firebase-messaging-sw.js``` 固定のようです。
    
    ```javascript:firebase-messaging-sw.js
    importScripts('https://www.gstatic.com/firebasejs/3.7.0/firebase-app.js');
    importScripts('https://www.gstatic.com/firebasejs/3.7.0/firebase-messaging.js');

    firebase.initializeApp({
        'messagingSenderId': 'YOUR-SENDER-ID'
    });

    const messaging = firebase.messaging();
    messaging.setBackgroundMessageHandler(function(payload) {
      console.log('[firebase-messaging-sw.js] Received background message ', payload);
      // Customize notification here
      const notificationTitle = payload.notification.title;
      const notificationOptions = {
          body: payload.notification.body,
          icon: payload.notification.icon
        };
      return self.registration.showNotification(notificationTitle,notificationOptions);
    });
    ```

1. 3で確認した送信者IDを ``` 'messagingSenderId': 'YOUR-SENDER-ID' `` にコピーして書き換える。
1. publicディレクトリに ```manifest.json``` を作成する。※FCMを利用する場合この値 ``` 103953800507 ``` 固定のようです。
    
    ```
    {
        "gcm_sender_id": "103953800507"
    }
    ```

1. index.htmlに manifest.json を指定するメタタグを追加する
    
    ```
    <link rel="manifest" href="/manifest.json">
    ```

1. WebPush取得処理を開始するための ボタンとユーザー毎のトークンを表示する欄をindex.htmlに追加する。
    
    ```
    <input type="button" id="btnWebPush" value="WebPush権限を取得">
    <br>
    <input type="text" value="YOUR-IID-TOKEN" id="txtIIToken" style="width:80%;">
   ```

1. index.html に FCMを利用するための javascript を追加する。
    
    ```
    const messaging = firebase.messaging();
    messaging.onMessage(function(payload) {
      console.log("Message received. ", payload);
      alert(payload.notification.title+"\r\n"
            +payload.notification.body+"\r\n"
            +payload.notification.icon);
    });

    //プッシュ通知パーミッション取得
    var requestPermission = function () {
      messaging.requestPermission()
      .then(function() {
        //ユーザー毎のトークンを取得して画面に表示する
        messaging.getToken()
        .then(function(token) {
          console.log('Token refreshed.');
          console.log("token "+token);
          document.getElementById("txtIIToken").value = token;
        })
        .catch(function(err) {
          console.log('Unable to retrieve refreshed token ', err);
        });
      })
      .catch(function(err) {
        console.log('Unable to get permission to notify.', err);
      });
    }
    window.onload = function() {
      //パーミッションを取得するボタンクリック時
      document.getElementById("btnWebPush").onclick = requestPermission;
    };
    ```
1. ローカル環境で実行して内容を確認してみる<br>```firebase serve```<br>表示される URLをブラウザで開く
http://localhost:5000

1. WebPush権限を取得ボタンをクリックしてユーザートークンを取得する。<br>トークン取得に成功すれば ```YOUR-IID-TOKEN``` 欄に表示されます。 
 
ここまでの実装でFCMの利用準備ができました。続いてコマンドラインからメッセージを送ってみます。

# コマンドラインからメッセージ送信
1. メッセージは下記のコマンドで送信することができます。
    
    ```
    curl -X POST -H "Authorization: key=YOUR-SERVER-KEY" -H "Content-Type: application/json" -d '{
   "notification": {
     "title": "タイトル",
     "body": "本文",
     "icon": "/images/icon.png",
     "click_action": "http://localhost:5000"
   },
   "to": "YOUR-IID-TOKEN"
   }' "https://fcm.googleapis.com/fcm/send"
    ```
1. ```YOUR-SERVER-KEY``` は 上の欄3のfirebase consoleで確認した サーバーキーをコピーします。
1. WebPush権限を取得ボタンをクリックして取得した ```YOUR-IID-TOKEN``` を YOUR-IID-TOKEN 欄にコピーする

1. ターミナルを開いて実行してみる。成功すれば下のようなレスポンスが表示される。<br>* "success":1 があれば成功している。
    
    ```
    {
      "multicast_id":12345678...,
      "success":1,
      "failure":0,
      "canonical_ids":0,
      "results":[{"message_id":"0:1234567890%abcdfeg123456"}]
    }
    ```

1. ローカル実行で開いていたタブを閉じた状態で上のコマンドを実行すると ブラウザプッシュ通知が表示される。<br>![スクリーンショット 2017-03-14 17.50.42.png](https://qiita-image-store.s3.amazonaws.com/0/100147/4a1c2ffc-9871-8750-e9b4-3bab72130cf4.png)

とても簡単にWebPushを実装する事ができました。
本来はService Workerの知識やGCM(Google Cloud Messaging)の知識が必要で難しいのですが、Firebaseのjavascriptライブラリのおかげで簡単に実装できるようです。

#おまけ
特定のURLに定期的にアクセスしてくれる Cronサービス[My Web Cron Service](http://mywebcron.com/) を使ってFCMを実行する方法

1. fcm_send.html 等の名前で javascript から FCMにメッセージをPOSTするｈｔｍを作る。
   
    ```
$(function(){
      console.log("onload");
      //FCMへPOSTする
      const options = {
        url:'https://fcm.googleapis.com/fcm/send',
        type:"POST",
        headers:{
          "Authorization":"key="+SERVER_KEY,
          "Content-Type":"application/json"
        },
        contentType: 'application/json',
        dataType: "json",
        data:JSON.stringify({
          notification: {
            title: "タイトル",
            body: "本文",
            icon: "/images/icon.png",
            click_action: "http://localhost:5000"
          },
          to: YOUR_IID_TOKEN
        }),
        success:function(json) {
          console.log("success");
          console.log(json);
        },
        error: function() {},
        complete: function() {}
      };
      $.ajax(options);
    });
    ```

1. firebaseホスティングにdeployして サーバ上の fcm_send.html のURLを覚える<br>https://xxxxxxx.firebaseapp.com/fcm_send.html

1. fcm_send.htmlのURLを [My Web Cron Service](http://mywebcron.com/) に登録する
![スクリーンショット 2017-04-07 13.21.41.png](https://qiita-image-store.s3.amazonaws.com/0/100147/26860c8b-0b77-df5b-0de9-d93cbbb87bfc.png)

1. 指定時間毎にWebPushが実行される。
 
# 参考
[JavaScript クライアントでメッセージを受信する](https://firebase.google.com/docs/cloud-messaging/js/receive)
[クイックスタートサンプル](https://github.com/firebase/quickstart-js/tree/master/messaging)