メッセージの受信

プッシュ通知を受け取るには、AndroidManifest.xml でメッセージ受け取り用に指定した FirebaseMessagingService または BroadcastReceiver を実装します。この際、ヘルパー API を利用できます。

プッシュ通知を受け取り、内容をパースする例を以下に挙げます。

public class MyFirebaseMessagingService extends FirebaseMessagingService {
  @Override
  public void onMessageReceived(RemoteMessage remoteMessage) {
    // Get the push message.
    Map<String, String> payload = remoteMessage.getData();
    ReceivedMessage message = PushMessageBundleHelper.parse(payload);

    // Get the sender of the push message.
    KiiUser sender = message.getSender();
    // Refresh the sender and then access it.

    // Determine the push notification type and start parsing.
    PushMessageBundleHelper.MessageType type = message.pushMessageType();
    switch (type) {
      case PUSH_TO_APP:
        // Handle the "Push to App" message.
        break;
      case PUSH_TO_USER:
        PushToUserMessage pum = (PushToUserMessage) message;
        // Extract the target scope.
        switch (pum.getScope()) {
          case APP_AND_GROUP:
            KiiGroup group = pum.getEventSourceGroup();
            // Refresh the group and then access it.
            break;
          case APP_AND_USER:
            KiiUser user = pum.getEventSourceUser();
            // Refresh the user and then access it.
            break;
          case APP_AND_THING:
            KiiThing thing = pum.getEventSourceThing();
            // Refresh the thing and then access it.
            break;
        }

        // Extract the subscribed topic.
        if (pum.containsKiiTopic()) {
          KiiTopic topic = pum.getKiiTopic();

          // Extract field values.
          long when = pum.getMessage().getLong("when");
          String app_specific_string = pum.getMessage().getString("app_specific_key1");
          long app_specific_long = Long.parseLong(pum.getMessage().getString("app_specific_key2"));
        }
        break;
      case DIRECT_PUSH:
        // Handle the "Direct Push" message.
        break;
    }
  }
}

FirebaseMessagingService のサブクラスとして実装します。onMessageReceived メソッドの引数で得られたペイロードを PushMessageBundleHelper.parse メソッドに渡して、ReceivedMessage を作成します。

ReceivedMessage を作成後、以下の方法でプッシュメッセージの詳細を取得できます。

  1. getSender メソッドを実行して、プッシュメッセージの送信者を取得。
  2. pushMessageType メソッドを実行して、プッシュメッセージの種別を判別。
    (ユーザープッシュ通知の場合、種別は "PUSH_TO_USER")
  3. getScope メソッドで対象のスコープを特定し、スコープに応じた getEventSourceGroupgetEventSourceUsergetEventSourceThing を実行してスコープオブジェクトを取得。
  4. getKiiTopic メソッドを実行し、対象トピック取得。
  5. getMessage メソッドを実行してメッセージの Bundle を取得し、その他の既定フィールドやアプリ定義フィールドの値を取得。

ハンドラー内では、複数のトピックや Bucket の購読も識別して、それぞれ別の処理を行うことができます。すべてのプッシュメッセージはこのメソッドで受信されますが、pushMessageType メソッドによってプッシュ通知の種類を、getKiiTopic メソッドによってトピック名を取得することで、目的のトピックを識別できます。

プッシュ通知を期待どおりに受け取れない場合、トラブルシューティング を参考に問題を解決してください。また、プッシュ通知設定チュートリアル にあるシンプルな実装によって、プッシュ通知の動作だけを検証することもできます。

ステータスバーへの表示

Android では、プッシュ通知を受信しても onMessageReceived メソッド、または、onReceive メソッドが呼ばれるだけです。特に、ステータスバーにメッセージを表示したいような場合は、自分で作り込む必要があります。実装のヒントは、プッシュ通知の実装ヒント をご覧ください。

プッシュメッセージの送信者

プッシュメッセージの送信者を取得する方法を以下に示します。Push to User での送信者は、メッセージを送信したユーザーまたは Thing を表します。

PushToUserMessage pum = (PushToUserMessage) message;

// Get the sender of the push message.
KiiUser user = message.getSender();
// Refresh the user and then access it.

// Get the sender of the push message.
KiiPushMessageSender sender = message.getPushMessageSender();
if (sender instanceof KiiUser) {
  KiiUser senderUser = (KiiUser)sender;
  // Refresh the user and then access it.
} else if (sender instanceof KiiThing) {
  KiiThing senderThing = (KiiThing)sender;
  // Refresh the thing and then access it.
}

送信者を取得するには、以下のいずれかのメソッドを使用します。

  • getSender()

    メッセージを送信したのがユーザーであった場合、そのユーザーを返します。Thing の場合は null を返します。

  • getPushMessageSender()

    メッセージを送信したのがユーザーまたは Thing であった場合、そのユーザーまたは Thing を返します。目的の型にキャストして参照します。

プッシュメッセージの例

以下は、FCM からのプッシュメッセージを受け取ったとき、remoteMessage.getData() によって取得できるデータのイメージです。Push to User では、通知されたトピック名や、アプリケーションから指定した追加データ(ここでは Key1 = Value1)を上記のメソッドによって取得できます。これらのデータの詳細は Javadoc を参照してください。

{
    topic = myTopic,
    objectScopeUserID = 01234567-89ab-cdef-0123-456789abcdef,
    objectScopeAppID = 0123abcd,
    sender = 01234567-89ab-cdef-0123-456789abcdef,
    collapse_key = do_not_collapse,
    when = 1403845393893,
    objectScopeType = APP_AND_USER,
    from = 123456789012,
    Key1 = Value1
}

プッシュ通知のループに対する注意

プッシュ通知の設計や実装を行うときには、プッシュ通知のループが発生しないように十分に注意してください。プッシュ通知の受信処理で再びプッシュが発生する処理を行うと、永久ループから抜け出せなくなります。

ユーザープッシュ通知(Push to User)では、プッシュメッセージの受信処理を契機に、再びトピックへのメッセージ送信を行うと、プッシュ通知のループが発生する可能性があります。

万一、永久ループがリリースモジュールで発生してしまった場合、対処が非常に困難です。本質的には、すべてのエンドユーザーのモバイルアプリを対処済みバージョンに更新する必要があります。更新完了までは、開発者ポータルのプッシュ通知のキーや証明書を削除したり、ユーザーごとに REST API で購読を解除したりするなどの対処が必要になります。