2016-05-31 13 views
9

Ho seguito il tutorial di google su https://firebase.google.com/docs/notifications/ios/console-topics#receive_and_handle_topic_messages per iscriversi a un argomento Firebase sulla mia app iOS.Impossibile ricevere notifiche push su iOS dagli argomenti di Firebase 3.2.0

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 
} 

Tuttavia, quando invio una notifica push di argomento dalla console di Firebase. Non ho potuto ricevere alcuna notifica push. Ma quando invio la notifica push al segmento utente dalla console, la spinta funziona perfettamente. Quando controllo la console Xcode, vedo questo errore FIRMessaging.

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

Ho provato a cercare questo errore ma non ho avuto fortuna a trovare nulla. Non sono sicuro che questo sia il problema che causa il mancato invio della mia app da parte della mia app.

Qualcuno ha questo problema e sa come risolverlo?

risposta

29

Sembra che tu stia chiamando lo subscribeToTopic troppo presto.

In primo luogo, prima di impostare qualsiasi chiamata Firebase, assicuratevi di chiamare

FIRApp.configure() 

Questo farà in modo che tutti i servizi Firebase siano configurate correttamente e inizializzati.

Successivamente, è necessario attendere un po 'per iscriversi agli argomenti. Il tuo cliente deve prima registrare la tua app sia con APN che con FCM per assicurarti che possa ricevere le notifiche. Ciò implica una chiamata di rete, il che significa che non puoi iscriverti agli argomenti quando la tua app viene avviata per la prima volta.

Invece, ti consiglio di inserire quel codice nel tuo gestore application:didRegisterUserNotificationSettings. Qualcosa di simile a questo:

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

Edit: E la versione Swift ...

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

Grazie Todd. Funziona perfettamente! – howly

+5

Esiste una soluzione per iOS 10 per questo? L'iscrizione a argomenti su iOS 10 non funziona. – vnchopra

+6

Per chiunque cerchi di utilizzare questo codice, è necessario abbonarsi a '/ topics/cool_users' invece di solo' cool_users' – henrikmerlander

5

Il accepted solution non ha funzionato per me. Il token non è sempre disponibile quando viene chiamato application:didRegisterUserNotificationSettings:. Ad esempio se l'applicazione è appena installata e inizia per la prima volta FIRInstanceID.instanceID().token() restituisce zero.

È necessario assicurarsi che l'applicazione chiama subscribeToTopic:dopo il il token è disponibile. Alla fine ho creato un oggetto helper che accoda le chiamate subscribeToTopic:, unsubscribeFrom: e le esegue in ordine FIFO dopo che il token è arrivato.

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 attende finché non viene visualizzato il token. AsynchronousOperation viene utilizzato come classe base per ridurre al minimo la piastra di riscaldamento.

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() 
    } 
} 

alcune cose da tenere a mente:

  • App devono chiamare FIRApp.configure() o FIRApp.configureWithOptions(_:) la preparazione prima chiamate Firebase (come Todd Kerpelman menzionato)
  • subscribeToTopic:, unsubscribeFrom: non sono thread-safe e devono essere eseguiti sul thread principale
  • I nomi degli argomenti devono essere nel formato "/ topics/*" (come henmer menzionato)
  • Assicurarsi di utilizzare diversi plist di configurazione per il debug e il rilascio dell'app Store della propria app. Vedi documentazione FIRApp.configureWithOptions(_:).
  • Data & Il tempo deve essere aggiornato, altrimenti il ​​token potrebbe non essere consegnato.
  • Assicurarsi di utilizzare the newest framework version. Ho avuto problemi con la consegna di notifica con l'SDK rilasciato intorno a gennaio 2017.
+0

Grazie per la tua indagine. Ascoltare il 'kFIRInstanceIDTokenRefreshNotification' su una nuova installazione sembra essere l'unico modo per prevenire gli errori di iscrizione degli argomenti. – ray

2

Il mio problema non è stato risolto chiamando subscribeToTopic dopo

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

invece ha funzionato chiamando subscribeToTopic dopo

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

questa funzione viene chiamata quando si riceve il token di push da APNS n Firebase.

Xcode 8.3.2

Swift 3.0