3

iOS 12 has added critical alerts. The APNS payload has the sound dictionary to support critical alerts. Is there an equivalent sound dictionary support in FCM payload to send FCM notifications to iOS devices.

AL.
  • 36,815
  • 10
  • 142
  • 281
  • 1
    Looks like it is now fully supported. https://firebase.google.com/docs/cloud-messaging/http-server-ref#notification-payload-support See Table 2a. – ts3v1n Mar 27 '19 at 10:02
  • Did you manage to get it running? We tried all possibilities but could not get it to override silent mode. We got it running with plain APNS, but we need to use FCM.What exact format does the sound dictionary have to have? The one google describes for legacy http does not work! – AndyB Jun 25 '19 at 19:37
  • 1
    You have to use api http v1 of firebase. Critical alerts is not supported on legacy api https://firebase.google.com/docs/cloud-messaging/migrate-v1 – Mallox Aug 06 '19 at 11:38

4 Answers4

6

Critical alerts have now been added by firebase.

It can be added to the MessagingPayload like this:

const messagingPayload = {
  token: this.FCMToken,
  notification: {
    ...payload,
  },
  apns: {
    payload: {
      aps: {
        criticalSound: {
          critical: true,
          name: 'default',
          volume: 1.0,
        },
      },
    },
  },
};

return admin.messaging().send(messagingPayload);

The docs can be a little confusing. You have to use messaging().send() and encode the token in the payload, instead of using messaging().sendToDevice().

The payload message is a TokenMessage https://firebase.google.com/docs/reference/admin/node/admin.messaging.TokenMessage

p.s.

You also need to get an entitlement from Apple before you can use critical alerts: https://developer.apple.com/contact/request/notifications-critical-alerts-entitlement/

3

Answering my own question.

I had to rely on notification extension to do the magic as the FCM payload doesn't support the iOS sound dictionary. I send the "critical" flag set to 1 as part of FCM data payload and use it in notification extension to mark a notification as critical.

class NotificationService: UNNotificationServiceExtension {
    var contentHandler: ((UNNotificationContent) -> Void)?
    var bestAttemptContent: UNMutableNotificationContent?

    override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
       self.contentHandler = contentHandler
       bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
       let userInfo: [AnyHashable : Any] = (bestAttemptContent?.userInfo)!
       if let apsInfo = userInfo["aps"] as? [AnyHashable: Any], let bestAttemptContent = bestAttemptContent, let critical =  userInfo["critical"] as? String, Int(critical)! == 1 {
            //critical alert try to change the sound if sound file is sent in notificaiton.
            if let sound = apsInfo["sound"] as? String {
                //sound file is present in notification. use it for critical alert..
                bestAttemptContent.sound =
                    UNNotificationSound.criticalSoundNamed(UNNotificationSoundName.init(sound),
                                                           withAudioVolume: 1.0)
            } else {
                //sound file not present in notifiation. use the default sound.
                bestAttemptContent.sound =
                                UNNotificationSound.defaultCriticalSound(withAudioVolume: 1.0)
            }
            contentHandler(bestAttemptContent)
        }
    }
}
  • This can be a workaround but can you confirm that you send a rich push and thus have to set `mutable-content` to `true` for this to work ? – Mallox Jan 07 '19 at 21:15
  • 1
    @Mallox Yes, we have to set `mutable-content` to `true`. With out that the service extension is not called. – Shashidhar Yamsani Jan 08 '19 at 15:01
  • 1
    Update Firebase now supports adding critical alerts dictionary. see here https://firebase.google.com/docs/cloud-messaging/http-server-ref#notification-payload-support – Mudassir Zulfiqar Oct 22 '19 at 13:28
1

There is currently no sound dictionary support in FCM which is equivalent to iOS' sound dictionary. As I'm sure you're already aware of, the counterpart of FCM with APNs' when it comes to sound is the sound parameter:

The sound to play when the device receives the notification.

Sound files can be in the main bundle of the client app or in the Library/Sounds folder of the app's data container. See the iOS Developer Library for more information.

However, reading from the UNNotificationSound docs, maybe you could try adding a data message payload that contains an identifier (e.g. "isCritical": "true") then have your app handle it as needed.

Community
  • 1
  • 1
AL.
  • 36,815
  • 10
  • 142
  • 281
0

Using new api is possible:

import firebase_admin
from firebase_admin import credentials
from firebase_admin import messaging

#for generate credential use this tutorial: https://medium.com/@ThatJenPerson/authenticating-firebase-cloud-messaging-http-v1-api-requests-e9af3e0827b8
cred = credentials.Certificate("/dir-your-credential/credentical.json")
firebase_admin.initialize_app(cred)


# This registration token comes from the client FCM SDKs.
registration_token = 'example-YynJsQ96UFvhER7mBeYD6'

# See documentation on defining a message payload.
message = messaging.Message(
    notification=messaging.Notification(
      body = 'Hi body message \uD83D\uDEA9',
      title = 'Title Push'
     ),
    apns=messaging.APNSConfig(
        payload=messaging.APNSPayload(
            aps=messaging.Aps(badge=2, sound=messaging.CriticalSound(critical=True, name="your-song-alert.wav", volume=0.8)),
        ),
    ),
    token=registration_token,
)

# Send a message to the device corresponding to the provided
# registration token.
response = messaging.send(message)
# Response is a message ID string.
print('Successfully sent message:', response)