FCM-Hintergrundbenachrichtigungen funktionieren nicht in iOS
Ich habe ein problem mit FCM-Benachrichtigung auf iOS.
Erhalte ich Benachrichtigungen mit Erfolg, wenn meine app in den Vordergrund (die callback - didReceiveRemoteNotification
im appdelegate
ausgelöst wird), aber ich erhalte keine Benachrichtigungen, wenn die app im hintergrund läuft (ich sehe nichts in der notification tray von iOS).
So, ich denke, das problem ist das format der Nachricht von FCM.
Die json gesendet von meinem server zu FCM, ist in dem folgenden format:
{
"data":{
"title":"mytitle",
"body":"mybody",
"url":"myurl"
},
"notification":{
"title":"mytitle",
"body":"mybody"
},
"to":"/topics/topic"
}
Wie Sie sehen können, gibt es zwei Blöcke in meiner json: eine Benachrichtigung block (um Benachrichtigungen zu erhalten, im hintergrund), und ein Daten-block (um Benachrichtigungen zu erhalten, im Vordergrund).
Kann ich nicht verstehen, warum die Benachrichtigungen im hintergrund sind nicht erhalten.
Meine Zweifel über die Reihenfolge der Blöcke (ein problem, wenn ich den "data" - block vor den "Benachrichtigung" - block?).
EDIT:
Mehr info über das problem.
Dies ist mein appdelegate.swift:
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate
{
var window: UIWindow?
//Application started
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool
{
let pushNotificationSettings: UIUserNotificationSettings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
application.registerUserNotificationSettings(pushNotificationSettings)
application.registerForRemoteNotifications()
FIRApp.configure()
NSNotificationCenter.defaultCenter().addObserver(self, selector: "tokenRefreshNotification:", name: kFIRInstanceIDTokenRefreshNotification, object: nil)
return true
}
//Handle refresh notification token
func tokenRefreshNotification(notification: NSNotification) {
let refreshedToken = FIRInstanceID.instanceID().token()
print("InstanceID token: \(refreshedToken)")
//Connect to FCM since connection may have failed when attempted before having a token.
if (refreshedToken != nil)
{
connectToFcm()
FIRMessaging.messaging().subscribeToTopic("/topics/topic")
}
}
//Connect to FCM
func connectToFcm() {
FIRMessaging.messaging().connectWithCompletion { (error) in
if (error != nil) {
print("Unable to connect with FCM. \(error)")
} else {
print("Connected to FCM.")
}
}
}
//Handle notification when the application is in foreground
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)
}
//Application will enter in background
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.
}
//Application entered in background
func applicationDidEnterBackground(application: UIApplication)
{
FIRMessaging.messaging().disconnect()
print("Disconnected from FCM.")
}
//Application will enter in foreground
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.
}
//Application entered in foreground
func applicationDidBecomeActive(application: UIApplication)
{
connectToFcm()
application.applicationIconBadgeNumber = 0;
}
//Application will terminate
func applicationWillTerminate(application: UIApplication)
{
//Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
}
Nur so kann ich empfangen von Nachrichten im Vordergrund stehen, ist durch die Deaktivierung von method swizzling, Einstellung FirebaseAppDelegateProxyEnabled, um NICHT in "meine info".plist.
In diesem Fall FCM-Dokumentation sagt, dass ich zur Umsetzung meiner appdelegate.swift zwei Methoden:
- FIRMessaging.messaging().appDidReceiveMessage(userInfo) in didReceiveRemoteNotification callback
- FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenType.Sandbox) in didRegisterForRemoteNotificationsWithDeviceToken callback
Aber wenn ich implementieren diese Funktionen, Nachrichten Haltestellen zu kommen, auch wenn die app im Vordergrund.
Ich weiß, das ist sehr seltsam.
EDIT 2:
Wenn die app im hintergrund läuft, die die Benachrichtigung nicht erhalten, aber wenn ich öffne meine app, die die gleiche Mitteilung empfangen wird, sofort (Methode didReceiveRemoteNotification ausgelöst wird).
priority
während der Verwendung von content_available
. Ich bin nicht so vertraut, wie APNS funktioniert, aber es gibt eine chance, dass die Meldung ignoriert werden, wenn sowohl priority
und content_available
ist in einer einzigen Nutzlast. Lassen Sie mich wissen, wenn es funktioniert. Prost! High
und dies hat nicht geholfen InformationsquelleAutor der Frage Mark O' Brian | 2016-06-18
Du musst angemeldet sein, um einen Kommentar abzugeben.
Vorausgesetzt, Sie haben alles eingerichtet, richtig, dann die Einstellung
priority
von der Nachricht ausnormal
zuhigh
sollte es sofort erscheinen. Dies ist aufgrund der Art und Weise iOS-bundles-Benachrichtigungen und Sie behandelt. Erfahren Sie mehr über die Priorität bei der FCM-Benachrichtigungen hier. Bitte beachten Sie, dass Sie nicht wirklich verwendenhigh
in der Produktion, es sei denn, es ist ein gutes Beispiel dafür, wie es hat eine Batterie Strafe.Hier ist der Verweis von Apple docs
InformationsquelleAutor der Antwort Chris
Müssen Sie die
content_available
- Eigenschaft auf true wie folgt:Es ist eine blue note Feld in diesem Abschnitt, die besagt: https://firebase.google.com/docs/cloud-messaging/concept-options#notifications
InformationsquelleAutor der Antwort Keith Holliday
Müssen Sie möglicherweise die push-notification-Berechtigung. Tun Sie dies, indem Sie auf Ihre Ziel-Einstellungen, klicken Sie dann auf "Fähigkeiten" und drehen "Push-Benachrichtigungen" auf.
InformationsquelleAutor der Antwort astromme
Priorität und content_available (wie bereits in anderen Antworten) sind die wichtigsten Elemente, um sicherzustellen, dass Sie die Benachrichtigungen erhalten. Tests ergaben interessante Ergebnisse, so dass ich dachte, zu teilen Sie Sie hier.
Test-Ergebnisse: Swift 3, Xcode 8, iOS 10
Priority = "high" => "sofort" (innerhalb offensichtlich Netzwerk-Verzögerungen) Empfang der Nachricht.
Priority = "normal" => verschiedene Ergebnisse (in der Regel schnell, aber offensichtlich langsamer als "high")
content_available = true in die Benachrichtigungen (keine payload message)
content_available = true in der obersten Ebene (keine Nutzlast Nachricht)
content_available = true in die Benachrichtigungen (mit message {title/body})
content_available = true in der obersten Ebene (mit payload message)
SCHLUSSFOLGERUNGEN:
EDIT: Weitere Test-Ergebnisse:
- wenn Sie eine msg-Titel MÜSSEN Sie haben eine msg-Körper oder Sie nicht bekommen eine Benachrichtigung.
Das ungerade Teil ist, dass Sie vibrieren, Abzeichen und sound, aber der alert-box nicht angezeigt, es sei denn, Sie haben einen Körper, ebenso wie der Titel.
InformationsquelleAutor der Antwort CFP Support
Hatte ich dieses Problem mit der
content_available
- Eigenschaft festgelegt. Die Lösung war, entfernen Sie und installieren Sie die Anwendung aus dem iOS-Gerät.InformationsquelleAutor der Antwort azmeuk