Firebase Cloud Messaging iOS:无后台推送通知 [英] Firebase Cloud Messaging iOS: No background push notification

查看:558
本文介绍了Firebase Cloud Messaging iOS:无后台推送通知的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用较新的Firebase云消息传递方法,我可以在应用程序委托中的 didReceiveRemoteNotification 方法中成功接收有效内容,当我的应用程序被预先的。然而,我没有得到任何有效载荷,当我的应用程序是后台时,不会调用 didReceiveRemoteNotification ,尽管消息成功的api响应发送(见下文)

以下是我发送到FCM API以触发推送通知的请求 https://fcm.googleapis.com/fcm/send
$ b $ $ $
to:{valid-registration-token},
priority:high,//别人建议优先级设置为high会修正,但是没有
通知:{
body:Body3,
title :test
}
}

FCM

  {
multicast_id:6616533575211076304,
成功:1,
失败:0,
canonical_ids:0,
results:[
{
message_id:0:1468906545447775%a4aa0efda4aa0efd
}
]
}

这是我的appDelegate代码

  func应用程序(application:UIApplication,didFinishLaunchingWithOptions launchOptions:[ NSObject:AnyObject]?) - > Bool {

Fabric.with([Crashlytics.self])
FIRApp.configure()

NSNotificationCenter.defaultCenter()。addObserver(self,selector:# select(self.tokenRefreshNotification),
name:kFIRInstanceIDTokenRefreshNotification,object:nil)
return true
}



func application(application :UIApplication,didReceiveRemoteNotification userInfo:[NSObject:AnyObject],fetchCompletionHandler completionHandler:(UIBackgroundFetchResult) - > Void){
//让FCM知道分析等消息
FIRMessaging.messaging()。 appDidReceiveMessage(userInfo)

//打印完整消息。
print(%@,userInfo)

//处理您的消息

// let localNotification = UILocalNotification()
// localNotification。 fireDate = NSDate()
//让通知= userInfo [通知]!
// localNotification.alertBody = notification [body] as? String
// localNotification.alertTitle = notification [title] as? String
// localNotification.timeZone = NSTimeZone()
// application.scheduleLocalNotification(localNotification)


$ b func tokenRefreshNotification(notification:NSNotification) {
let refreshedToken = FIRInstanceID.instanceID()。token()!
print(InstanceID token:\(refreshedToken))
LoginVC.registerForPushNotifications()
connectToFcm()
}


//前台消息
func applicationDidBecomeActive(application:UIApplication){
connectToFcm()
}

// [START disconnect_from_fcm]
func applicationDidEnterBackground(application :UIApplication){
FIRMessaging.messaging()。disconnect()
print(与FCM断开连接)
}


func connectToFcm ){
FIRMessaging.messaging()。connectWithCompletion {(error)in
if(error!= nil){
print(Unable to connect with FCM。\(error))
} else {
print(Connected to FCM。)
}
}
}

}
code>

我在稍后的应用程序中调用此代码来请求权限

  static func registerForPushNotifications(){
let settings:UIUserNotificationSettings =
UIUserNotificationSettings(forTypes:[.Alert,.Badge,.Sound],类别:无)
UIApplication.sharedApplication()。registerUserNotificationSettings(settings)
UIApplication.sharedApplication()。registerForRemoteNotifications()
}
我可能忽略了一些简单的东西,但是如何才能在应用程序背景中显示通知?谢谢
显然,(尽管使用方法swizzling应该自动执行),您仍然必须在Firebase上设置APNS令牌实例。因此,这意味着您还必须执行 didRegisterForRemoteNOtificationsWithDeviceToken 方法,如

  func application(application:UIApplication,didRegisterForRemoteNotificationsWithDeviceToken deviceToken:NSData){


//设置firebase apns令牌
FIRInstanceID.instanceID()。setAPNSToken(deviceToken,type:FIRInstanceIDAPNSTokenType.Unknown )
}

作为补充说明。使用priority:high对于测试,因为它马上发送通知。


Using the newer Firebase cloud messaging with method swizzling i am successfully able to receive a payload in the didReceiveRemoteNotification method in my app delegate when my app is foregrounded. However i do not get any sort of payload and didReceiveRemoteNotification does not get called when my app is backgrounded, despite the api response that the message is successfully sent (see below)
Here is the request that i send to the FCM api to trigger a push notification 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"  
 } 
}


with response from FCM

{
      "multicast_id": 6616533575211076304,
      "success": 1,
      "failure": 0,
      "canonical_ids": 0,
      "results": [
        {
          "message_id": "0:1468906545447775%a4aa0efda4aa0efd"
        }
      ]
    }

Here is my appDelegate code

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.")
            }
        }
    }

}

I call this code at a later flow in my app to ask for permissions

static func registerForPushNotifications() {
    let settings: UIUserNotificationSettings =
                UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
            UIApplication.sharedApplication().registerUserNotificationSettings(settings)
            UIApplication.sharedApplication().registerForRemoteNotifications()
}

Since i am able to receive notifications while app is foregrounded i assume this would allay all concerns that my apns certificates are not uploaded or that the registration token is incorrect. If that is not the case, please comment and i'll go down that rabbit hole again. There's probably something simple that i am overlooking, but how can i get the notifications to appear while the app is backgrounded? Thanks

解决方案

Apparently, (despite using method swizzling that should be doing it automatically) you must still set the APNS token on the Firebase Instance. Consequently this means you must also implement the didRegisterForRemoteNOtificationsWithDeviceToken method with something like

func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {


        // set firebase apns token
        FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenType.Unknown)
}

As an added note. Using "priority":"high" was useful for testing as it sent the notification right away.

这篇关于Firebase Cloud Messaging iOS:无后台推送通知的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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