Android
iOS
Push通知
monaca
BaaS@rakuza

Monaca×BaaS@rakuzaでプッシュ通知してみた

More than 1 year has passed since last update.

前の記事で作成したお知らせをPush通知するアプリを作ってみます。

Push通知のイメージ図

Push通知は以下のイメージで構成されています。デバイストークンを、iOSはAPNs(AppleのPush通知サーバ)、AndroidはGCM/FCM(GoogleのPush通知サーバー)より取得して、BaaS@rakuzaに保存します。BaaS@rakuzaは宛先となるデバイストークンとメッセージをAPNs/GCM/FCMに送り、デバイスにPush通知が届きます。

スクリーンショット 2017-03-21 23.08.36.png

必要なもの

  • Mac(できれば)
    • 必須ではないですが、iOSの証明書の作成はMacの方が楽です。
  • iPhone実機
  • Android実機(エミュレータでもたぶんOK)
  • Apple Developer Program
    • 証明書などの作成で必要です。有料
  • Googleアカウント
    • Google Developer Console用。APIキーの作成に必要です。
  • Monacaアカウント(Goldプラン以上)
  • BaaS@rakuzaのアカウント(無料体験版でもOK!)

1. iOSの設定

証明書などの作成

イメージ図の「①デバイストークン取得」、「④プッシュ通知」に必要な、証明書などを作成/登録します。以下、作成/登録が必要な項目です。

  1. CSRの作成
  2. ビルド用証明書の作成
  3. AppIDの作成
  4. 端末の登録
  5. プロビジョニングプロファイルの作成

1〜5については、Monacaさんの公式ページが詳しいので、こちらを参照します。ステップ1〜2まで行えばOKです。ただし、一部については以下に読み替えて進めます。

  • 証明書は「配布用証明書」を作成します。
    • BaaS@rakuzaはPush通知をAPNsの実稼働用サーバ(api.push.apple.com:443)に送信します。そのため、アプリ証明書および後述するPush通知証明書も配布用証明書が必要になります。
  • AppIDの登録は「Explicit App ID」で行います。
  • AppIDの「App Services」→「Push Notifications」にチェックをします。
  • Provisioning Profilesは「Ad Hoc」を選択します。
    • こちらも配布用にします。リリースするわけではないので、「Ad Hoc」(評価用)でOKです。

Push通知証明書作成

BaaS@rakuzaからAPNsにPush通知を送信する際に必要となる証明書を作成します。(イメージ図の「③プッシュ通知依頼」に該当)この証明書はビルド用証明書とは別物なので注意です。

  1. アプリビルド時の証明書作成と同様に、「Certificates, Identifiers & Profiles」→「Certificates」→右上の「+」をクリックし、「Production」→「Apple Push Notification service SSL (Sandbox & Production)」を選択して、Continue。
  2. 作成したAppIDを選択して、Continue。
  3. CSRを作成して、作成したファイルをアップロードします。
  4. 作成した証明書はダウンロードして、ファイル形式をp12かpemに変換します。
    • macOSであれば、ダブルクリックして一旦インストールし、キーチェーンアクセスツールで証明書を右クリックして書き出せばp12に変換できます。書き出す際、パスフレーズを設定しないよう注意です。(Windows/Linuxの方は「cer pem 変換」でググりましょう!)

スクリーンショット 2017-03-19 22.30.54.png

2. Androidの設定

イメージ図の「①デバイストークン取得」には「SenderID」が、「③プッシュ通知依頼」には「APIキー」が必要です。SenderID、APIキーの作成はFirebaseで行います。(AndroidのPush通知はGCMからFCMに移行し、新規にGCM向けのAPIキーをGoogle Developer Consoleを通して作成することはできなくなりました。1

コンソール画面に移動し、「新規プロジェクトを作成」よりプロジェクトを作成します。
fb3.png

プロジェクト作成後、左上の歯車マーク→「プロジェクトの設定」→「クラウドメッセージング」タブを開きます。
fb4.png

表示された画面の「送信者 ID」がSenderID、「Legacy server key」がAPIキーです。(2017/03/22時点でBaaS@rakuzaは古い形式のAPIキーのみをサポートしています。そのため、「Server key」ではなく「Legacy server key」を使用する必要があります)
fb5.png

3. Push通知証明書、APIキーをBaaS管理者画面で登録

管理者画面の「プッシュ通知管理」→「プッシュ通知環境設定」を開き、前章で作成した証明書&APIキーをBaaS@rakuzaに設定します。iOSのPush通知証明書はファイル名が日本語だと変な感じになるので、英数字のファイル名に変換しておくことをおすすめします。(push.p12とか)

スクリーンショット 2017-03-19 22.46.41.png

4. 「phonegap-plugin-push」のインストール

Push通知の各種機能(デバイストークン取得など)を使用するためには、Cordovaプラグインが必要になります。ここでは、汎用的なPush通知プラグインの「phonegap-plugin-push」を使用します。

バージョンは1.8.4にします。(1.9.x以降はCordovaのバージョンが6.4.0以降となっていますが、Monacaは6.2をサポートしているため)
いつもの様にgitのURLを設定すると最新版が読み込まれてしまうので、一旦1.8.4のソースコードをダウンロードして、「圧縮されたZIPパッケージをアップロード」でzipファイルをアップロードします。
スクリーンショット 2017-03-19 23.26.29.png

また、インストール後に「Push Plugin」→「設定」より、SenderIDを設定します。

SENDER_ID=<「2. Androidの設定」で作成したSenderID>

スクリーンショット 2017-03-19 23.26.51.png

※余談ですが、phonegap-plugin-pushは2.0.0(まだrcですが)からFCMに対応しています。しかし、Cordovaのバージョンが6.4.0以降のため、Monacaでは使用できません・・。6.4.0以降の対応はやくきてくれーー!!

5. ユーザーの登録

BaaS@rakuzaでは1ユーザー=1デバイストークンとなっているため、デバイストークンの登録にユーザーの登録が必要です。ユーザーはID/パスワードでも登録できますが、とりあえず匿名ユーザーを登録します。

MainController.js
const USER_ACCESS_TOKEN_KEY = 'userAccessToken';

function setupRakuza() {
  // 第一引数で指定されたテナントキーの値をもとに楽座のテナントを設定します
  var tenantKey = 'ここにテナントキー';
  RKZClient.setTenantKey(tenantKey, function() {
    // 成功時の処理
    alert('RKZClientクラスの初期化に成功しました。');
    // ユーザーの登録
    registerUser();
  }, function(error) {
    // エラー時にアラートでエラー内容を表示します
    alert(JSON.stringify(error, null, ' '));
  });
}

function registerUser() {
  var deferred = $q.defer();

  // ローカルからユーザーアクセストークンを取得
  var userAccessToken = localStorage.getItem(USER_ACCESS_TOKEN_KEY);
  if (!userAccessToken) {
    // ユーザーアクセストークンがなければ、新規でユーザーを作成
    var userData = {};
    RKZClient.registUser(userData, function (userData) {
      alert(userData.user_access_token + "," + userData.user_no);

      // ユーザーアクセストークンをローカルに保存する
      localStorage.setItem(USER_ACCESS_TOKEN_KEY, userData.user_access_token);
      // ユーザーアクセストークンを返す
      deferred.resolve(userData.user_access_token);
    }, function (error) {
      alert(JSON.stringify(error, null, ' '));
      deferred.reject(error);
    });
  } else {
    // あれば、ユーザーアクセストークンを返す
    deferred.resolve(userAccessToken);
  }

  // 結果はPrimiseを返して、呼び出し元で結果をハンドリングできる様にする
  return deferred.promise;
}

上記コードを実行後に管理者画面でユーザー一覧画面を表示すると、ユーザーが登録されたことが確認できます。
スクリーンショット 2017-03-19 23.48.48.png

6. デバイストークンの取得&登録

続いて、デバイストークンの取得&登録を行います。Push通知を行うには、デバイストークンが必要なため、アプリ側でデバイストークンを取得し、BaaS@rakuzaに送信&登録を行う必要があります。先ほどのユーザー登録処理後に、デバイストークンの取得&登録処理の関数を呼び出す様修正します。

MainController.js
function setupRakuza() {
  // 第一引数で指定されたテナントキーの値をもとに楽座のテナントを設定します
  var tenantKey = 'ここにテナントキー';
  RKZClient.setTenantKey(tenantKey, function() {
    // 成功時の処理
    alert('RKZClientクラスの初期化に成功しました。');
    // ユーザーの登録
    registerUser().then(function (userAccessToken) {
      // プッシュ通知のセットアップ
      setupPushNotification(userAccessToken);
    });
  }, function(error) {
    // エラー時にアラートでエラー内容を表示します
    alert(JSON.stringify(error, null, ' '));
  });
}

function registerUser() {
  // 略...
}

function setupPushNotification(userAccessToken) {
  // プッシュ通知初期設定
  var push = PushNotification.init({
    android: {
      senderID: '「2. Androidの設定」で作成したSenderID'
    },
    ios: {
      alert: 'true',
      badge: 'true',
      sound: 'true'
    }
  });

  // デバイストークン取得時のイベント
  push.on('registration', function(data) {
    console.info('registrationId: ' + data.registrationId);

    // デバイストークンをBaaS@rakuzaに送信&登録
    RKZClient.registPushDeviceToken(userAccessToken, data.registrationId, function (statusCode) {
      alert('デバイストークンを登録しました。');
    }, function (error) {
      alert(JSON.stringify(error, null, ' '));
    });
  });

  // 通知受信時のイベント
  push.on('notification', function(data) {
    console.info('message: ' + data.message);
    console.info('title: ' + data.title);
    console.info('count: ' + data.count);
    console.info('sound: ' + data.sound);
    console.info('image: ' + data.image);
    console.info('additionalData: ' + data.additionalData);
  });

  push.on('error', function(e) {
    console.error('message: ' + e.message);
  });
}

7. アプリのビルド

前述までの状態でアプリをビルドして実機にインストールします。iOSはAd Hocでビルドしてください。Androidはデバッグビルドで構いません。

8. Push通知実行

管理者画面より、お知らせをPush通知します。「お知らせ管理」→「お知らせ一覧」よりお知らせ一覧を表示し、Push通知したいお知らせの「Push」列のボタンをクリックします。
プッシュ通知入力画面でタイトルを編集できます。(ちなみに、実際に送信されるのはタイトルのみです)
配信日時を変更して、指定時間に送信も可能です。すぐに送りたい場合は変更せずそのまま「次へ」ボタンをクリックして、予約をします。
スクリーンショット 2017-03-20 0.21.27.png

しばらくすると、Push通知が届きます。
IMG_0001.jpg


もし、Push通知が届かない!?場合は管理画面(「プッシュ通知管理」→「プッシュ通知履歴」)から送信ログを参照できるので確認してみて下さい。「ログ詳細」からダウンロードできます。
無題5.png

エラーメッセージが以下の場合、APIキーが間違っているか、FCM移行後にGoogle Developer ConsoleでAPIキーを作成した可能性があります。後者の場合は、Firebaseより「Google プロジェクトをインポート」を実行して生成された「Legacy server key」を指定して下さい。

Android端末へのプッシュ通知の送信に失敗しました。 : HTTP/1.0 401 Unauthorized

ソースコード

今回修正したソースコードです。
https://github.com/kishino/BaaSSampleApp/commit/0400042c1fb001644c1d3cf39701edd5e6ecdf2a

おわりに

おそらく、一番ハマるのはiOSの証明書などの作成だと思います。(私もはまりました・・:sob:
ただ、そこを乗り越えれば面倒なサーバの処理をBaaSが行なってくれるので、簡単にPush通知が実装できて良い感じでした:grinning:


  1. 公式ドキュメントの「Authentication Error」を参照