didReceiveRemoteNotification 函数不使用 FCM 通知服务器调用
didReceiveRemoteNotification function doesn't called with FCM notification server
我正在使用 FCM 服务器进行远程通知,它可以完美地发送和接收通知。
我的问题是当设备在后台时,这个函数 func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void)
没有被调用。
我尝试过的解决方案:
这个函数:
userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void)
在用户点击通知时调用。否则不触发。
正在将 "content-available": true, "priority": "high"
添加到负载中。另外,我试过这个值 "content-available": 1
.
这是我的函数代码:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
print("userInfo: \(userInfo)")
completionHandler(.newData);
}
您需要检查的第一件事是 Background Mode > Remote Notification
是否开启。如果没有,则不会在后台模式下调用。
步骤 1 – 添加框架
import UserNotifications
步骤 2 – 继承 AppDelegate
和 UNUserNotificationCenterDelegate
final class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {}
步骤 3 – 对 registerPushNotifications
进行适当的更改并将其命名为 didFinishLaunchingWithOptions
private func registerPushNotifications() {
if #available(iOS 10.0, *) {
UNUserNotificationCenter.currentNotificationCenter().delegate = self
UNUserNotificationCenter.currentNotificationCenter().requestAuthorizationWithOptions([.Badge, .Sound, .Alert], completionHandler: { granted, error in
if granted {
UIApplication.sharedApplication().registerForRemoteNotifications()
} else {
// Unsuccessful...
}
})
} else {
let userNotificationTypes: UIUserNotificationType = [.Alert, .Badge, .Sound]
let settings = UIUserNotificationSettings(forTypes: userNotificationTypes, categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(settings)
UIApplication.sharedApplication().registerForRemoteNotifications()
}
}
步骤 4 – 实施新的处理程序
// leave this for older versions
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
}
// For iOS10 use these methods and pay attention how we can get userInfo
// Foreground push notifications handler
@available(iOS 10.0, *)
func userNotificationCenter(center: UNUserNotificationCenter, willPresentNotification notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) {
if let userInfo = notification.request.content.userInfo as? [String : AnyObject] {
// Getting user info
}
completionHandler(.Badge)
}
// Background and closed push notifications handler
@available(iOS 10.0, *)
func userNotificationCenter(center: UNUserNotificationCenter, didReceiveNotificationResponse response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void) {
if let userInfo = response.notification.request.content.userInfo as? [String : AnyObject] {
// Getting user info
}
completionHandler()
}
正如您所尝试的,我相信一切,后台权限已启用,内容可用是有效负载的一部分,您还在活动状态下收到通知,最后一件事将是 Power save mode
,您需要检查省电是否关闭;就好像你 Phone 处于省电模式,然后后台刷新和其他进程在受限状态下消失,所以应用程序不会在后台调用 didReceivedNotifcation
。
您需要在后台和前台看到远程通知并在应用 运行 时显示为警报是我在我的代码中使用的 appDelegate.swift:
import Firebase
import UserNotifications
import FirebaseMessaging
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
let gcmMessageIDKey = "gcm_message_id"
var deviceID : String!
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// [START set_messaging_delegate]
Messaging.messaging().delegate = self
// [END set_messaging_delegate]
if #available(iOS 10.0, *) {
// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.current().delegate = self
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
options: authOptions,
completionHandler: {_, _ in })
} else {
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(settings)
}
application.registerForRemoteNotifications()
FirebaseApp.configure()
Fabric.sharedSDK().debug = true
return true
}
func showNotificationAlert(Title : String , Message : String, ButtonTitle : String ,window : UIWindow){
let alert = UIAlertController(title: Title, message: Message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: ButtonTitle, style: .cancel, handler: nil))
window.rootViewController?.present(alert, animated: true, completion: nil)
}
// [START receive_message] remote notification
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
// Print full message.
print(userInfo)
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
// Print full message.
print(userInfo)
completionHandler(UIBackgroundFetchResult.newData)
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("Unable to register for remote notifications: \(error.localizedDescription)")
}
// This function is added here only for debugging purposes, and can be removed if swizzling is enabled.
// If swizzling is disabled then this function must be implemented so that the APNs token can be paired to
// the FCM registration token.
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
print("APNs token retrieved: \(deviceToken)")
// With swizzling disabled you must set the APNs token here.
// Messaging.messaging().apnsToken = deviceToken
}
}
// [START ios_10_message_handling]
@available(iOS 10, *)
extension AppDelegate : UNUserNotificationCenterDelegate {
// Receive displayed notifications for iOS 10 devices.
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
let userInfo = notification.request.content.userInfo
// With swizzling disabled you must let Messaging know about the message, for Analytics
// Messaging.messaging().appDidReceiveMessage(userInfo)
// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
// Print full message.
print(userInfo)
// Change this to your preferred presentation option
completionHandler([.alert, .badge, .sound])
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
if let aps = userInfo["aps"] as? NSDictionary {
if let alert = aps["alert"] as? NSDictionary {
if let title = alert["title"] as? NSString {
let body = alert["body"] as? NSString
showNotificationAlert(Title: title as String, Message: body! as String, ButtonTitle: "Ok", window: window!)
}
} else if let alert = aps["alert"] as? NSString {
print("mohsen 6 =\(alert)")
}
}
// Print full message.
print(userInfo)
completionHandler()
}
}
// [END ios_10_message_handling]
extension AppDelegate : MessagingDelegate {
// [START refresh_token]
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
print("Firebase registration token: \(fcmToken)")
deviceID = fcmToken
let dataDict:[String: String] = ["token": fcmToken]
NotificationCenter.default.post(name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict)
// TODO: If necessary send token to application server.
// Note: This callback is fired at each app startup and whenever a new token is generated.
}
// [END refresh_token]
// [START ios_10_data_message]
// Receive data messages on iOS 10+ directly from FCM (bypassing APNs) when the app is in the foreground.
// To enable direct data messages, you can set Messaging.messaging().shouldEstablishDirectChannel to true.
func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) {
print("Received data message: \(remoteMessage.appData)")
}
// [END ios_10_data_message]
}
如果您使用 Postman 进行测试,请尝试将 "content-available": true
更改为 "content_available" : true
。 content-available 将发送通知,但不会调用 didReceiveRemoteNotification
。
只是添加已接受的答案:在我的情况下,问题是相同的,但是当我通过 http "POST" NSMUtableRequest
发送通知时,应用已接受的答案的方法是将其实际添加到通知中参数以及声音、徽章、瓷砖等。
let postParams: [String : Any] = [
"to": receiverToken,
"notification": [
"badge" : 1,
"body": body,
"title": title,
"subtitle": subtitle,
"sound" : true, // or specify audio name to play
"content_available": true, // this will call didReceiveRemoteNotification in receiving app, else won't work
"priority": "high"
],
"data" : [
"data": "ciao",
]
]
希望这也能帮助其他人,因为我花了很长时间试图弄清楚如何应用这个解决方案。
非常感谢。
我正在使用 FCM 服务器进行远程通知,它可以完美地发送和接收通知。
我的问题是当设备在后台时,这个函数 func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void)
没有被调用。
我尝试过的解决方案:
这个函数:
userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void)
在用户点击通知时调用。否则不触发。
正在将
"content-available": true, "priority": "high"
添加到负载中。另外,我试过这个值"content-available": 1
.这是我的函数代码:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
print("userInfo: \(userInfo)")
completionHandler(.newData);
}
您需要检查的第一件事是 Background Mode > Remote Notification
是否开启。如果没有,则不会在后台模式下调用。
步骤 1 – 添加框架
import UserNotifications
步骤 2 – 继承 AppDelegate
和 UNUserNotificationCenterDelegate
final class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {}
步骤 3 – 对 registerPushNotifications
进行适当的更改并将其命名为 didFinishLaunchingWithOptions
private func registerPushNotifications() {
if #available(iOS 10.0, *) {
UNUserNotificationCenter.currentNotificationCenter().delegate = self
UNUserNotificationCenter.currentNotificationCenter().requestAuthorizationWithOptions([.Badge, .Sound, .Alert], completionHandler: { granted, error in
if granted {
UIApplication.sharedApplication().registerForRemoteNotifications()
} else {
// Unsuccessful...
}
})
} else {
let userNotificationTypes: UIUserNotificationType = [.Alert, .Badge, .Sound]
let settings = UIUserNotificationSettings(forTypes: userNotificationTypes, categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(settings)
UIApplication.sharedApplication().registerForRemoteNotifications()
}
}
步骤 4 – 实施新的处理程序
// leave this for older versions
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
}
// For iOS10 use these methods and pay attention how we can get userInfo
// Foreground push notifications handler
@available(iOS 10.0, *)
func userNotificationCenter(center: UNUserNotificationCenter, willPresentNotification notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) {
if let userInfo = notification.request.content.userInfo as? [String : AnyObject] {
// Getting user info
}
completionHandler(.Badge)
}
// Background and closed push notifications handler
@available(iOS 10.0, *)
func userNotificationCenter(center: UNUserNotificationCenter, didReceiveNotificationResponse response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void) {
if let userInfo = response.notification.request.content.userInfo as? [String : AnyObject] {
// Getting user info
}
completionHandler()
}
正如您所尝试的,我相信一切,后台权限已启用,内容可用是有效负载的一部分,您还在活动状态下收到通知,最后一件事将是 Power save mode
,您需要检查省电是否关闭;就好像你 Phone 处于省电模式,然后后台刷新和其他进程在受限状态下消失,所以应用程序不会在后台调用 didReceivedNotifcation
。
您需要在后台和前台看到远程通知并在应用 运行 时显示为警报是我在我的代码中使用的 appDelegate.swift:
import Firebase
import UserNotifications
import FirebaseMessaging
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
let gcmMessageIDKey = "gcm_message_id"
var deviceID : String!
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// [START set_messaging_delegate]
Messaging.messaging().delegate = self
// [END set_messaging_delegate]
if #available(iOS 10.0, *) {
// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.current().delegate = self
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
options: authOptions,
completionHandler: {_, _ in })
} else {
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(settings)
}
application.registerForRemoteNotifications()
FirebaseApp.configure()
Fabric.sharedSDK().debug = true
return true
}
func showNotificationAlert(Title : String , Message : String, ButtonTitle : String ,window : UIWindow){
let alert = UIAlertController(title: Title, message: Message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: ButtonTitle, style: .cancel, handler: nil))
window.rootViewController?.present(alert, animated: true, completion: nil)
}
// [START receive_message] remote notification
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
// Print full message.
print(userInfo)
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
// Print full message.
print(userInfo)
completionHandler(UIBackgroundFetchResult.newData)
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("Unable to register for remote notifications: \(error.localizedDescription)")
}
// This function is added here only for debugging purposes, and can be removed if swizzling is enabled.
// If swizzling is disabled then this function must be implemented so that the APNs token can be paired to
// the FCM registration token.
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
print("APNs token retrieved: \(deviceToken)")
// With swizzling disabled you must set the APNs token here.
// Messaging.messaging().apnsToken = deviceToken
}
}
// [START ios_10_message_handling]
@available(iOS 10, *)
extension AppDelegate : UNUserNotificationCenterDelegate {
// Receive displayed notifications for iOS 10 devices.
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
let userInfo = notification.request.content.userInfo
// With swizzling disabled you must let Messaging know about the message, for Analytics
// Messaging.messaging().appDidReceiveMessage(userInfo)
// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
// Print full message.
print(userInfo)
// Change this to your preferred presentation option
completionHandler([.alert, .badge, .sound])
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
if let aps = userInfo["aps"] as? NSDictionary {
if let alert = aps["alert"] as? NSDictionary {
if let title = alert["title"] as? NSString {
let body = alert["body"] as? NSString
showNotificationAlert(Title: title as String, Message: body! as String, ButtonTitle: "Ok", window: window!)
}
} else if let alert = aps["alert"] as? NSString {
print("mohsen 6 =\(alert)")
}
}
// Print full message.
print(userInfo)
completionHandler()
}
}
// [END ios_10_message_handling]
extension AppDelegate : MessagingDelegate {
// [START refresh_token]
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
print("Firebase registration token: \(fcmToken)")
deviceID = fcmToken
let dataDict:[String: String] = ["token": fcmToken]
NotificationCenter.default.post(name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict)
// TODO: If necessary send token to application server.
// Note: This callback is fired at each app startup and whenever a new token is generated.
}
// [END refresh_token]
// [START ios_10_data_message]
// Receive data messages on iOS 10+ directly from FCM (bypassing APNs) when the app is in the foreground.
// To enable direct data messages, you can set Messaging.messaging().shouldEstablishDirectChannel to true.
func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) {
print("Received data message: \(remoteMessage.appData)")
}
// [END ios_10_data_message]
}
如果您使用 Postman 进行测试,请尝试将 "content-available": true
更改为 "content_available" : true
。 content-available 将发送通知,但不会调用 didReceiveRemoteNotification
。
只是添加已接受的答案:在我的情况下,问题是相同的,但是当我通过 http "POST" NSMUtableRequest
发送通知时,应用已接受的答案的方法是将其实际添加到通知中参数以及声音、徽章、瓷砖等。
let postParams: [String : Any] = [
"to": receiverToken,
"notification": [
"badge" : 1,
"body": body,
"title": title,
"subtitle": subtitle,
"sound" : true, // or specify audio name to play
"content_available": true, // this will call didReceiveRemoteNotification in receiving app, else won't work
"priority": "high"
],
"data" : [
"data": "ciao",
]
]
希望这也能帮助其他人,因为我花了很长时间试图弄清楚如何应用这个解决方案。 非常感谢。