2016-05-31 123 views
9

我按照https://firebase.google.com/docs/notifications/ios/console-topics#receive_and_handle_topic_messages上的谷歌教程訂閱了我的iOS應用中的Firebase主題。無法接收來自Firebase 3.2.0主題的iOS推送通知

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool { 

    FIRMessaging.messaging().subscribeToTopic("/topics/Notifications") 

    let homeViewController = UINavigationController(rootViewController: HomeViewController()) 

    UINavigationBar.appearance().translucent = false 
    window = UIWindow(frame: UIScreen.mainScreen().bounds) 
    window?.rootViewController = homeViewController 

    window?.makeKeyAndVisible() 
    return true 
} 

但是,當我從Firebase控制檯發送主題推送通知時。我無法收到任何推送通知。但是當我從控制檯發送推送通知給用戶段時,推送工作正常。當我檢查Xcode控制檯時,我看到這個FIRMessaging錯誤。

2016-05-31 11:11:47.893: <FIRMessaging/WARNING> Cannot subscribe to topic: /topics/Notifications with token: (null) 

我試圖尋找這個錯誤,但沒有找到任何運氣。我不確定這是否是導致我的應用程序無法接收任何主題的問題。

有沒有人有這個問題,並知道如何解決它?

回答

29

看起來也許你打電話subscribeToTopic太早。

首先,你設置任何火力地堡電話之前,請確保您撥打

FIRApp.configure() 

這將確保所有的火力地堡服務設置正確和初始化。

接下來,您將需要稍等一點才能訂閱主題。您的客戶需要先向APN和FCM註冊您的應用程序,以確保它可以接收通知。這涉及網絡調用,這意味着您的應用首次啓動時無法訂閱主題。

相反,我建議將代碼放入application:didRegisterUserNotificationSettings處理程序中。事情是這樣的:

- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings { 
    NSLog(@"Hooray! I'm registered!"); 
    [[FIRMessaging messaging] subscribeToTopic:@"/topics/cool_users"]; 
} 

編輯:和斯威夫特版本...

func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) { 
    print("Hooray! I'm registered!") 
    FIRMessaging.messaging().subscribeToTopic("/topics/swift_fans") 
} 
+0

感謝託德。它工作完美! – howly

+5

是否有iOS 10的解決方案?在iOS 10上訂閱主題不起作用。 – vnchopra

+6

對於任何人試圖使用這段代碼,你應該訂閱'/ topics/cool_users'而不是'cool_users' – henrikmerlander

5

accepted solution並沒有爲我工作。調用application:didRegisterUserNotificationSettings:時令牌不總是可用。 例如,如果應用程序是新安裝的並且第一次啓動FIRInstanceID.instanceID().token()返回nil。

您需要確保應用程序調用subscribeToTopic:令牌可用。 我最終創建了一個幫助程序對象,它在入口令牌到達後排隊subscribeToTopic:unsubscribeFrom:調用並以FIFO的順序執行它們。

class FIRMessagingHelper { 

    private let queue: OperationQueue 

    init() { 
     queue = OperationQueue() 
     queue.maxConcurrentOperationCount = 1 
     queue.addOperation(TokenReadyOperation()) 
    } 

    func subscribeTo(topic: String) { 
     queue.addOperation { 
      OperationQueue.main.addOperation({ 
       FIRMessaging.messaging().subscribeToTopic(topic) 
      }) 
     } 
    } 

    func unsubscribeFrom(topic: String) { 
     queue.addOperation { 
      OperationQueue.main.addOperation({ 
       FIRMessaging.messaging().unsubscribeFromTopic(topic) 
      }) 
     } 
    } 
} 

TokenReadyOperation等待,直到出現令牌。 AsynchronousOperation被用作基本類來最小化樣板。

class TokenReadyOperation : AsynchronousOperation { 

    override init() { 
     super.init() 
     NotificationCenter.default.addObserver(self, 
               selector: #selector(TokenReadyOperation.tokenRefreshed(notification:)), 
               name: .firInstanceIDTokenRefresh, 
               object: nil) 
    } 

    override func didStart() { 
     finishIfTokenAvailable() 
    } 

    private func finishIfTokenAvailable() { 
     guard FIRInstanceID.instanceID().token() != nil else { return } 
     markFinished() 
    } 

    /// Posted every time token changes 
    @objc private func tokenRefreshed(notification: Notification) { 
     finishIfTokenAvailable() 
    } 
} 

幾件事情要記住:

  • 應用程序必須調用FIRApp.configure()FIRApp.configureWithOptions(_:)之前作出任何火力地堡呼叫(如Todd Kerpelman提到)
  • subscribeToTopic:unsubscribeFrom:不是線程安全的,必須執行主線程
  • 主題名稱必須爲「/ topics/*」格式(如提及的henmer
  • 請確保使用不同的配置plist進行應用程序的調試和App Store發佈。請參閱FIRApp.configureWithOptions(_:)文檔。
  • 日期&時間應該是最新的,否則令牌可能無法交付。
  • 請務必使用the newest framework version。我曾與通知傳遞的問題與2017年左右月份發佈的SDK
+0

感謝您的調查。在全新安裝中監聽「kFIRInstanceIDTokenRefreshNotification」似乎是防止主題訂閱失敗的唯一方法。 – ray

2

我的問題是無法通過調用subscribeToTopic解決後

func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) {

而是

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { 
後曾致電 subscribeToTopic

當您從APNS獲得您的推送令牌時,此功能會被調用篝火基地。

的Xcode 8.3.2

雨燕3.0