我对iOS上的FCM通知有问题.

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

所以,我认为问题在于FCM发送的消息的格式.

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

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

我不明白为什么没有收到后台通知.

EDIT:

这是我的代理.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,在我的信息中将FirebaseAppDelegateProxyEnabled设置为NO.普利斯特.

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

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

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

我知道这很奇怪.

EDIT 2:

当应用程序位于后台时,不会收到通知,但当我打开应用程序时,会立即收到相同的通知(方法DidReceiveEmoteNotification被激发).

推荐答案

假设您已经正确设置了所有内容,那么将消息的prioritynormal设置为high应该会立即显示.这是因为iOSBundle 和处理通知的方式.你可以读到关于Priority of FCM notifications here的书.请注意,除非有充分的理由,否则你不应该在生产中使用high,因为它会导致电池损耗.

这是Apple's docs的参考资料

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

10–立即发送消息.具有此优先级的通知

5-在考虑电源的情况下发送推送消息

Swift相关问答推荐

TabView中的视频播放器意外播放

如何在向照片添加文本时定义文本对齐、文本背景的Alpha和在文本之前添加图像

音频播放器无法播放URL音频(操作系统状态错误2003334207.)

有没有一种方法可以迭代可编码的代码(例如,JSON解析中的每一项)?

Swift C外部实现的Task / Future类类型

background Task(.backgroundTask)不适用于MySQL

应该在ViewModel还是ViewController中使用"Task {}"?

ConfirmationDialog取消swiftui中的错误

是否有一个带有空初始值设定项的 Swift 类/ struct 的标准协议

是否可以使用 .task 修饰符更新基于两个值的视图

动画偏移正在 destruct 按钮 SwiftUI

当使用 CGFloat 而不是数字文字时,为什么 node 的位置会发生变化?

调用从 SwiftUI 视图传递到 PageViewController.Coordinator 的函数

如何在不阻塞 UI 更新的情况下使用 Swift Concurrency 在后台执行 CPU 密集型任务?

在 Swift 中返回实例类型

swift : 具有类型和值的枚举常量

不能从非开放类继承 swift

在 Swift 中为 UIPickerView 设置默认值?

如何使用 Swift 枚举作为字典键? (符合 Equatable)

如何在 SwiftUI Segmented Picker 中更改选定的段 colored颜色