FCM 后台通知在 iOS 中不起作用 [英] FCM background notifications not working in iOS

查看:38
本文介绍了FCM 后台通知在 iOS 中不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 iOS 上遇到 FCM 通知问题.

I have a problem with FCM notification on iOS.

当我的应用程序处于前台时,我成功收到通知(appdelegate 中的回调 didReceiveRemoteNotification 被触发),但当应用程序处于前台时我没有收到通知背景(我在 iOS 的通知托盘中没有看到任何东西).

I receive notifications with success when my app is in foreground (the callback didReceiveRemoteNotification in appdelegate is fired), but I don't receive notifications when the app is in background (I do not see anything in the notification tray of iOS).

所以,我认为问题在于FCM发送的消息格式.我的服务器发送到 FCM 的 json 格式如下:

So, I think the problem is in the format of the message sent by FCM. The json sent by my server to FCM, is in the following format:

{  
   "data":{  
      "title":"mytitle",
      "body":"mybody",
      "url":"myurl"
   },
   "notification":{  
      "title":"mytitle",
      "body":"mybody"
   },
   "to":"/topics/topic"
}

如您所见,我的 json 中有两个块:一个通知块(在后台接收通知)和一个数据块(在前台接收通知).

As you can see, there are two blocks in my json: one notification block (to receive notifications in background), and one data block (to receive notifications in foreground).

我不明白为什么没有收到后台通知.我的疑问是关于块的顺序(如果我把数据"块放在通知"块之前会有问题吗?).

I cannot understand why notifications in background are not received. My doubts are about the order of the blocks (is a problem if I put the "data" block before the "notification" block?).

有关问题的更多信息.

这是我的 appdelegate.swift:

This is my 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:.
    }


}

我可以在前台接收消息的唯一方法是禁用方法 swizzling,在我的 info.plist 中将 FirebaseAppDelegateProxyEnabled 设置为 NO.

The only way I can receive messages in foreground, is by disabling method swizzling, setting FirebaseAppDelegateProxyEnabled to NO in my info.plist.

在这种情况下,FCM 文档说我必须在我的 appdelegate.swift 中实现两个方法:

In this case, FCM documentation says that I have to implement in my appdelegate.swift two methods:

 - FIRMessaging.messaging().appDidReceiveMessage(userInfo)  in didReceiveRemoteNotification callback
 - FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenType.Sandbox) in didRegisterForRemoteNotificationsWithDeviceToken callback

但如果我实现这些功能,即使应用程序在前台,消息也会停止到达.

But if I implement those functions, messages stops to arrive even when the app is in foreground.

我知道这很奇怪.

编辑 2:

当应用程序在后台时不会收到通知,但是当我打开我的应用程序时,会立即收到相同的通知(方法 didReceiveRemoteNotification 被触发).

When the app is in background the notification isn't received, but when i open my app, the same notification is received immediately (method didReceiveRemoteNotification is fired).

推荐答案

假设您已经正确设置了所有内容,然后将消息的 prioritynormal 设置为high 应该让它立即出现.这是由于 iOS 捆绑通知和处理它们的方式.您可以阅读优先级此处为 FCM 通知.请注意,除非有很好的案例,否则您不应该在生产中真正使用 high,因为它会消耗电池电量.

Assuming you've set up everything correctly, then setting the priority of the message from normal to high should make it appear immediately. This is due to the way iOS bundles notifications and handles them. You can read about the Priority of FCM notifications here. Please note that you shouldn't really use high in production unless there is a good case for it, as it has a battery penalty.

这是来自 Apple 的文档

通知的优先级.指定以下值之一:

The priority of the notification. Specify one of the following values:

10-立即发送推送消息.具有此优先级的通知必须在目标设备上触发警报、声音或徽章.它是一个将此优先级用于仅包含内容可用键.

10–Send the push message immediately. Notifications with this priority must trigger an alert, sound, or badge on the target device. It is an error to use this priority for a push notification that contains only the content-available key.

5—在考虑功率的时间发送推送消息设备的考虑.具有此优先级的通知可能分组并分批交付.它们受到限制,并且在某些情况下案件不交付.如果省略此标头,APNs 服务器将设置优先级为 10.

5—Send the push message at a time that takes into account power considerations for the device. Notifications with this priority might be grouped and delivered in bursts. They are throttled, and in some cases are not delivered. If you omit this header, the APNs server sets the priority to 10.

这篇关于FCM 后台通知在 iOS 中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆