おでんはじめました。

required ちくわぶ and 巾着,optional はんぺん.

Xamarin.Forms で App Center のプッシュ通知を使ってみる

この記事は Xamarin Advent Calendar 2018 の 19 日目の記事です。

App Center の Push Notifications と Xamarin.Forms の Android を使用してプッシュ通知を送受信する方法を説明します。App Center の Push Notifications は Preview 版(2018.12.19 現在)ですのでご注意ください。

Xamarin.Forms でプッシュ通知を実装する方法

Xamarin.Forms でプッシュ通知を実装するには以下の方法があります。

プッシュ通知の仕組みは、プラットフォーム通知システム(以下 PNS: Platform Notification System )と呼ばれるプラットフォーム独自のインフラストラクチャを利用してプッシュ通知を配信します。 PNS は Android であれば Firebase Cloud Messaging (FCM)、iOS であれば Apple Push Notification Service (APNS) を使用することになります。

他にも Azure Notification Hubs を使用しないで直接各 PNS とプッシュ通知のやり取りをする方法や、プッシュ通知に似てるものとして Firebase In-App Messaging というのもあります。Firebase In-App Messaging はアプリに事前に URL スキームを埋め込んでおき、Firebase からその URL に対してメッセージを送信するとそのアプリがメッセージを受信するという仕組みです。

Azure Mobile Apps SDK を使用する方法は App Service の URL を指定するだけで各種の接続をまかなってくれて扱いやすいのですが、開発は止まってるぽいです。1

Azure Notification Hubs は ネイティブ側(iOS / Android)にコードを実装する必要があるのですが、App Center の Push Notifications は共通プロジェクトの App クラスにちょろちょろっと書くだけなのでずいぶん簡単になっています(それでも事前に設定することがいろいろありますが)。

Firebase Cloud Messaging の設定

今回は Android を使ってプッシュ通知をおこなうので、Firebase Cloud Messaging でのプロジェクトとアプリの登録が必要になります。

  1. Firebase にログインする
  2. 右上の「コンソールへ移動」をクリック
  3. プロジェクトを追加する
    f:id:masatoru:20181218183333p:plain
  4. 左上の設定をクリック
  5. 「プロジェクトの設定」をクリック
    f:id:masatoru:20181218183617p:plain
  6. Android アプリに Firebase を追加」をクリック f:id:masatoru:20181219122016p:plain
  7. 「アプリの登録」の「 Android パッケージ名」は Xamarin の Android プロジェクト→プロパティ→ Android マニフェスト→パッケージ名 をコピペします
    f:id:masatoru:20181219122502p:plain
  8. 「アプリを登録」をクリックすると google-services.json をダウンロードできるのでこれを保存しておきます
  9. JAVAに関するところは Xamarin には関係ないので「次へ」で無視

これでアプリ登録が完了しました。

サーバーキーの取得

設定→クラウドメッセージングの「サーバーキー」をコピペして保存しておきます。

App Center でアプリケーションを追加する

App Center にログインして All apps から右上の Add newAdd new app をクリックします。

「アプリケーション名」の入力と、OS は Android、Platform は Xamarin を指定します。

f:id:masatoru:20181219115000p:plain

作成したアプリケーションから Push → Notifications をクリックします。 ここに移行の実装手順が記載されています。

  1. Xamarin.Forms での実装手順
  2. (Firebase の設定と)Android プロジェクトへの記述
  3. Firebase のサーバーキーのコピペ

上記手順を以下進めていきます。

Xamarin.Forms にプッシュ通知を実装する

.NET Standard で Xamarin.Forms のプロジェクトを作成します。

パッケージマネージャーから Microsoft.AppCenter.Push をすべてのプロジェクトにインストールします。バージョンは 1.11.0(2018.12.15現在)です。

App.xaml.cs にコードを追加していきます。まずは using を追加します。

using Microsoft.AppCenter.Push

同様に App.xaml.csOnStart() メソッドに 以下を追加します。上記の Push → Notifications のページに記載されているのでそちらをコピペしてください。

protected override void OnStart()
{
  AppCenter.Start("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", typeof(Push));
  Push.PushNotificationReceived += this.Push_PushNotificationReceived;
}

プッシュ通知を受信したときに Push_PushNotificationReceived イベントが呼ばれるので、受信した内容を表示するようにします。

private async void Push_PushNotificationReceived(object sender, PushNotificationReceivedEventArgs e)
{
    await this.MainPage.DisplayAlert(e.Title, e.Message, "OK");
}

Android プロジェクトへ追記する

Android プロジェクトの PropertiesAndroidManifest.xml ファイルの <application>...</application> タグ内に以下を追加します。

<receiver android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver" android:exported="false" />
<receiver android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver" android:exported="true" android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="${applicationId}" />
</intent-filter>
</receiver>

追加後は以下のようになります。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.company.PushAppCenterSample" android:installLocation="auto">
  <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="27" />
  <application android:label="PushAppCenterSample.Android">
    <receiver android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver" android:exported="false" />
    <receiver android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver" android:exported="true" android:permission="com.google.android.c2dm.permission.SEND">
      <intent-filter>
        <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
        <category android:name="${applicationId}" />
      </intent-filter>
    </receiver>
  </application>
</manifest>

Fireabase でダウンロードした google-service.jsonAndroid プロジェクトにコピーして、「ビルドアクション」を GoogleServicesJson に設定します。

選択できない場合は一度プロジェクトを保存して Visual Studio を終わらせて、再度プロジェクトを開くと表示されます。

f:id:masatoru:20181219123640p:plain

Firebase のサーバーキーのコピペ

上記で Firebase の設定で取得したサーバーキーをここにコピペします。

以上で App Center の設定 と Xamarin.Forms の実装は完了です。

プッシュ通知の送信テストをする

送信テストは App Center のサイトの Notifications ページにある Send Notification ボタンからおこないます。

f:id:masatoru:20181218160145p:plain

Compose で送信するメッセージを指定します。Cmapaign Name, Message が必須で、Title, Custom Data はオプションになっています。Custom data は Key/Valueで値を送信することができます(後述)。

f:id:masatoru:20181218161842p:plain

Target でどのデバイスに送信するかを決定します。

  • All registerd devices - 登録されているすべてのデバイスに送信します。
  • Custom device list - 指定したデバイスに最大20個まで一度の送信することができます。
  • Audience - 国や言語、デバイスのバージョンなどを指定して送信することができます。

f:id:masatoru:20181218161802p:plain

最後に Review で送信する内容を確認して Send notification クリックします。

f:id:masatoru:20181218162629p:plain

うまくいけばデバイスにプッシュ通知が到達しメッセージが表示されます。これまでの経験ではいずれも1秒かからずに到達する感じです。

f:id:masatoru:20181219215210p:plain

Swagger を使ってプッシュ通知を送信する

REST API を使用してプッシュ通知を送信することもできます。使用できる API が OpenAPI(旧Swagger) で定義されています。

API を使用するためには API トークンが必要になります。API トークンは(アプリの設定ではなく) App Center の設定(右上の自分のアイコン)→ Account Settings → API Tokens → New API Token で発行できます。

f:id:masatoru:20181219173514p:plain

Swagger UI を使ってプッシュ通知のメッセージを送信してみます。プッシュ通知の API一覧 の右上にある Authorize をクリックして取得した API トークンを APIToken(apiKey) にコピペします。

f:id:masatoru:20181219180146p:plain

プッシュ通知の API一覧 から POST を使用します。

f:id:masatoru:20181219193918p:plain

[Try it out] をクリックすると値を編集できるので、ここに値を入力していきます。 すべてのデバイスに送信する場合は、"notification_target": null になります。

Example value

{
  "notification_content": {
    "name": "プッシュ通知のテスト",
    "title": "プッシュ通知のタイトル",
    "body": "プッシュ通知のメッセージ"
  },
    "notification_target" : null
}

The name of the owner にオーナー名、The name of the application にアプリ名を入力して、Execute をクリックします。成功すれば notification_id と値が JSON が返ります。

特定のデバイスにプッシュ通知をおこなう

特定のデバイスにプッシュ通知をおこなう場合は、notification_target に対象のデバイス ID を指定します。最大で同時に 20 台まで送信できます。

Example value

{
  "notification_content": {
    "name": "プッシュ通知のテスト",
    "title": "プッシュ通知のタイトル",
    "body": "プッシュ通知のメッセージ"
  },
  "notification_target":  {
    "type": "devices_target",
    "devices": ["xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"],
  }
}

バイス ID は、App Center の SDK を使用して AppCenter.GetInstallIdAsync(); で取得することができます。

Custom Data を使ってプッシュ通知をおこなう

送信する JSONcustom_data を付加すると Key/Value の値を送信することができます。

Example value

{
  "notification_content": {
    "name": "プッシュ通知のテスト",
    "title": "プッシュ通知のタイトル",
    "body": "プッシュ通知のメッセージ",
    "custom_data": {
      "dinner": "beer"
    },
  },
  "notification_target":  {
    "type": "devices_target",
    "devices": ["xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"],
  }
}

バイス側で受け取る方法は、Push_PushNotificationReceived イベントの引数の PushNotificationReceivedEventArgs クラスの CustomData プロパティに Key/Value 値が入っているので、これを使って分岐処理などをおこなうことができます。

private async void Push_PushNotificationReceived(object sender, PushNotificationReceivedEventArgs e)
{
    if (e.CustomData != null && e.CustomData.ContainsKey("dinner"))
    {
        var action = e.CustomData["dinner"];
        switch (action)
        {
            case "beer":
                await this.MainPage.DisplayAlert("Sample", "また飲むのか!", "OK");
                break;
            case "beef":
                await this.MainPage.DisplayAlert("Sample", "焼肉いいね!", "OK");
                break;
        }
    }
}

まとめ

プッシュ通知は環境の設定や実機が必要などめんどくさいイメージがありますが、App Center の Push Notifications は(これまでに比べて)実装が簡単で、かつ安定してプッシュ通知を受信してくれるので、それほどストレスなく使えると思います。ぜひ一度お試しください。

明日は @yu_ka1984 さんです。よろしくお願いします!