アプリがforegroundedの場合、メソッドswizzlingで新しいFirebaseクラウドメッセージングを使用すると、アプリデリゲートのdidReceiveRemoteNotification
メソッドでペイロードを正常に受信できます。ただし、アプリがbackgroundedの場合、メッセージが正常に送信されたというAPI応答にもかかわらず(以下を参照)、ペイロードが何も取得されず、didReceiveRemoteNotification
が呼び出されません。
ここに、プッシュ通知をトリガーするためにFCM apiに送信するリクエストがありますhttps://fcm.googleapis.com/fcm/send
{
"to": "{valid-registration-token}",
"priority":"high", //others suggested setting priority to high would fix, but did not
"notification":{
"body":"Body3",
"title":"test"
}
}
FCMからの応答あり
{
"multicast_id": 6616533575211076304,
"success": 1,
"failure": 0,
"canonical_ids": 0,
"results": [
{
"message_id": "0:1468906545447775%a4aa0efda4aa0efd"
}
]
}
これが私のappDelegateコードです
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
Fabric.with([Crashlytics.self])
FIRApp.configure()
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.tokenRefreshNotification),
name: kFIRInstanceIDTokenRefreshNotification, object: nil)
return true
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
// Let FCM know about the message for analytics etc.
FIRMessaging.messaging().appDidReceiveMessage(userInfo)
// Print full message.
print("%@", userInfo)
// handle your message
// let localNotification = UILocalNotification()
// localNotification.fireDate = NSDate()
// let notification = userInfo["notification"]!
// localNotification.alertBody = notification["body"] as? String
// localNotification.alertTitle = notification["title"] as? String
// localNotification.timeZone = NSTimeZone()
// application.scheduleLocalNotification(localNotification)
}
func tokenRefreshNotification(notification: NSNotification) {
let refreshedToken = FIRInstanceID.instanceID().token()!
print("InstanceID token: \(refreshedToken)")
LoginVC.registerForPushNotifications()
connectToFcm()
}
//foreground messages
func applicationDidBecomeActive(application: UIApplication) {
connectToFcm()
}
// [START disconnect_from_fcm]
func applicationDidEnterBackground(application: UIApplication) {
FIRMessaging.messaging().disconnect()
print("Disconnected from FCM.")
}
func connectToFcm() {
FIRMessaging.messaging().connectWithCompletion { (error) in
if (error != nil) {
print("Unable to connect with FCM. \(error)")
} else {
print("Connected to FCM.")
}
}
}
}
アプリの後でフローでこのコードを呼び出して、権限を要求します
static func registerForPushNotifications() {
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(settings)
UIApplication.sharedApplication().registerForRemoteNotifications()
}
アプリがフォアグラウンドになっているときに通知を受け取ることができるので、これは私のapns証明書がアップロードされていない、または登録トークンが正しくないというすべての懸念を和らげると思います。そうでない場合は、コメントしてください。そのうさぎの穴をもう一度下ります。見落としている簡単なものがあると思いますが、アプリのバックグラウンド中に通知を表示するにはどうすればよいですか?ありがとう
どうやら(自動的に行われるはずのメソッドのスウィズリングを使用しているにもかかわらず)、FirebaseインスタンスにAPNSトークンを設定する必要があります。したがって、これはdidRegisterForRemoteNOtificationsWithDeviceToken
メソッドも次のように実装する必要があることを意味します
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
// set firebase apns token
FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenType.Unknown)
}
追加のメモとして。 "priority":"high"
を使用すると、通知がすぐに送信されるため、テストに役立ちました。
ダニエルジョージのソリューションと同様に、次の方法で問題を修正できます。
Messaging.messaging().apnsToken = deviceToken
FirebaseInstanceID 2.0.8、FirebaseMessaging 2.0.8
少なくとも私のアプリにとって望ましい動作は、PN(プッシュ通知)のコンテンツがアプリの必要なページに表示されるプッシュ通知の到着です。
PNが到達できるアプリの状態は3つあります(もちろん、実装によって異なりますが、Appleがこれらの状態でPNを処理する方法)
(動作はAppleによって決定されます!)
1)アプリはフォアグラウンドにあります:
この場合、アプリalwaysはPNを処理します
2)アプリはバックグラウンドです:
この場合、アプリalwaysはPNを処理します
)アプリが強制終了/クローズされました:
今、3つの可能な方法があります
通知をスワイプして離れる-> PNは[〜#〜] not [〜#〜]アプリによって処理されます
ランチャーアイコンを介してアプリを直接開く-> PNは[〜#〜] not [〜#〜]アプリによって処理されます
通知をクリックします-> PNはアプリによって処理されます
この場合、ユーザーが通知をタップしてアプリを開かないを実行すると、通知データを取得する方法がありませんがあります。
アプリの状態から独立するには、特定のデータをリクエストできるサーバーをセットアップする必要があります。例えば。すべての通知を表示するビューがあり、特定のデータを要求するにはAPIが必要です。 Pushnotificationの受信メソッドでデータを処理しないでください。
それが誰かを助けることを願っています!
FCMからトークンを取得した後、次の手順に従って、FCMを使用したバックグラウンドペイロードデータのフェッチを有効にします。
project Navigator> AppCapabilities>バックグラウンドモードを開き、リモート通知を確認します。
App.delegateで以下を定義します。
func application(_ application: UIApplication,didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
print("userinfo in background mode on-\(userInfo)")
completionHandler(UIBackgroundFetchResult.newData)
}
Appleガイドライン: ここにリンクの説明を入力 に従ってペイロードを正しくフォーマットしてください==
キーと値のペアを追加することを忘れないでください:{"content-available":1}
バックグラウンドでペイロードを取得できない場合を除きます。
fCMトークンを使用して、もう一度通知を送信してみてください。幸せなコーディングを
JSONペイロードに "content_available":trueが追加されていることを確認してください。そうしないと、バックグラウンドモードでプッシュ通知を取得できません。
"notification" : {
"body" : "this is body",
"title" : "this is title"
}
"content_available" : true