4

我正嘗試使用FCM令牌從Firebase通知控制檯向特定設備發送簡單的推送通知。 Firebase通知控制檯顯示通知已發送,但設備未收到通知。我已嘗試發送通知,然後等待查看控制檯是否從didReceiveRemoteNotification登錄,但通知耗時過長(小時)顯示爲在Firebase控制檯中發送(即使將優先級設置爲high)。Firebase通知到設備使用FCM令牌說已發送但未收到

應用代表

import UIKit 
import Firebase 
import FirebaseStorage 
import FirebaseDatabase 
import FirebaseMessaging 
import CoreData 
import UserNotifications 

@UIApplicationMain 
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate { 

    var window: UIWindow? 

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 
     // Override point for customization after application launch. 

     // Use Firebase library to configure APIs 
     FirebaseApp.configure() 

     ///// 
     // For Firebase Cloud Messaging (FCM) 
     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() 
     // End of [for Firebase Cloud Messaging (FCM)] 
     ///// 

     return true 
    } 

    /////////////////////// 
    // FCM Setup 

    // Monitor token generation for FCM: Be notified whenever the FCM token is updated 
    func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String) { 
     print("Firebase registration token: \(fcmToken)") 
    } 

    // Monitor token generation for FCM: 
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { 
     Messaging.messaging().apnsToken = deviceToken 
    } // Handle messages received through the FCM APNs interface 
    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) { 
     print("didReceiveRemoteNotification") 
     // If you are receiving a notification message while your app is in the background, 
     // this callback will not be fired till the user taps on the notification launching the application. 
     // TODO: Handle data of notification 

     // With swizzling disabled you must let Messaging know about the message, for Analytics 
     // Messaging.messaging().appDidReceiveMessage(userInfo) 

     // Print message ID. 
     // gcm_message_id 
     if let messageID = userInfo["gcmMessageIDKey"] { 
      print("Message ID: \(messageID)") 
     } 

^我的猜測是,這個問題可能與「gcm_message_id」 /「gcmMessageId」 /「gcm.message_id」做,因爲它在每個不同三種方法我試過下面

 // Print full message. 
     print(userInfo) 
    } 

    // Handle messages received through the FCM APNs interface 
    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { 
     print("didReceiveRemoteNotification (withCompletionHandeler)") 
     // If you are receiving a notification message while your app is in the background, 
     // this callback will not be fired till the user taps on the notification launching the application. 
     // TODO: Handle data of notification 

     // 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)") 
     } 

^我的猜測是,這個問題可能與「gcm_message_id」 /「gcmMessageId」 /「gcm.message_id」做,因爲它是不同的我n各自的三種方法我試過下面

 // Print full message. 
     print(userInfo) 

     completionHandler(UIBackgroundFetchResult.newData) 
    } 

    // End of [FCM Setup] 
    /////////////////////// 
} 

視圖控制器

class ViewController: UIViewController { 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     // Retrieve the current registration token for Firebase Cloud Messaging (FCM) 
     let token = Messaging.messaging().fcmToken 
     print("FCM token: \(token ?? "")") 
     } 
} 

應享權利&啓用推送通知

我已經加入了推送權利see here和啓用後臺模式推送通知see here和adde d將GoogleService-Info.plist添加到我的項目中。

發送通知

我創建從火力地堡通知控制檯通知(如下圖所示),所以應該沒有問題與通知本身的結構

方法。 enter image description here

我曾嘗試以下方法來解決這個問題,但都產生相同的結果:

有誰知道爲什麼通知被標記爲已發送Firebase通知控制檯但未顯示在設備上?

+0

請檢查以下內容:1.您是否添加了推送權利? 2.你添加了GoogleService-Info.plist嗎? –

+0

@ jn-se,感謝您的評論。我添加了推送權利(併爲推送通知啓用了後臺模式),並將GoogleService-Info.plist添加到了我的項目中。我已將屏幕截圖添加到上述問題 – Rbar

+0

除權利外:1。 「但通知需要很長時間才能顯示爲在Firebase控制檯中發送(即使我將優先級設置爲高)。」< - 首先解決此問題。它不應該是這樣的。 2.確保你沒有收到註冊令牌的任何錯誤3.然後編輯你的問題,並添加有效載荷的確切**結構**以及它的外觀。很多時候,有效載荷的結構是錯誤的,因此你什麼也得不到! – Honey

回答

4

一對夫婦與推送通知工作時,我使用的故障排除步驟是:

  1. 獲取推動工作獨立於火力服務第一。我使用這個tool.
  2. 確保你沒有任何包標識符命名空間衝突。因此,例如,在appstore構建,testflight構建和/或在設備上開發構建應用程序的任何組合。刪除所有應用程序的一個實例。包標識符是您的設備知道將推送通知路由到哪個應用程序的方式。
  3. 當其他所有事情都失敗時 - 我嘗試通過構建一個新的示例項目並將其與新的Firebase項目掛鉤來查看是否可以將我的注意力縮小到僅僅能夠在沒有任何其他業務的情況下進行推送工作我的應用程序的邏輯。這有助於我向自己證明自己並沒有瘋狂,並向我證明,這並不是一種神祕的網絡狀況,導致我的困境。

我希望這可以幫助你,因爲你工作得到它所有的想法。

+2

感謝您的疑難解答提示!奇怪的是,從手機中刪除應用程序,然後從XCode再次運行/安裝解決了它。代碼本身沒有什麼必須改變,現在通知按預期工作。獨自搭建快速啓動項目也有助於防止我感覺自己完全瘋了,因爲它按預期工作,並且具有與我自己相同的代碼(https://github.com/firebase/quickstart- IOS /斑點/主/消息/ MessagingExampleSwift/AppDelegate.swift)。再次感謝提示,並希望答案/問題/評論可以幫助其他人! – Rbar

+1

很高興幫助!與您的項目的其餘部分祝你好運。 – Doug

0

有誰知道爲什麼通知被標記爲在Firebase通知控制檯中發送但未在設備上顯示?

因爲「發送」並不意味着「收到」。

通知不能保證在設備上收到。使用基本的APNS基礎設施,如果在設備上收到或處理了通知,您甚至無法獲取信息。

如果在設備上沒有收到成功發送的消息,可能有很多原因。此外,即使您收到Firebase令牌,這並不意味着您的設備可以在任何情況下收到通知。

要隔離這個問題,我建議建立最小化的設置並使用沒有Firebase的APNS。您可以使用Terminal或NWPusher(https://github.com/noodlewerk/NWPusher)從本地macOS系統發送通知,並使用iOS本地遠程推送通知框架接收通知。

保持照顧到APNS設備令牌轉換爲提交的通知所要求的正確格式:

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { 

    let token = deviceToken.hexEncodedString() 
    print("Token: \(token)") 
} 

數據擴展:

extension Data { 
    func hexEncodedString() -> String { 
     return map { String(format: "%02hhx", $0) }.joined() 
    } 
} 
+0

我欣賞所有建議,但如果我理解正確,你建議我根本不使用Firebase通知,這在我的情況下不是一個選項 – Rbar

+0

它是一個用於調試以識別問題的好選擇。如果它在APNS設置最小的情況下無法使用,則在配置或應用程序設置時會出現錯誤。如果運行良好,錯誤與Firebase設置或推送有效負載有關,但應用程序配置正確。 –

0

我看到你在你的項目的Capabilities所做的一切。

幾點:

  • 順應你的類messaging delegate像這樣:

    Messaging.messaging().delegate = self 
    
  • 確保您已設置您的證書正確和上載火力地堡推送通知的配置一切(不準確術語)。

  • 我已經完成了幾個使用Firebase推送通知服務的應用程序,並且從頭開始創建一個示例應用程序可能會幫助您瞭解您做錯了什麼。

And ...這是一個更好的代碼塊,用於註冊您的推送通知應用程序。

// Setup Push Notifications 

    if #available(iOS 10.0, *) { 
     let center = UNUserNotificationCenter.current() 
     center.delegate = self 
     center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in 
      if error == nil{ 
       DispatchQueue.main.async(execute: { 
        application.registerForRemoteNotifications() 
       }) 
      } 
     } 
    } 
    else { 
     let notificationTypes: UIUserNotificationType = [.sound, .alert, .badge] 
     let notificationSettings = UIUserNotificationSettings(types: notificationTypes, categories: nil) 
     application.registerForRemoteNotifications() 
     application.registerUserNotificationSettings(notificationSettings) 
    } 
相關問題