Receiving a Push Notification

To receive push notifications, you need to implement either FirebaseMessagingService or BroadcastReceiver that is defined in the AndroidManifest.xml. Kii Cloud SDK provides a helper API to support your application to parse push messages.

See the following sample code:

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;
    }
  }
}

You will implement the logic as a subclass of the FirebaseMessagingService. Pass the push message payload that is obtained as the argument of the onMessageReceived method to the PushMessageBundleHelper.parse method in order to create a ReceivedMessage instance.

After creating a ReceivedMessage instance, you can get the push message content after getting the Bundle as follows:

  1. Gets the sender of the push message by calling the getSender method.
  2. Determines the type of the push message by calling the pushMessageType method.
    If the message is "Push to User", the type will be "PUSH_TO_USER".
  3. Determines the target scope with the getScope method and get the scope object using the appropriate methods (getEventSourceGroup, getEventSourceUser, or getEventSourceThing)
  4. Extracts the target topic by calling the getKiiTopic method.
  5. Gets the message Bundle with the getMessage method and extracts more default and custom field values.

All push notifications will be received by this method. As shown in the above example, you can determine the push notification type and the topic name with the pushMessageType and getKiiTopic methods, respectively.

If you have issues in receiving push notifications, information in Troubleshooting might help you. You can also use the simple implementation illustrated in Push Notification Tutorials to investigate if the push notification is working properly.

Notification on the status bar

An Android device only executes the onMessageReceived or onReceive method when it receives a push notification. If you want to show a message on the status bar, you need to implement the logic by yourself. See Push Notification Implementation Tips for some hints.

Push message sender

The following snippet shows how you can get the sender of a push notification. A user or thing who sent the message will be set as the sender for the Push to User notification.

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.
}

Use one of the following methods for getting the sender.

  • getSender()

    If a user sent the message, the method returns this user. If a thing sent the message, the method returns a null.

  • getPushMessageSender()

    If a user or thing sent the message, the method returns this user or thing. To refer the returned value, cast it to the target type.

Push message example

The following is an example of the data you can get by executing the remoteMessage.getData() method when an FCM push message is received. You can get various information from the push message, such as the topic that sent the notification and the custom data specified by the application (in this example Key1 = Value1). See the Javadoc to learn more.

{
    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
}

Preventing an infinite loop of push notifications

When designing and implementing the push notification feature, ensure that your mobile app does not cause an infinite loop of push notifications. If the notification reception process triggers another push notification, there is no way to stop the infinite loop.

Specifically for the Push to User notification feature, if the notification reception process sends a push message to the subscribed topic, it will cause an infinite loop.

If your release module caused an infinite loop, it would be very difficult to solve the issue. To fix it fundamentally, your mobile app on every end-user's device must be updated to a fixed version. Until the update is complete, you would need to delete the key or the certificates in the developer portal or unsubscribe each user from the bucket by using the REST API.