通过 FCM 的 iOS 严重警报

Posted

技术标签:

【中文标题】通过 FCM 的 iOS 严重警报【英文标题】:iOS critical alert through FCM 【发布时间】:2018-10-05 03:36:58 【问题描述】:

ios 12 添加了严重警报。 APNS 有效负载具有 sound dictionary 以支持关键警报。 FCM 有效负载中是否有等效的声音字典支持以将 FCM 通知发送到 iOS 设备。

【问题讨论】:

看起来现在完全支持了。 firebase.google.com/docs/cloud-messaging/… 见表 2a。 你设法让它运行了吗?我们尝试了所有可能性,但无法让它覆盖静音模式。我们用普通的 APNS 让它运行,但我们需要使用 FCM。声音字典必须有什么确切的格式?谷歌为旧版 http 描述的那个不起作用! 你必须使用firebase的api http v1。旧版 API 不支持严重警报 firebase.google.com/docs/cloud-messaging/migrate-v1 【参考方案1】:

回答我自己的问题。

由于 FCM 有效负载不支持 iOS 声音字典,我不得不依靠通知扩展来实现这一点。我将设置为 1 的“关键”标志作为 FCM 数据负载的一部分发送,并在通知扩展中使用它来将通知标记为关键。

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)
        
    

【讨论】:

这可能是一种解决方法,但您能否确认您发送了丰富的推送,因此必须将 mutable-content 设置为 true 才能正常工作? @Mallox 是的,我们必须将mutable-content 设置为true。没有那个服务扩展不会被调用。 更新 Firebase 现在支持添加关键警报字典。看这里firebase.google.com/docs/cloud-messaging/…【参考方案2】:

firebase 现在添加了严重警报。

可以像这样添加到 MessagingPayload 中:

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

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

文档可能有点混乱。您必须使用messaging().send() 并在payload 中编码令牌,而不是使用messaging().sendToDevice()。

payload 消息是一个 TokenMessage https://firebase.google.com/docs/reference/admin/node/admin.messaging.TokenMessage

附言

您还需要从 Apple 获得授权,然后才能使用严重警报: https://developer.apple.com/contact/request/notifications-critical-alerts-entitlement/

【讨论】:

【参考方案3】:

FCM 中目前没有声音字典支持,相当于 iOS 的声音字典。我相信您已经知道,当谈到声音时,带有 APN 的 FCM 的对应物 sound 参数:

设备收到通知时播放的声音。

声音文件可以位于客户端应用的主包中,也可以位于应用数据容器的 Library/Sounds 文件夹中。请参阅iOS Developer Library 了解更多信息。

但是,从UNNotificationSound 文档中阅读,也许您可​​以尝试添加一个包含标识符(例如"isCritical": "true")的data 消息有效负载,然后让您的应用根据需要处理它。

【讨论】:

根据您的建议并使用 iOS 通知扩展,我能够实现关键警报功能。 @ShashidharYamsani 听起来棒极了!干杯!【参考方案4】:

可以使用新的api:

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)

【讨论】:

以上是关于通过 FCM 的 iOS 严重警报的主要内容,如果未能解决你的问题,请参考以下文章

对OneSignal的严重警报支持不起作用

通过 FCM 发送推送通知时何时使用 iOS 设备令牌?

FCM 通过 fcm 控制台向我的 ios 设备发送通知,但从 php 服务它没有发送通知

Android - 通过活动启动 Firebase 消息传递 (FCM) 的某种方式?

iOS 无法通过 FCM 接收推送通知(可以通过 APNs)

通过 FCM 发送时未收到推送通知,但在 IOS 上通过 APN 发送时收到