35

We are using FCM to send remote notifications for both iOS and Android. The following are the payloads we are sending from the backend.

options = {
     notification: {
          title: "title",
          body:  body,
          sound: 'default'
     },
    priority: "high",
    content_available: true,
    data: {
       type: 'type',
       id: id,
    }
}

This works for ios and android. But for some reason, the android side we need to send title,body and sound for keys in data payload and need to remove notification payload.

Now the notifications are not receiving ios side when app is not active, banner notifications are not arriving but the data is receiving when app is active. We need banners on the iOS side.

Is that notification key is mandatory to display banner in iOS?

How to use the same payload for both iOS and Android.

options = {

priority: "high",
content_available: true,
data: {
      title: "title",
      body:  body,
      sound: 'default'
      type: 'type',
      id: id,
     }
}

Also tried adding content_available and priority keys with various combinations. Gone through all FCM docs and it still confuses. Help/Suggestions appreciated.

Preetam Jadakar
  • 4,479
  • 2
  • 28
  • 58
  • we need "aps":{"content-available":1,"alert":"ALERT","sound":"default"} like this for banner in iOS – Vinupriya Arivazhagan Jan 10 '17 at 07:07
  • @VinupriyaArivazhagan: we are using FCM, so the payload format is bit different than default you suggested. – Preetam Jadakar Jan 10 '17 at 07:15
  • you have give it manually, when you are creating your payload message – Vinupriya Arivazhagan Jan 10 '17 at 07:23
  • Hi. When testing in Android with your payload, is the app in foreground or background? – AL. Jan 10 '17 at 07:25
  • works for all condition @AL. problem is with ios – Preetam Jadakar Jan 10 '17 at 08:27
  • 4
    *Is that notification key is mandetory to display banner in iOS?* -- Yes. A notification will only appear on iOS tray only if you have a `notification` payload. `data`-only payloads (in your first scenario) are [stored by FCM until your app goes on foreground and is connected to FCM](https://firebase.google.com/docs/cloud-messaging/concept-options#data_messages). – AL. Jan 10 '17 at 09:12
  • 2
    I would suggest sending separate payloads for Android and iOS users. It's more work, but that way, you'd be able to control the behavior accordingly, depending on the client app device. Cheers! – AL. Jan 10 '17 at 09:14
  • @AL.thanks..was looking for same. – Preetam Jadakar Jan 10 '17 at 09:17
  • 1
    @AL. - HOW do you send separate payloads for Android and iOS users? Are you saying that our company's server that is creating the payload should be aware of whether it is sending to an Android or iOS phone, and change the contents accordingly? (I was hoping Google did that for us; that they mapped *their* notification keys to platform-specific ones.) – ToolmakerSteve Feb 15 '17 at 02:15
  • 1
    @AL. ... or is there a way to give FCM *both* payloads at once, and it sends the appropriate one to each phone? – ToolmakerSteve Feb 15 '17 at 02:21
  • 2
    @ToolmakerSteve Hi. You'll have to do the mapping in your own database/app server. Yes. What I was thinking here was every time a registration token is generated on the client app side, you send it to your database/app server along the type of device (i.e. `"Android"`, `"iOS"`). So that when you'll be sending messages, you'll first have to check the type of device. I did say *it's more work*, but it's a sure way to give you control over things. AFAIK, it is the developer's responsibility to keep track of the registration tokens and any details that should be associated with it. – AL. Feb 15 '17 at 02:24
  • 1
    @ToolmakerSteve There is no option to send two payloads and have FCM sort out which to send to a registration token. I'm fairly sure that there isn't a way to distinguish whether the device is Android or iOS by just depending on the registration token (hence the need of the mapping). :) – AL. Feb 15 '17 at 02:27
  • 2
    @AL. Thank you - that explains a lot. Not what I expected, given that Google says this is a "cross-platform" solution! I thought they would have some way to remap the keys, depending on what device was being sent to. Solve that problem once and for all, rather than it being solved over and over again, independently by each developer. Ah well. Especially odd given that they talk about sending messages to a **group** of devices... – ToolmakerSteve Feb 15 '17 at 02:44
  • 1
    @ToolmakerSteve You're welcome. :) If you strongly want that service and think that it would highly improve the FCM service, I suggest that you file for a [Feature Request](https://firebase.google.com/support/contact/bugs-features/). Cheers! :) – AL. Feb 15 '17 at 02:46
  • The alternate way we implemented which is imperfect actually, is. firebase messaging to topics, subscribe your device to topic and then send notification to topics with conditions, refer [this](https://medium.com/developermind/using-firebase-cloud-messaging-for-remote-notifications-in-ios-d35de1dc67b2) – Ahsaan Yousuf Nov 29 '17 at 10:35

2 Answers2

16

A recent feature was added for FCM that gives an option to provide specific params for specific platforms, called Platform Overrides:

Customizing a message across platforms

Messages sent by the FCM v1 HTTP protocol can contain two types of JSON key pairs:

  • a common set of keys to be interpreted by all app instances that receive the message.
  • platform-specific blocks of keys interpreted only by app instances running on the specified platform.
  • Platform-specific blocks give you flexibility to customize messages for different platforms to ensure that they are handled correctly when received. In many scenarios, it makes sense to use both common keys and platform-specific keys in a given message.

When to use common keys

  • Whenever you're targeting app instances on all platforms — iOS, Android, and web
  • When you are sending messages to topics

The common keys that are interpreted by all app instances regardless of platform are message.notification.title, message.notification.body, and message.data.

When to use platform-specific keys

  • When you want to send fields only to particular platforms
  • To send platform-specific fields in addition to the common keys

Whenever you want to send values to specific platforms only, don't use common keys; use platform-specific key blocks. For example, to send a notification to only iOS and web but not Android, you must use two separate blocks of keys, one for iOS and one for web.

When you are sending messages with specific delivery options, use platform-specific keys to set them. You can specify different values per platform if you want; but even when you want to set essentially the same value across platforms, you must use platform-specific keys. This is because each platform may interpret the value slightly differently — for example, time-to-live is set on Android as an expiration time in seconds, while on iOS it is set as an expiration date.

Example: notification message with platform-specific delivery options

The following v1 send request sends a common notification title and content to all platforms, but also sends some platform-specific overrides. Specifically, the request:

  • sets a long time-to-live for Android and Web platforms, while setting the APNs (iOS) message priority to a low setting
  • sets the appropriate keys to define the result of a user tap on the notification on Android and iOS — click_action, and category, respectively.
{
  "message":{
     "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
     "notification":{
       "title":"Match update",
       "body":"Arsenal goal in added time, score is now 3-0"
     },
     "android":{
       "ttl":"86400s",
       "notification"{
         "click_action":"OPEN_ACTIVITY_1"
       }
     },
     "apns": {
       "headers": {
         "apns-priority": "5",
       },
       "payload": {
         "aps": {
           "category": "NEW_MESSAGE_CATEGORY"
         }
       }
     },
     "webpush":{
       "headers":{
         "TTL":"86400"
       }
     }
   }
 }

See the HTTP v1 reference documentation for complete detail on the keys available in platform-specific blocks in the message body. For more information about building send requests that contain the message body, see Build Send Requests.

AL.
  • 36,815
  • 10
  • 142
  • 281
  • I sent 'category' in this way as you described above. but it wasn't received in "notificationContent.categoryIdentifier" Do you have any idea ? – Waqas Jul 02 '19 at 11:32
  • 2
    Thank you for a comprehensive answer, I tried this payload but unfortunately and got 400 Bad Request (to) – Ahmad Abdullah May 03 '20 at 00:54
  • I tried also to add "to" before message key, I got successfull response but unfortunately notification not received on iOS 13 – Ahmad Abdullah May 03 '20 at 00:57
  • Hey @AhmadAlselwadi I suggest posting a question with all the details you have available. Cheers! – AL. May 03 '20 at 02:06
  • Thank you @AL. Here is my question: https://stackoverflow.com/questions/61569583/firebase-notifications-received-on-ios-12-but-not-received-on-ios-13 – Ahmad Abdullah May 03 '20 at 04:31
  • how can we set badge count in this json format to set notification count on app icon in home screen – shanthan Jun 15 '20 at 11:44
  • How can i set Interactive Buttons? – Miguel Oct 17 '22 at 13:16
7

Below payload can be used as a common payload for android and iOS. "score" is just a dummy keyword for explanation and you can add more but all the values should be in String.

{
    priority: "high",
    tokens: [tokens],
    data: {
          title: <title>,
          body:<body>, <-- this data will be used by the android
          score: 345.
          },
    apns: {
      headers: {
        "apns-priority": "10"
      },
      payload: {
        aps: {          <-- payload for iOS
          alert: {
                title: <title>,
                body:<body>
               },
          data:{
               score: 345
          }
        }
      }
    }
  }

In the above payload,

  1. In android, data which is below tokens, will be used as a data payload and no need of notification for title and body as it is included in the data itself.
  2. For iOS, it requires notification tag for the iOS which is causing the problem for Android. So, it is solved by removing notification and adding the separate apns tag for the iOS and a new tag which is not given in the firebase documentation is "alert". iOS will look for apns payload and "alert" will be a substitute for the "notification".
Kunal Sale
  • 121
  • 2
  • 3