Issues Listening to Incoming Notifications with native, raw device token (standalone app)

Hey guys!

We’re trying to listen for incoming notifications so we can route to a particular page based on the data passed with the notification payload. We are doing this, as you might expect, via:

Notifications.addListener(this.handleNotification);

We’re sending notifications via our own notifications system, using device tokens obtained using:

const { data: token, type: platform } = await this.getDevicePushToken();

Something that’s arisen is that when a user taps a notification sent using a native device token, the listener doesn’t pick up on it at all. Notifications sent via an Expo push token are picked up by the listener as you would expect. Is there some kind of metadata we need to send with our notification payloads to get this to work? Is there something in the code that prevents notifications from other sources from working properly (something I can imagine on Android, but I’m not sure how this is possible on iOS)?

Any help would be much appreciated, even a pointer to a chunk of code so I can start to work on a PR!

Hi,

I’m actually having the exact same issue.

When adding the notifications listener, it does not trigger when a notification is received whilst the app is open or when the user selects the notification.

This would be a very useful feature as when a notification is received as, for example, it can be used to trigger an application store update when a notification is received.

Has anybody else experienced this issue?

Hi @josh-es – this could be happening because Expo needs the notification payload to be in a specific (undocumented) format. This is something not covered in the docs. This class does the current (Feb 2018) JSON encoding/decoding of the notification payload: https://github.com/expo/expo/blob/master/android/expoview/src/main/java/host/exp/exponent/notifications/ExponentNotification.java#L21.

Hey @ide!

I’ve found the way to doing this, but I think it’s highlighted a bug in Expo’s codebase.

Firstly, the solution. In our situation, we use AWS and SNS Mobile Push to send push notifications from our service, and the payload is required in the following format:

{
  body: Object, // the data you want to send with the notification
  message: String, // the notification body
  notificationId: Int, // some ID number
  isMultiple: Boolean,
  remote: Boolean
}

You can construct this with the following Java code, as an example:

payload.put("body", dataMap);
payload.put("message", notification.getMessage());
payload.put("notificationId", -1);
payload.put("isMultiple", false);
payload.put("remote", true);

I am happy to provide more details on the solution to this to anyone else who’s using native device tokens with Expo - the best place to find me is by direct messaging me on the Expo Developers Slack; my username is josh-es.

Secondly, the bug. The payload received by the Notifications listener in the JavaScript code looks like this when using our push notifications service:

I then tried the same thing using the Expo push service:

Notice that the message property is being set to the same object as the data property, which is working as intended? Surely in theory the message property should be set to the notification text, and the data property set to the data object passed to the Expo push service, or the equivalent in a native notification payload? There are notices in the codebase about this being deprecated (in the ExponentNotification class linked to above), but is there some other way to access notification messages via the Notifications.addListener handler in the JavaScript?

The notificationId might be added elsewhere in the client or via SNS or GCM. This is the payload format we send to SNS:

  {
    Message: JSON.stringify({
      default: message.body,
      GCM: JSON.stringify({
        priority: 'normal' | 'high',
        data: {
          experienceId: string,
          title: string,
          message: string,
          body: object,
        },
      }),
    }),
    MessageStructure: 'json',
    TargetArn: SNSEndpointARN,
  }

(Note: this may change at any time and is not part of the public API.)

1 Like

You’re absolutely right, the experience ID is set to a random integer within the Expo codebase for remote notifications when collapse mode is not used.

I don’t suppose you have a similar payload format for the APNS side? I have everything working on the Android side, but my Obj-C is rubbish so no such luck so far on the iOS side! :stuck_out_tongue:

This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.