Je tente d'envoyer une notification Push simple à partir de la console de notification firebase à un périphérique spécifique à l'aide d'un jeton FCM. La console de notification de Firebase indique que la notification a été envoyée, mais que le périphérique ne la reçoit pas. J'ai essayé d'envoyer la notification et d'attendre de voir si la console se connecte à partir de didReceiveRemoteNotification
, mais la notification prend trop de temps (plusieurs heures) pour être affichée comme étant envoyée dans la console Firebase (même lorsque j'ai défini la priorité sur high
).
Délégué App
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)")
}
^ Je suppose que le problème peut avoir à voir avec "gcm_message_id"/"gcmMessageId"/"gcm.message_id" car il est différent dans chacune des trois approches ci-dessous}
// 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)")
}
^ Je suppose que le problème peut avoir à voir avec "gcm_message_id"/"gcmMessageId"/"gcm.message_id" car il est différent dans chacune des trois approches ci-dessous}
// Print full message.
print(userInfo)
completionHandler(UIBackgroundFetchResult.newData)
}
// End of [FCM Setup]
///////////////////////
}
Contrôleur de vue
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 ?? "")")
}
}
Droits et activation des notifications push
J'ai ajouté les droits d'accès Push et modes de fond activés pour les notifications Push et a ajouté GoogleService-Info.plist à mon projet.
Méthode d'envoi de la notification
Je crée une notification à partir de la console de notifications Firebase (comme indiqué ci-dessous). La structure de la notification elle-même ne devrait donc pas poser de problème .
J'ai essayé les approches suivantes pour remédier au problème, mais toutes ont abouti au même résultat:
Est-ce que quelqu'un sait pourquoi la notification est marquée comme envoyée dans la console de notification de Firebase mais n'apparaît pas sur le périphérique?
Voici quelques étapes de dépannage que j'utilise lorsque je travaille avec des notifications Push:
J'espère que cela vous aidera pendant que vous travaillez à tout comprendre.
Essayez d'ajouter le code suivant à didRegisterForRemoteNotificationsWithDeviceToken func:
Messaging.messaging().apnsToken = deviceToken
Donc ça va ressembler à ça:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
Messaging.messaging().apnsToken = deviceToken
}
C'est un travail pour moi.
Quelqu'un sait-il pourquoi la notification est marquée comme envoyée dans la console de notification de Firebase mais n'apparaît pas sur le périphérique?
Parce que "envoyé" ne signifie pas "reçu".
La réception des notifications sur l'appareil ne peut pas être garantie. Avec l'infrastructure APNS de base, vous ne pouvez même pas obtenir les informations si une notification a été reçue ou traitée sur le périphérique.
Si vous ne recevez pas un message envoyé avec succès sur l'appareil, les raisons peuvent être multiples. De plus, même si vous recevez un jeton Firebase, cela ne signifie pas que votre appareil peut recevoir la notification dans tous les cas.
Pour isoler le problème, je suggérerais de construire la configuration minimale et d’utiliser APNS sans Firebase. Vous pouvez utiliser Terminal ou NWPusher ( https://github.com/noodlewerk/NWPusher ) pour envoyer des notifications à partir de votre système macOS local et du cadre de notifications Push à distance natif iOS pour recevoir des notifications.
Veillez à convertir le jeton de périphérique APNS au format correct requis pour l'envoi d'une notification:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let token = deviceToken.hexEncodedString()
print("Token: \(token)")
}
Extension de données:
extension Data {
func hexEncodedString() -> String {
return map { String(format: "%02hhx", $0) }.joined()
}
}
Je vois que vous avez tout fait dans la variable Capabilities
de votre projet.
Des points:
Conformez votre classe à messaging delegate
comme ceci:
Messaging.messaging().delegate = self
Assurez-vous que vous avez correctement configuré vos certificats et transféré tout le contenu dans les configurations de notification push de Firebase (terme non exact).
J'ai utilisé plusieurs applications qui utilisent le service de notification push de Firebase et créer un exemple d'application à partir de zéro peut vous aider à comprendre ce que vous avez fait de mal.
Et ... voici un bloc de code plus agréable pour enregistrer votre application pour la notification Push.
// 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)
}