web-dev-qa-db-ja.com

Firebase Cloud Messaging通知がiOSペイロード形式を送信しない

昨夜、アプリでFCMを使用してプッシュ通知をテストしましたが、クラッシュしました(数日前に機能していました)。 Firebaseコンソールの通知メニューを使用してテストします。

さらに通知ペイロードの形式が変更され、 Apple Documentation のようなiOS形式が含まれていないことを調査します。

APNs証明書を再確認し、開発証明書がなくなったら、証明書を再アップロードしようとすると、同様のエラー this one が発生しました。

私はFirebaseチームにフィードバックを送信しましたが、それは彼らの最後の問題であると述べました。 (注:上記のリンクには、firebaseチームの応答も掲載しています)。私のDev APNs証明書が復活しましたが、形式は同じです。

これが私が得たペイロードです(from Swift Print function)から)

{
    "collapse_key" = "com.xxx.xxx";
    from = xxx;
    notification =     {
        badge = 3;
        body = "Firebase console";
        e = 1;
        title = Test;
    };
}

そして、このペイロードはiOSにプッシュ通知を表示させません。

そして iOS向けのこのFCMドキュメント に基づいています

次のコードは通知が来たときにアプリをクラッシュさせます

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)
}
  • Dev APNs証明書を再アップロードしようとしましたが、まだエラーが発生します
  • また、別のフィードバックを送信しましたが、Firebaseチームはまだ返信していません

何か不足していますか?

編集:

上で言ったように、それは数日前に機能し、 この問題 が表示されるとクラッシュします。

具体的には、この行はアプリをクラッシュさせます。ペイロードの形式が変更された(apsペイロードが欠落している)ために、このように思われます。

print("Message ID: \(userInfo["gcm.message_id"]!)")

コードを削除すると(上記のように生成されても)うまく機能しますが、それでも私はapsペイロード形式を取得しないので、アプリがバックグラウンドで実行されているときに通知がポップアップすることはありません。また、アプリがフォアグラウンドにある場合、通知ハンドラーが機能しません。

編集2

AppDelegateに通知を登録済み

let setting = UIUserNotificationSettings(forTypes: [.Sound, .Alert, .Badge] , categories: nil)
    application.registerUserNotificationSettings(setting)
    application.registerForRemoteNotifications()

私はこれを認識しており、すでにプッシュ通知とリモート通知のバックグラウンドモードを有効にしています。

Capabilities

2016年6月28日編集

Firebaseコンソールから通知をもう一度プッシュしてみましたが、それでもこのような同じペイロード形式を取得しました

%@ [notification: {
    badge = 2;
    body = "Test Message";
    e = 1;
    sound = default;
    sound2 = default;
    title = Test;
}, collapse_key: com.xxx, from: 717xxxxxx]

FCM Firebaseコンソールの設定は次のようになります

Firebase Console Setting

2016年7月8日編集

これは私の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)
    }


}

これが私のアプリからの完全なログです

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
12
Bagus Cahyono

同じ問題がありました

FCMガイドのこの部分について: https://firebase.google.com/docs/cloud-messaging/ios/client#swizzling_disabled_receive_messages_through_the_messaging_apns_interface

setAPNSToken:type:の追加に関する問題を解決しました

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
    [[FIRInstanceID instanceID] setAPNSToken:deviceToken type:FIRInstanceIDAPNSTokenTypeSandbox];
}

その後、fcmは、iOS用に適切にフォーマットされたペイロードでプッシュの送信を開始しました。

もちろん、本番環境で使用する場合はFIRInstanceIDAPNSTokenTypeProd

4
Przemek Jaskot

あなたが印刷している「ペイロード」は私には正しく見えます。ただし、これはAPNペイロードではないであることに注意してください。実際にはユーザー情報の辞書です。質問を理解した場合、"aps"フィールドが欠落していることを心配しているようです。ユーザー情報辞書にはそのフィールドは表示されません。

これを実際のデバイスまたはシミュレータで実行していますか?シミュレータはリモート通知を表示できません。実際のデバイスでは、アプリは通知を表示するためにバックグラウンドにある必要があります。

ローカル通知を送信してみてください(30秒間スケジュールしてください):

localNotif.fireDate = [[NSDate date] dateByAddingTimeInterval:30];

そして、ホームキーを押して待ちます。

1
IanS

私は同じ問題を抱えていました、私は「高」優先度を追加しました、そしてそれは私のために働きました!

{
    "collapse_key" :"com.xxx.xxx",
    to: "xxx",
    priority : "high",
    notification :{..}
}
0
aamarcha

指定した「ペイロード」は、(おそらく)didReceiveRemoteNotificationメソッドの最後の行、つまりprint("%@", userInfo)によって生成されたものです。

上記のコードはアプリをクラッシュさせると主張していますが、これはそのコードがログに正常に出力されることに矛盾しています。

他の何かがあなたのアプリをクラッシュさせていると思います。システムログを確認しましたか? (シミュレーターを使用している場合は、「デバッグ」>「システムログを開く」に移動します)。

Firebaseデモアプリ(pod try Firebase)、期待どおりに機能していることを納得させます。

0
IanS

ここでも同じ問題。さらに、キーで「aps」を含むFirebaseメッセージは、コンソールで送信中に配信されないようです。ペイロード形式を変更するには、Firebaseのいくつかのバグである必要があります。

バックグラウンドモードでのFirebase通知の取得について、この場合、iOSはペイロード形式を認識しないと思います->通知はまったくありません。バックグラウンドでFirebaseからメッセージを読み取るには、バックグラウンドモードに移行するときにFIRMessaging.messaging()。disconnect()を呼び出さないでください。次に、メッセージを取得して独自のハンドルで処理します(まだシステム通知はありません)。

0
vietphung

Gcm.message_idがnullである理由を調査しています。2、3日ください。

アプリがバックグラウンドにあるときに通知を受け取らないようにするには、クイックスタートサンプル(didFinishLaunchingWithOptionsを参照)に示されているように、リモート通知に登録してください: https://github.com/firebase/quickstart-ios /blob/master/messaging/FCMSwift/AppDelegate.Swift

また、Xcodeでバックグラウンド通知を処理できるように機能を設定していることを確認してください。

0

Apple=の開発者フォーラムに参加しましたが、didRegisterForRemoteNotificationsWithDeviceTokenはSandBoxモードでは機能せず、本番環境でのみ機能したようです。didRegisterForRemoteNotificationsWithDeviceTokenは登録場所ですFirebaseを備えたdeviceToken。それが起こらなかったため、FirebaseはデバイスがAppleであることを認識していなかったため、notificationキーでペイロードを送信していました。今日Apple問題を修正し、通知を送信できます。

0
MrDank