ServicePattern / MobileAPI_Android

Messaging API library and example for Android mobile platform
1 stars 1 forks source link

Customization of notification payload #31

Closed bramley-stride closed 3 years ago

bramley-stride commented 3 years ago

Android apps can only intercept and process firebase notifications via onMessageReceived(RemoteMessage remoteMessage) while the app is in foreground. When in background, the firebase library itself issues the notification based on properties set in the backend, according to this table: https://firebase.google.com/docs/cloud-messaging/android/receive#handling_messages

Because of this, we'd like to request some customizations to the payload: ref: https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages#androidnotification

click_action: "BP_CHAT"
channel_id: "BP_CHAT"
icon: "ic_stat_bp_chat"

Please also populate notification.title, as it's currently null. ref: https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages#notification

Another way around this is for BP to move everything from the notification object (ie title, body) to the payload section, leaving the notification object null and allowing our app to issue the notification itself.

Our app will still need to intercept onMessageReceived and issue a notification, in the case where the user receives a message while in the app, but is on a different screen to the chat.

ALobastov commented 3 years ago

Here is a complete notification payload sent by the server:

{
  "message":{
    "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
    "notification":{
      "title_loc_key":"keyChatNewMessageTitle",
      "title_loc_args":["John Doe"],
      "body":"<Message content>",
      "sound":"default"
    },
    "data":{
      "chatID":<chat_id>,
      "messageID":<message_id>,
      "category":"NEW_CHAT_MESSAGE"
    }
  }
}

Please specify exactly what changes are proposed. Do you need these three new attributes in the "notification" part of the payload?

As of notification.title - we are not setting the title directly as it will have to be localizable in most cases. We use client side localization approach where the server uses title_loc_key and title_loc_args attributes instead of title - the application is supposed to have the localized title strings in the app string resources. If you see title_loc_key as NULL in some notifications - please open separate issue for this and specify which exact notification it applies to (including client logs as always requested).

bramley-stride commented 3 years ago

The 3 new fields are required in the android notification object as defined here: https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages#androidnotification

We can't always provide logs, because as that table in the first link shows, our app code is not hit when a notification is received while app in background.

bramley-stride commented 3 years ago

I see titleLocalizationKey is always populated, but titleLocalizationArgs is often [], for example all of the notifications received in #30 have empty args. What should the value of R.string.keyChatNewMessageTitle be? "%1$s"? Because don't we just want to show the sender's name as the title? And how should this look if it's an empty array (I'm not familiar with what Firebase would do in that scenario, would it throw a FormatException?

ALobastov commented 3 years ago

Requested attributes (click_action, channel_id, icon) added; server version 5.5.6.58688. Will notify again once development server is updated.

ALobastov commented 3 years ago

The server uses the following string keys for iOS notification: keyChatNewMessageTitle: the key of the title string for the new message notification. It does not have any arguments. Typical value is "You have a new message" for iOS or “You have a new message from %1$s” for Android. When using Android (only) new message notification sends a single title argument - name of the sender party. I.e. if the title argument is ["John Doe"] the Android notification will show "You have a new message from John Doe". keyChatNewMessageSubtitle: the key of the subtitle string for the new message notification. Only present on iOS. Typical value "From %@". New message notification sends a single subtitle argument - name of the sender party. I.e. if the subtitle argument is ["John Doe"] the notification will show "From John Doe". keyChatTimeoutWarningTitle: the key of the title string for the timeout warning notification. Typical value is "The session is about to time out" keyChatInactivityTimeoutTitle: the key of the title string for the inactivity timeout notification. Typical value is "Are you still there?" Note that for Android the notification only has the title (there is no subtitle), so the message sender name is included in the title string.

ALobastov commented 3 years ago

If title_loc_key is keyChatNewMessageTitle and title_loc_args is empty array, that means the chat nick is empty in the messaging entry (server side configuration). Server configuration is TTec responsibility.

ALobastov commented 3 years ago

What should the value of R.string.keyChatNewMessageTitle be? "%1$s"? Because don't we just want to show the sender's name as the title? And how should this look if it's an empty array (I'm not familiar with what Firebase would do in that scenario, would it throw a FormatException?

Depends of what application wants to display. If you want to display "New message from John Doe" then it will be "New message from %1$s". If you want to display just "John Doe" then it will be "%1$s".

ALobastov commented 3 years ago

The development server has been updated to version 5.5.6.58695 which includes three requested notification attributes (channel_id, click_action and icon).

bramley-stride commented 3 years ago

I am seeing click_action and icon, but not getting channel_id. Example log:

2021-04-21 00:12:44.614 7462-8868/au.com.webjet.dev D/FCMNotificationReceiver: Push notification received from: 897661342721 collapseKey: au.com.webjet.dev Title: null Body: There are no agents available to handle your request at this time. Please try again later. Tag: null ChannelId: null Icon: ic_stat_bp_chat TitleLocalizationKey: keyChatNewMessageTitle TitleLocalizationArgs: [] BodyLocalizationKey: null BodyLocalizationArgs: null ClickAction: BP_CHAT 2021-04-21 00:12:44.620 7462-8868/au.com.webjet.dev D/ApiLogger: Log to /storage/emulated/0/Android/data/au.com.webjet.dev/files/ApiLogs/AU Dev/2021-04-21 00.12.44.615_push_897661342721.txt

ChannelId: null Icon: ic_stat_bp_chat ClickAction: BP_CHAT

This is using remoteMessage.getNotification().getChannelId() Log code in onMessageRecieved:

if (remoteMessage.getNotification() != null) {
            logMsg+="\nTitle: " + remoteMessage.getNotification().getTitle()
                    +" Body: "+remoteMessage.getNotification().getBody()
                    +" Tag: "+remoteMessage.getNotification().getTag()
                    +" ChannelId: "+remoteMessage.getNotification().getChannelId()
                    +" Icon: "+remoteMessage.getNotification().getIcon()
                    +" TitleLocalizationKey: "+remoteMessage.getNotification().getTitleLocalizationKey()
                    +" TitleLocalizationArgs: "+ Arrays.toString(remoteMessage.getNotification().getTitleLocalizationArgs())
                    +" BodyLocalizationKey: "+ remoteMessage.getNotification().getBodyLocalizationKey()
                    +" BodyLocalizationArgs: "+ Arrays.toString(remoteMessage.getNotification().getBodyLocalizationArgs())
                    +" ClickAction: "+ remoteMessage.getNotification().getClickAction()
            ;
            Log.d(TAG, logMsg);
        }

full code: https://github.com/ServicePattern/MobileAPI_Android/issues/29#issuecomment-822906132

ALobastov commented 3 years ago

Here is a complete payload of the notification extracted from actual server log: { "data": { "category": "NEW_CHAT_MESSAGE", "chatID": "ec0f6d46-4569-4e86-90e8-57adae155bb7" }, "notification": { "badge": 0, "body": "Describe your issue please", "channel_id": "BP_CHAT", "click_action": "BP_CHAT", "icon": "ic_stat_bp_chat", "sound": "default", "title_loc_args": [ "" ], "title_loc_key": "keyChatNewMessageTitle" }, "to": "d5Y9YBWAK64:APA91bGc777c0DMInRHb_n8sFwovQr1NldnmVY70f-oqIHvl-Sfx8mcfyGIl9UkXZmaaWzF9sejqgsWqUFWGDRgIB4xSIT5w6wAZ28AANgDpVWnobSRaVmBr9PMGR1m4cdKoIVl6xTp8" } Do you see anything incorrect here?

ALobastov commented 3 years ago

Are you sure you wanted channel_id and not android_channel_id? By decompiling Firebase RemoteMessage class it looks like the Notification.channelId is filled in from the android_channel_id JSON attribute; not from channel_id.

Pleas confirm.

ALobastov commented 3 years ago

BrightPatern server uses Legacy HTTP FCM protocol; the payload details differs from the REST: https://firebase.google.com/docs/cloud-messaging/http-server-ref#send-downstream Per this reference, it is indeed android_channel_id and not channel_id.

Fixed; build 5.5.6.58747. Dev server upgraded.