cordovaでFirebase Cloud Messagingを使ってみる。 #1

# 0. 前段
2016年のGoogle I/Oで、大幅にFirebaseのアップデートが発表されました。
その中でも、注目度の高かったFirebase Notifications。
多くの人が

「これでPush通知が自在に送れる！」

と思ったわけですが、Firebase Notifications自体は、GUIからPush通知を送るための機能でした。

しかしこのFirebase Notificationsは今回、Google Cloud MessagingからFirebase Cloud Messagingと名前を変えたサービスを利用したツールのため、このFirebase Cloud Messagingを使ってPush通知が送れます。

今回は、その中でもCordovaを利用してiOSアプリでFirebase Cloud MessagingのPush通知が送れるか試して見たいと思います。

※この記事は、2016年6月18日に行われた[GCPUG仙台のイベント](http://connpass.com/event/34119/)での個別ワークとして実際にやってみたことを書いています。

# 1. Cordovaのアプリビルド

いつものように、プロジェクトディレクトリで

```bash
cordova create notification
```

# 2. アプリの登録
<img width="1150" alt="Screen Shot 2016-06-18 at 2.53.09 PM.png" src="https://qiita-image-store.s3.amazonaws.com/0/103745/68cd5126-0e3e-8b41-e3a5-8e2614cd312b.png">

iOSのアプリをDev Centerで登録します。
その時に"Push Notification"にチェックを入れるのを忘れずに。

# 3. プラグインのインストール
今回使うプラグインはこちら。
[cordova-plugin-fcm](https://www.npmjs.com/package/cordova-plugin-fcm)

プラグインをインストールします。

```bash
cd notification
cordova plugin add cordova-plugin-fcm
```

ただこのプラグインは、CordovaのiOSのバージョンが4.0.0以上だとエラーが出るようで、ドキュメントにはバージョンを下げろと書かれています。

```bash
cordova platform add ios@3.9.2
```

#4 Cordovaのconfig.xmlを編集しておきます
```xml
<?xml version='1.0' encoding='utf-8'?>
<widget id="io.thedott.notification" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
    <name>notification</name>
    <description>
        Firebase Cloud Messagingのサンプル
    </description>
    <author email="shimizu@thedott.io" href="http://thedott.io">
        :.shimizu
    </author>
    <content src="index.html" />
    <plugin name="cordova-plugin-whitelist" spec="1" />
    <access origin="*" />
    <allow-intent href="http://*/*" />
    <allow-intent href="https://*/*" />
    <allow-intent href="tel:*" />
    <allow-intent href="sms:*" />
    <allow-intent href="mailto:*" />
    <allow-intent href="geo:*" />
    <platform name="android">
        <allow-intent href="market:*" />
    </platform>
    <platform name="ios">
        <allow-intent href="itms:*" />
        <allow-intent href="itms-apps:*" />
    </platform>

    <preference name="BackupWebStorage" value="local"/>
</widget>
```

で、Cordovaをbuild

```bash
cordova build
```

xcodeを立ち上げると、ビルドは通ってます。

#5 Firebase側にiOSアプリに登録する
<img width="892" alt="Screen Shot 2016-06-18 at 3.11.18 PM.png" src="https://qiita-image-store.s3.amazonaws.com/0/103745/e145306f-bfe3-f8fb-3ee2-a4ef63d649ba.png">

#6 iOSアプリにFirebaseを追加する
<img width="834" alt="Screen Shot 2016-06-18 at 3.12.22 PM.png" src="https://qiita-image-store.s3.amazonaws.com/0/103745/887fb8d3-69a1-15cc-f7ac-3cde85981260.png">

Cordovaの場合は、root folderに置けと言われているのでダウンロードしてきたGoogleService-Info.plistをxCodeからプロジェクト直下にドラッグドロップしてコピーします。

[2017.1.15 追記]
久しぶりに試したところ、cordova-plugin-fcmでは、cordovaのプロジェクトのrootフォルダーに、上記のplistを置くようにエラーがでてしまったので、正しくは、rootフォルダーに置くようにしてみてください。

#7 受け取る側の準備
```js
var app = {
    // Application Constructor
    initialize: function() {
        this.bindEvents();
    },
    // Bind Event Listeners
    //
    // Bind any events that are required on startup. Common events are:
    // 'load', 'deviceready', 'offline', and 'online'.
    bindEvents: function() {
        document.addEventListener('deviceready', this.onDeviceReady, false);
    },
    // deviceready Event Handler
    //
    // The scope of 'this' is the event. In order to call the 'receivedEvent'
    // function, we must explicitly call 'app.receivedEvent(...);'
    onDeviceReady: function() {
        app.receivedEvent('deviceready');
        FCMPlugin.onNotification(
          function(data){
            setTimeout(function(){
                alert(data.notification.body);
            }, 100);
            console.log('data');
          },
          function(data){
            console.log('succsess');
          },
          function(data){
            console.log('error');
          }
        );
    },
    // Update DOM on a Received Event
    receivedEvent: function(id) {
        var parentElement = document.getElementById(id);
        var listeningElement = parentElement.querySelector('.listening');
        var receivedElement = parentElement.querySelector('.received');

        listeningElement.setAttribute('style', 'display:none;');
        receivedElement.setAttribute('style', 'display:block;');

        console.log('Received Event: ' + id);
    }
};

app.initialize();
```

cordovaが生成したindex.jsのonDeviceReadyのところに、追加しました。

```js
    onDeviceReady: function() {
        app.receivedEvent('deviceready');
        FCMPlugin.onNotification(
          function(data){
            setTimeout(function(){
                alert(data.notification.body);
            }, 100);
            console.log('data');
          },
          function(data){
            console.log('succsess');
          },
          function(data){
            console.log('error');
          }
        );
    },
```

これでAlertだけですが、メッセージを受け取る準備ができました。

#8 時間がなくなったので、アラートだけでもNotificationsからテストしよう。

<img width="763" alt="Screen Shot 2016-06-18 at 4.27.49 PM.png" src="https://qiita-image-store.s3.amazonaws.com/0/103745/57521632-0745-8398-24e8-6cadb8472db7.png">

これで送信すると…

<img width="375" alt="S__8233047.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/103745/dacb51d7-90ae-6ec9-e735-f8dd187ce693.jpeg">

とりあえず、Notificationsから、Cordovaでもメッセージを受け取ることができました。

[#2へ続く](http://qiita.com/donuzium/items/05754109e817159ea767)