La nuit dernière, j'ai testé la notification Push à l'aide de FCM dans mes applications et elle s'est écrasée (cela fonctionnait il y a quelques jours). Je le teste en utilisant le menu de notification dans la console Firebase.
J'étudie en outre que le format de charge de notification a été modifié et n'inclut pas le format iOS comme celui de la Documentation Apple .
Je re-vérifie mon certificat APNs et celui du développement est parti, j'essaye de re-télécharger le certificat et il y a une erreur similaire comme celui-ci .
J'ai soumis un feedback à l'équipe de firebase et lui a dit que c'était un problème pour eux. (Remarque: je publie également la réponse de l'équipe firebase dans le lien ci-dessus). Mon certificat APN Dev est de retour, mais le format reste le même.
Voici la charge que j'ai eu (de la fonction Swift Print)
{
"collapse_key" = "com.xxx.xxx";
from = xxx;
notification = {
badge = 3;
body = "Firebase console";
e = 1;
title = Test;
};
}
Et cette charge utile ne permet pas à iOS d’afficher la notification Push.
Et basé sur cette documentation FCM pour iOS
le code suivant va faire planter l'application lorsque la notification arrive
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject],
fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
// 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
// Print message ID.
print("Message ID: \(userInfo["gcm.message_id"]!)")
// Print full message.
print("%@", userInfo)
}
Est-ce que je manque quelque chose?
Modifier:
Comme je l'ai dit plus haut, le système fonctionnait quelques jours en arrière et il se bloque lorsque ce problème apparaît.
Plus précisément, cette ligne provoquera le blocage de l'application, et je suppose que c'est parce que le format de la charge utile a changé (la charge utile aps est manquante).
print("Message ID: \(userInfo["gcm.message_id"]!)")
Le code fonctionne bien lorsqu'il est supprimé (et produit ci-dessus), mais je n'ai toujours pas le format de charge utile aps, de sorte que la notification ne s'affiche jamais lorsque les applications sont en arrière-plan. De plus, mon gestionnaire de notifications ne fonctionnera pas lorsque les applications en avant-plan.
Edit 2:
J'enregistre déjà une notification dans mon AppDelegate
let setting = UIUserNotificationSettings(forTypes: [.Sound, .Alert, .Badge] , categories: nil)
application.registerUserNotificationSettings(setting)
application.registerForRemoteNotifications()
Je suis conscient de cela et déjà activé le mode de fond Notification Push et Notification à distance.
Edit 28 juin 2016:
J'ai essayé à nouveau d'envoyer des notifications depuis la console firebase, et j'ai quand même le même format de charge utile comme celui-ci.
%@ [notification: {
badge = 2;
body = "Test Message";
e = 1;
sound = default;
sound2 = default;
title = Test;
}, collapse_key: com.xxx, from: 717xxxxxx]
Mon paramètre de console FCM Firebase ressemble à ceci
Edit 8 juillet 2016:
Ceci est mon code AppDelegate
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, GIDSignInDelegate {
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Firebase
let setting = UIUserNotificationSettings(forTypes: [.Sound, .Alert, .Badge] , categories: nil)
application.registerUserNotificationSettings(setting)
application.registerForRemoteNotifications()
FIRApp.configure()
print(FIRInstanceID.instanceID().token())
FIRAnalytics.logEventWithName(kFIREventAppOpen, parameters: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(tokenRefreshNotificaiton), name: kFIRInstanceIDTokenRefreshNotification, object: nil)
return true
}
// MARK - Firebase
func connectToFcm() {
FIRMessaging.messaging().connectWithCompletion { (error) in
if (error != nil) {
print("Unable to connect with FCM. \(error)")
} else {
print("Connected to FCM.")
}
}
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
// 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
// Print message ID.
// print("Message ID: \(userInfo["gcm.message_id"]!)")
// Print full message.
print("%@", userInfo)
var body = ""
var title = "20Fit"
guard let aps = userInfo["aps"] as? [String : AnyObject] else {
print("Error parsing aps")
return
}
if let alert = aps["alert"] as? String {
body = alert
} else if let alert = aps["alert"] as? [String : String] {
body = alert["body"]!
title = alert["title"]!
}
let banner = Banner(title: title, subtitle: body, image: nil, backgroundColor: UIColor.blackColor(), didTapBlock: nil)
banner.show(duration: 5.0)
}
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: .Sandbox)
}
func tokenRefreshNotificaiton(notification: NSNotification) {
let refreshedToken = FIRInstanceID.instanceID().token()!
print("InstanceID token: \(refreshedToken)")
sendTokenToServer()
// Connect to FCM since connection may have failed when attempted before having a token.
connectToFcm()
}
func applicationWillResignActive(application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
func applicationDidEnterBackground(application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
FIRMessaging.messaging().disconnect()
print("Disconnected from FCM")
}
func applicationWillEnterForeground(application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(application: UIApplication) {
connectToFcm()
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
FIRAnalytics.logEventWithName("app_terminated", parameters: nil)
}
}
Voici le journal complet de mes applications
2016-07-08 19:26:48.022 20FIT Member[2525:1122556] WARNING: Firebase Analytics App Delegate Proxy is disabled. To log deep link campaigns manually, call the methods in FIRAnalytics+AppDelegate.h.
2016-07-08 19:26:48.273 20FIT Member[2525:1122556] Configuring the default app.
2016-07-08 19:26:48.318 20FIT Member[2525:] <FIRAnalytics/DEBUG> Debug mode is on
2016-07-08 19:26:48.338 20FIT Member[2525:] <FIRAnalytics/INFO> Firebase Analytics v.3200000 started
2016-07-08 19:26:48.338 20FIT Member[2525:] <FIRAnalytics/INFO> To enable debug logging set the following application argument: -FIRAnalyticsDebugEnabled (see google link)
2016-07-08 19:26:48.343: <FIRInstanceID/WARNING> Failed to fetch APNS token Error Domain=com.firebase.iid Code=1001 "(null)"
2016-07-08 19:26:48.350: <FIRMessaging/INFO> FIRMessaging library version 1.1.0
2016-07-08 19:26:48.339 20FIT Member[2525:] <FIRAnalytics/DEBUG> Debug logging enabled
2016-07-08 19:26:48.365 20FIT Member[2525:] <FIRAnalytics/DEBUG> Uploading data. Host: https://play.googleapis.com/log
2016-07-08 19:26:48.366 20FIT Member[2525:] <FIRAnalytics/DEBUG> Firebase Analytics is monitoring the network status
Optional("cXwsIWfiJas:APA91bGjUnL-oztH9LntO4EaKdJxPQN_-Za5ydC-hPR-_HPZXNm4m_mzqSztvbBG7HczNN5Jr7Btr8h4ETF5FyOOUn8Ombk4c3RoTL6GDFrh6BnG0ECs_r_Hqx1dnVHeJVwLQo4JInn2")
2016-07-08 19:26:48.406 20FIT Member[2525:] <FIRAnalytics/DEBUG> Successfully parsed a configuration. Version: 1464617411301000
2016-07-08 19:26:48.429 20FIT Member[2525:] <FIRAnalytics/DEBUG> Firebase Analytics is ready to receive events
2016-07-08 19:26:48.432 20FIT Member[2525:] <FIRAnalytics/DEBUG> No network. Upload task will not be scheduled
2016-07-08 19:26:48.434 20FIT Member[2525:] <FIRAnalytics/DEBUG> Cancelling background upload task.
2016-07-08 19:26:48.437 20FIT Member[2525:] <FIRAnalytics/DEBUG> Scheduling user engagement timer
2016-07-08 19:26:48.438 20FIT Member[2525:] <FIRAnalytics/DEBUG> Timer scheduled to fire in approx. (s): 3600
2016-07-08 19:26:48.441 20FIT Member[2525:] <FIRAnalytics/INFO> Firebase Analytics enabled
2016-07-08 19:26:48.445 20FIT Member[2525:] <FIRAnalytics/DEBUG> Logging event: Origin, name, params: app, app_open, {
"_o" = app;
}
2016-07-08 19:26:48.477 20FIT Member[2525:] <FIRAnalytics/DEBUG> Scheduling user engagement timer
2016-07-08 19:26:48.478 20FIT Member[2525:] <FIRAnalytics/DEBUG> Canceling active timer
2016-07-08 19:26:48.479 20FIT Member[2525:] <FIRAnalytics/DEBUG> Timer scheduled to fire in approx. (s): 3600
2016-07-08 19:26:48.562 20FIT Member[2525:] <FIRAnalytics/DEBUG> Network status has changed. code, status: 2, Connected
2016-07-08 19:26:48.566 20FIT Member[2525:] <FIRAnalytics/DEBUG> Network status has changed. code, status: 2, Connected
2016-07-08 19:26:48.618 20FIT Member[2525:] <FIRAnalytics/DEBUG> Event logged. Event name, event params: app_open, {
"_o" = app;
}
2016-07-08 19:26:48.635 20FIT Member[2525:] <FIRAnalytics/DEBUG> Timer scheduled to fire in approx. (s): 3143.319384038448
2016-07-08 19:26:48.636 20FIT Member[2525:] <FIRAnalytics/DEBUG> Upload task scheduled to be executed in approx. (s): 3143.319384038448
2016-07-08 19:26:48.637 20FIT Member[2525:] <FIRAnalytics/DEBUG> Do not schedule an upload task. Task already exists
2016-07-08 19:26:48.710 20FIT Member[2525:] <FIRAnalytics/DEBUG> Received SSL challenge for Host. Host: https://play.googleapis.com/log
2016-07-08 19:26:49.408 20FIT Member[2525:] <FIRAnalytics/DEBUG> Uploading data. Host: https://play.googleapis.com/log
Connected to FCM.
2016-07-08 19:26:49.869 20FIT Member[2525:] <FIRAnalytics/DEBUG> Received SSL challenge for Host. Host: https://play.googleapis.com/log
2016-07-08 19:26:50.206 20FIT Member[2525:] <FIRAnalytics/DEBUG> Uploading data. Host: https://play.googleapis.com/log
2016-07-08 19:26:50.723 20FIT Member[2525:] <FIRAnalytics/DEBUG> Received SSL challenge for Host. Host: https://play.googleapis.com/log
%@ [notification: {
badge = 2;
body = "Test Message";
e = 1;
sound = default;
sound2 = default;
title = Yoiii;
}, collapse_key: com.xxx.xxx, from: 717xxxx]
Error parsing aps
J'ai eu le même problème
Concernant cette partie des guides fcm: https://firebase.google.com/docs/cloud-messaging/ios/client#swizzling_disabled_receive_messages_through_the_messaging_apns_interface
J'ai résolu le problème avec l'ajout de setAPNSToken:type:
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
[[FIRInstanceID instanceID] setAPNSToken:deviceToken type:FIRInstanceIDAPNSTokenTypeSandbox];
}
Après cela, fcm a commencé à envoyer des push avec une charge utile correctement formatée pour iOS.
Bien sûr, pour l’utilisation dans l’environnement de production FIRInstanceIDAPNSTokenTypeProd
La "charge utile" que vous imprimez me convient parfaitement. Cependant, notez qu'il s'agit de et non de la charge utile APN . C'est en fait un dictionnaire d'informations utilisateur. Si je comprends votre question, vous semblez craindre que le champ "aps"
manque. Vous ne verrez pas ce champ dans le dictionnaire utilisateur-info.
Utilisez-vous cela sur un appareil réel ou dans le simulateur? N'oubliez pas que le simulateur ne peut pas afficher de notifications à distance et que sur un appareil réel, l'application doit être en arrière-plan pour afficher les notifications.
Essayez d'envoyer une notification locale (planifiez-la pour 30 secondes):
localNotif.fireDate = [[NSDate date] dateByAddingTimeInterval:30];
Et appuyez sur la touche d'accueil et attendez.
J'ai eu le même problème, j'ai ajouté la priorité «haute» et cela a fonctionné pour moi!
{
"collapse_key" :"com.xxx.xxx",
to: "xxx",
priority : "high",
notification :{..}
}
La "charge utile" que vous avez fournie était (probablement) produite par la dernière ligne de la méthode didReceiveRemoteNotification
, c'est-à-dire print("%@", userInfo)
.
Vous prétendez que le code ci-dessus provoque le blocage de l'application, ce qui est en contradiction avec l'impression de ce code dans le journal.
Je pense que quelque chose d'autre bloque votre application. Avez-vous regardé dans le journal du système? (Si vous utilisez le simulateur, accédez à Débogage> Ouvrir le journal système).
Je suggérerais de lancer l'application de démonstration Firebase (pod try Firebase
) pour vous convaincre que cela fonctionne comme vous le souhaiteriez.
Même problème ici. En outre, le message Firebase avec la clé 'aps' ne semble pas être envoyé lors de l'envoi avec la console. Il doit y avoir des bogues avec Firebase pour changer le format de charge utile.
À propos de la notification de Firebase en mode arrière-plan, dans ce cas, je pense qu'iOS ne reconnaîtra pas le format de charge utile -> pas de notification du tout. Pour lire le message de Firebase en arrière-plan, n'appelez pas FIRMessaging.messaging (). Disconnect () lorsque vous passez en mode arrière-plan. Ensuite, vous devriez recevoir votre message et le gérer avec votre propre identifiant (toujours aucune notification système).
Je cherche à savoir pourquoi votre gcm.message_id est null, donnez-moi quelques jours.
Pour ne pas recevoir la notification lorsque l'application est en arrière-plan, assurez-vous de vous inscrire aux notifications à distance, comme indiqué dans l'exemple de démarrage rapide (voir didFinishLaunchingWithOptions) ici: https://github.com/firebase/quickstart-ios/blob /master/messaging/FCMSwift/AppDelegate.Swift
Assurez-vous également que dans Xcode, vous avez défini vos fonctionnalités pour permettre le traitement des notifications en arrière-plan.
J'ai parcouru le forum des développeurs d'Apple et il semble que didRegisterForRemoteNotificationsWithDeviceToken
ne fonctionnait pas en mode SandBox et travaillait uniquement en production. didRegisterForRemoteNotificationsWithDeviceToken
est l'endroit où j'enregistre le deviceToken avec firebase. Comme cela ne se produisait pas, Firebase envoyait une charge avec la clé notification
car elle ne savait pas que le périphérique était Apple. Aujourd'hui, Apple a résolu le problème et je peux maintenant envoyer des notifications.