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:
        PushToAppMessage pam = (PushToAppMessage) message;
        // Extract the target scope.
        switch(pam.getScope()) {
          case APP_AND_GROUP:
            KiiGroup group = pam.getEventSourceGroup();
            // Refresh the group and then access it.
            break;
          case APP_AND_USER:
            KiiUser user = pam.getEventSourceUser();
            // Refresh the user and then access it.
            break;
          case APP_AND_THING:
            KiiThing thing = pam.getEventSourceThing();
            // Refresh the thing and then access it.
            break;
        }

        // Extract the subscribed bucket and the changed KiiObject.
        if (pam.containsKiiBucket()) {
          KiiBucket bucket = pam.getKiiBucket();
          if (pam.containsKiiObject()) {
            KiiObject obj = pam.getKiiObject();
          }

          // Extract field values.
          long when = pam.getMessage().getLong("when");
          String event_type = pam.getMessage().getString("type");
        }
        break;
      case PUSH_TO_USER:
        // Handle the "Push to User" message.
        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 App", the type will be "PUSH_TO_APP".
  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 Bucket and Object by calling the getKiiBucket and getKiiObject methods, respectively.
  5. Gets the message Bundle with the getMessage method and extracts more default and custom field values.

Note that the key-value pairs of the KiiObject instance created with the above steps will be empty. If you need to refer to the key-value pairs, execute the refresh method.

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 modified the subscribing bucket will be set as the sender for the Push to App notification.

PushToAppMessage pam = (PushToAppMessage) 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 modified the bucket, the method returns this user. If the bucket is modified by a thing or via the data browser on the developer portal, the method returns a null.

  • getPushMessageSender()

    If a user or thing modified the bucket, the method returns this user or thing. To refer the returned value, cast it to the target type. If the bucket is modified via the data browser on the developer portal, the method returns a null.

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 which bucket and object were modified and how they were modified (e.g., added, deleted and so on).

See the Javadoc to learn more. The fields not covered in this Javadoc are the ones added by FCM. See the documentation by Google for the details.

{
    bucketType = rw,
    modifiedAt = 1403845696260,
    bucketID = bucketName,
    origin = EVENT,
    from = 123456789012,
    type = DATA_OBJECT_CREATED,
    objectScopeUserID = 01234567-89ab-cdef-0123-456789abcdef,
    objectScopeAppID = 0123abcd,
    sender = 01234567-89ab-cdef-0123-456789abcdef,
    collapse_key = bucketName,
    objectID = fedcba09-8765-4321-fedc-ba0987654321,
    when = 1403845696274,
    objectScopeType = APP_AND_USER,
    appID = 0123abcd
}

You cannot customize push messages in the Push To App. See Customizing a push message for the possible alternatives.

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 App notification feature, if the notification reception process updates the subscribed bucket, 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.