[英]Firebase Cloud Messaging iOS: No background push notification
使用較新的 Firebase 雲消息傳遞和方法 swizzling,當我的應用程序處於前台時,我能夠成功地在我的應用程序委托中的didReceiveRemoteNotification
方法中接收有效負載。 但是,我沒有收到任何類型的有效負載,並且當我的應用程序處於后台時, didReceiveRemoteNotification
不會被調用,盡管消息已成功發送的 api 響應(見下文)
這是我發送到 FCM api 以觸發推送通知的請求https://fcm.googleapis.com/fcm/send
{
"to": "{valid-registration-token}",
"priority":"high", //others suggested setting priority to high would fix, but did not
"notification":{
"body":"Body3",
"title":"test"
}
}
來自 FCM 的回應
{
"multicast_id": 6616533575211076304,
"success": 1,
"failure": 0,
"canonical_ids": 0,
"results": [
{
"message_id": "0:1468906545447775%a4aa0efda4aa0efd"
}
]
}
這是我的 appDelegate 代碼
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
Fabric.with([Crashlytics.self])
FIRApp.configure()
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.tokenRefreshNotification),
name: kFIRInstanceIDTokenRefreshNotification, object: nil)
return true
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
// Let FCM know about the message for analytics etc.
FIRMessaging.messaging().appDidReceiveMessage(userInfo)
// Print full message.
print("%@", userInfo)
// handle your message
// let localNotification = UILocalNotification()
// localNotification.fireDate = NSDate()
// let notification = userInfo["notification"]!
// localNotification.alertBody = notification["body"] as? String
// localNotification.alertTitle = notification["title"] as? String
// localNotification.timeZone = NSTimeZone()
// application.scheduleLocalNotification(localNotification)
}
func tokenRefreshNotification(notification: NSNotification) {
let refreshedToken = FIRInstanceID.instanceID().token()!
print("InstanceID token: \(refreshedToken)")
LoginVC.registerForPushNotifications()
connectToFcm()
}
//foreground messages
func applicationDidBecomeActive(application: UIApplication) {
connectToFcm()
}
// [START disconnect_from_fcm]
func applicationDidEnterBackground(application: UIApplication) {
FIRMessaging.messaging().disconnect()
print("Disconnected from FCM.")
}
func connectToFcm() {
FIRMessaging.messaging().connectWithCompletion { (error) in
if (error != nil) {
print("Unable to connect with FCM. \(error)")
} else {
print("Connected to FCM.")
}
}
}
}
我在我的應用程序的稍后流程中調用此代碼以請求權限
static func registerForPushNotifications() {
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(settings)
UIApplication.sharedApplication().registerForRemoteNotifications()
}
由於我能夠在應用程序處於前台時收到通知,因此我認為這將消除所有關於我的 apns 證書未上傳或注冊令牌不正確的擔憂。 如果不是這種情況,請發表評論,我會再次進入那個兔子洞。 我可能忽略了一些簡單的事情,但是如何在應用程序處於后台時顯示通知? 謝謝
顯然,(盡管使用應該自動執行的方法調配)您仍然必須在 Firebase 實例上設置 APNS 令牌。 因此,這意味着您還必須使用類似的方法實現didRegisterForRemoteNOtificationsWithDeviceToken
方法
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
// set firebase apns token
FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenType.Unknown)
}
作為補充說明。 使用"priority":"high"
對測試很有用,因為它會立即發送通知。
至少對於我的應用程序而言,所需的行為是推送通知的到達,其中 PN(推送通知)的內容應顯示在應用程序的所需頁面中。
我有 PN 可以到達的三種不同的應用程序狀態:(當然這取決於您的實現,但您應該了解蘋果在這些狀態下如何處理 PN)
(行為由蘋果決定!)
1)應用程序在前台:
在這種情況下,應用程序始終處理 PN
2)應用程序在后台:
在這種情況下,應用程序始終處理 PN
3)應用程序被殺死/關閉:
現在有三種可能的方式
滑動通知 -> 應用程序不會處理 PN
直接通過啟動器圖標打開應用程序 -> 應用程序不會處理 PN
點擊通知 -> PN 將由應用程序處理
對於這種情況,如果用戶沒有通過點擊通知打開應用程序,則無法獲取通知數據。
要獨立於應用程序狀態,您需要設置一個服務器,您可以在其中請求特定數據。 例如,您有一個顯示所有通知的視圖,您需要一個 API 來請求特定數據。 您不應該在 Pushnotification 的接收方法中處理數據。
我希望能幫助別人!
與 Daniel George 的解決方案類似,我可以通過以下方式解決我的問題:
Messaging.messaging().apnsToken = deviceToken
FirebaseInstanceID 2.0.8,FirebaseMessaging 2.0.8
確保您在 JSON 負載中添加了 "content_available" : true 。 否則您將不會在后台模式下收到推送通知。
"notification" : {
"body" : "this is body",
"title" : "this is title"
}
"content_available" : true
從 FCM 獲取成功令牌后,請按照以下步驟使用 FCM 啟用后台有效負載數據獲取:
打開 Project Navigator > AppCapabilities > Background Modes > 檢查遠程通知
在 App.delegate 中定義:
func application(_ application: UIApplication,didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { print("userinfo in background mode on-\\(userInfo)") completionHandler(UIBackgroundFetchResult.newData) }
根據蘋果指南正確格式化您的有效負載: 在此處輸入鏈接描述
不要忘記添加鍵值對: {"content-available":1}
除非您無法在后台獲取有效負載。
現在嘗試使用 FCM 令牌再次發送通知。 祝你編碼愉快
我一直在努力理解為什么我的 iOS14 通知沒有通過。 Firebase 文檔中沒有提到這一點。
在 2020 年 12 月的 iOS14 上,我可以確認@Daniel George 的解決方案仍然有效並修復了我的通知無法通過的問題。 使用更新的語法重新發布。
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { Messaging.messaging().apnsToken = deviceToken }
iOS14.1、Swift 5.3、Firebase 和 Firebase Cloud Messaging 於 2020 年 12 月 18 日更新。
AFAIK,對於 ios,您將無法使用 FCM 為處於后台或已終止狀態的應用程序發送推送通知消息。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.