web-dev-qa-db-fra.com

Méthode correcte pour récupérer un jeton pour FCM - iOS 10 Swift 3

j'avais mis en œuvre Firebase avec FirebaseAuth/FCM, etc. et envoyé une notification avec succès via la console Firebase. 

Cependant, il me faudrait pousser la notification depuis mon propre serveur d'applications.

je me demande ci-dessous quel est le bon moyen de récupérer l'identifiant d'enregistrement de l'appareil: -

1) récupérer le jeton d'identification d'enregistrement de didRegisterForRemoteNotificationWithDeviceToken

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    var token = ""

    for i in 0..<deviceToken.count {
        token += String(format: "%02.2hhx", arguments: [deviceToken[i]])
    }

    print("Registration succeeded!")
    print("Token: ", token)
    Callquery(token)

}

2) Récupérer le jeton d'inscription de firebase (basé sur le document Firebase qui récupère le jeton d'enregistrement actuel)

let token = FIRInstanceID.instanceID().token()!

j'utilisais le premier moyen, la notification Push n'est pas reçue, même l'identifiant d'enregistrement est stocké dans la base de données de mon serveur d'applications en conséquence et j'obtiens le résultat de la session CURL: -

{"multicast_id":6074293608087656831,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"InvalidRegistration"}]}

j'avais aussi essayé la deuxième façon et obtenir une erreur fatale en exécutant l'application comme ci-dessous: -  enter image description here

apprécié si quelqu'un pouvait me montrer le bon chemin, merci!

25
aznelite89

La fonction tokenRefreshNotification n'est pas toujours appelée lors du lancement de l'application.

Cependant, lorsque je place le code dans la fonction déléguée régulière didRegisterForRemoteNotificationsWithDeviceToken, je peux obtenir le jeton à chaque fois:

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    if let refreshedToken = InstanceID.instanceID().token() {
        print("InstanceID token: \(refreshedToken)")
    }
}

(Swift 3 + Firebase 4.0.4)

44
Sam

Swift 3 + Firebase 4.0.4:

static var FirebaseToken : String? {
    return InstanceID.instanceID().token()
}
22
MBH

La méthode recommandée par Firebase:

let token = Messaging.messaging().fcmToken

Référence: Configuration d'une application client Firebase Cloud Messaging sur iOS

17
Musa almatri

Swift 4 + Firebase (5.3.0)

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    InstanceID.instanceID().instanceID(handler: { (result, error) in
        if let error = error {
            print("Error fetching remote instange ID: \(error)")
        } else if let result = result {
            print("Remote instance ID token: \(result.token)")
        }
    })
}
7
Daniyal Raza

Swift 4

Gracieuseté de: https://stackoverflow.com/a/50945350/1014164

InstanceID.instanceID().instanceID { (result, error) in
    if let error = error {
        print("Error fetching remote instange ID: \(error)")
    } else if let result = result {
        print("Remote instance ID token: \(result.token)")
    }
}
7
cohen72

Jeton de périphérique FCM Swift3

    let fcmDeviceToken = FIRInstanceID.instanceID().token()
    print("FCM token: \(fcmDeviceToken ?? "")")
6
jazzbpn

Commencez par vous inscrire à la notification d'actualisation de jeton de base de feu:

NotificationCenter.default.addObserver(self, selector: 
     #selector(tokenRefreshNotification), name:     
     NSNotification.Name.InstanceIDTokenRefresh, object: nil)

Ensuite, vous pouvez recevoir le jeton dans le sélecteur tokenRefreshNotification:

func tokenRefreshNotification(_ notification: Notification) {
    if let refreshedToken = FIRInstanceID.instanceID().token() {
      print("InstanceID token: \(refreshedToken)")
    }

    // Connect to FCM since connection may have failed when attempted before having a token.
    connectToFcm()
}
5
Naveen Ramanathan

J'avais le même problème, mais je ne pouvais pas comprendre ce qui se passait.

La didRegisterForRemoteNotificationsWithDeviceToken suggérée par @Sam s’appelle (presque) à chaque fois, c’est donc un bon travail. MAIS, il n'est pas appelé la première fois que vous ouvrez l'application avec le jeton actualisé.

Donc, pour ce scénario, vous avez toujours besoin du:

func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String) {
    print("Refreshed Token: \(fcmToken)")
}

Donc, si vous utilisez uniquement le:

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    if let fcmToken = InstanceID.instanceID().token() {
        print("InstanceID token: \(fcmToken)")
    }
}

Vous ne recevrez le "jeton actualisé" que la deuxième fois que l'utilisateur ouvre l'application.

J'ai réussi à forcer un jeton d'actualisation en désinstallant l'application et en nettoyant le dossier de construction (Produit> Nettoyer le dossier de construction). Bon pour les tests.

Idéalement, tout pourrait être géré avec la méthode de délégué messaging:didReceiveRegistrationToken, mais je n’ai pas pu le faire fonctionner. Une autre méthode pour être averti des modifications apportées au jeton FCM consiste à écouter NSNotification nommé kFIRMessagingRegistrationTokenRefreshNotification comme suggéré dans la documentation: https://firebase.google.com/docs/cloud-messaging/ios/client

2
erickva

Commencez par importer les bibliothèques telles que:

import FirebaseInstanceID
import FirebaseMessaging
import UserNotifications

set Delegate: MessagingDelegate, UNUserNotificationCenterDelegate

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, MessagingDelegate, UNUserNotificationCenterDelegate {

Écrivez ce code sur didFinishLaunching ():

 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    // Override point for customization after application launch.
    FirebaseApp.configure()
    Messaging.messaging().delegate = self

    //remote Notifications
    if #available(iOS 10.0, *) {
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { (isGranted, err) in
            if err != nil {
                //Something bad happend
            } else {
                UNUserNotificationCenter.current().delegate = self
                Messaging.messaging().delegate = self

                DispatchQueue.main.async {
                    UIApplication.shared.registerForRemoteNotifications()
                }
            }
        }
    } else {
        // Fallback on earlier versions
    }

    if #available(iOS 10, *) {
        UNUserNotificationCenter.current().requestAuthorization(options: [.badge,.sound,.alert], completionHandler: { (granted, error) in
            application.registerForRemoteNotifications()
        })
    }else{
        let notificationSettings = UIUserNotificationSettings(types: [.badge,.sound,.alert], categories: nil)
        UIApplication.shared.registerUserNotificationSettings(notificationSettings)
        UIApplication.shared.registerForRemoteNotifications()
    }

    return true
}

Ecrivez la méthode connectFCM comme suit:

func ConnectToFCM() {
    Messaging.messaging().shouldEstablishDirectChannel = true

    if let token = InstanceID.instanceID().token() {
        print("\n\n\n\n\n\n\n\n\n\n ====== TOKEN DCS: " + token)
    }

Également écrire des méthodes de délégué pour enregistrer et recevoir une notification Push:

func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String) {
    print("\n\n\n\n\n ==== FCM Token:  ",fcmToken)
    HelperFunction.helper.storeInUserDefaultForKey(name: kFCMToken, val: fcmToken)
    ConnectToFCM()
}

@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {

   // UIApplication.shared.applicationIconBadgeNumber += 1

    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "Barker"), object: nil)
}

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {

    print(userInfo)
}

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
                 fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {

    print(userInfo)

    completionHandler(UIBackgroundFetchResult.newData)
}

}

Nous pouvons maintenant le tester depuis la console firebase .  enter image description here

100% de travail, facile et testé

Remarque: 1) Activez la notification Push à partir de la section de fonctionnalité de xcode.

2) vérifiez deux fois vos deux certificats p12 téléchargés sur le paramètre de projet firebase.

3) Seul le jeton de périphérique peut être obtenu à partir d'un périphérique réel, pas d'un simulateur.

1
Mr.Javed Multani

Pour obtenir le jeton FCM actuel

if let token = Messaging.messaging().fcmToken {
    // token is current fcmToken
}

Renouveler le jeton FCM actuel

Si nous supprimons instanceId en cours, un nouveau jeton sera reçu via MessagingDelegate (message: didReceiveRegistrationToken) un moment plus tard.

InstanceID.instanceID().deleteID { (error) in
    if let er = error {
        print(er.localizedDescription)
    } else {
        print("instanceID().deleteID  success ---------------➤")
    }
}
1
Brownsoo Han