Firebase 云消息传递不会创建推送通知,但会获取信息

Posted

技术标签:

【中文标题】Firebase 云消息传递不会创建推送通知,但会获取信息【英文标题】:Firebase Cloud Messaging Doesn't Create Push Notifications but Gets Information 【发布时间】:2016-10-22 08:24:42 【问题描述】:

我正在学习本教程 (https://www.youtube.com/watch?v=JsWHzU1DxjM) 以尝试将推送通知放入我的 ios 应用程序。我能够成功获得 APNS 证书并将“推送通知”和“后台模式”功能设置为开启。此外,当我从 firebase 控制台发送通知时,Firebase 能够从通知中获取信息。但是,当应用程序在后台运行时,横幅通知永远不会出现。我觉得我可能在将教程从 Objective-C 转换为 Swift 时遇到问题,因为教程是在 Objective-C 中的,但我不确定。如果有帮助的话,我会放置我的 AppDelegate 类和程序输出。

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate 

var window: UIWindow?

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool 

    connectToFcm()

    NSNotificationCenter.defaultCenter().addObserver(
        self,
        selector: #selector(tokenRefreshCallback),
        name: kFIRInstanceIDTokenRefreshNotification,
        object: nil)

    let allNotificationTypes = UIUserNotificationType(arrayLiteral: UIUserNotificationType.Sound, UIUserNotificationType.Alert, UIUserNotificationType.Badge)
    let settings = UIUserNotificationSettings(forTypes: allNotificationTypes, categories: nil)
    application.registerUserNotificationSettings(settings)
    application.registerForRemoteNotifications()
    return FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)


func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool 
    return FBSDKApplicationDelegate.sharedInstance().application(application, openURL: url, sourceApplication: sourceApplication, annotation: annotation)


override init() 
    FIRApp.configure()
    FIRDatabase.database().persistenceEnabled = false


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.
    FIRMessaging.messaging().disconnect()
    print("Disconnected from FCM.")
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.


func applicationWillEnterForeground(application: UIApplication) 
    connectToFcm()
    // 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) 
    // 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) 
    //try! FIRAuth.auth()!.signOut()


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



func tokenRefreshCallback(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()
    

    

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("\(userInfo)")
    //print("Message ID: \(userInfo["gcm.message_id"]!)")
    NSNotificationCenter.defaultCenter().postNotificationName("name", object: userInfo)

    // Print full message.
    print("%@", userInfo)


控制台日志:

2016-06-20 19:14:50.801 MapKitTry[2244:721460] Configuring the default app.
2016-06-20 19:14:50.839 MapKitTry[2244:] <FIRAnalytics/INFO> Firebase Analytics v.3200000 started
2016-06-20 19:14:50.846 MapKitTry[2244:] <FIRAnalytics/INFO> To enable debug logging set the following application argument: -FIRAnalyticsDebugEnabled (see -omitted-)
2016-06-20 19:14:50.849: <FIRInstanceID/WARNING> FIRInstanceID AppDelegate proxy enabled, will swizzle app delegate remote notification handlers. To disable add "FirebaseAppDelegateProxyEnabled" to your Info.plist and set it to NO
2016-06-20 19:14:50.849: <FIRInstanceID/WARNING> Failed to fetch APNS token Error Domain=com.firebase.iid Code=1001 "(null)"
2016-06-20 19:14:50.853: <FIRMessaging/INFO> FIRMessaging library version 1.1.0
2016-06-20 19:14:50.863: <FIRMessaging/WARNING> FIRMessaging AppDelegate proxy enabled, will swizzle app delegate remote notification receiver handlers. Add "FirebaseAppDelegateProxyEnabled" to your Info.plist and set it to NO
2016-06-20 19:14:50.902 MapKitTry[2244:] <FIRAnalytics/INFO> Successfully created Firebase Analytics App Delegate Proxy automatically. To disable the proxy, set the flag FirebaseAppDelegateProxyEnabled to NO in the Info.plist
no login
2016-06-20 19:14:51.076 MapKitTry[2244:] <FIRAnalytics/INFO> Firebase Analytics enabled
Connected to FCM.
[notification: 
body = "Push notification";
e = 1;
, collapse_key: pdrum3.KingOfTheTown, from: 302278087187]
%@ [notification: 
body = "Push notification";
e = 1;
, collapse_key: pdrum3.KingOfTheTown, from: 302278087187]

【问题讨论】:

在这里你可以看到我的演示=> ***.com/questions/37667753/… 该属性用于设置应用代理接收到的APNS Token。 FIRMessaging 使用方法调配来确保自动设置 APNS 令牌。但是,如果您通过在应用程序的 Info.plist 中将 FirebaseAppDelegateProxyEnabled 设置为 NO 来禁用 swizzling,则应在应用程序委托的 -application:didRegisterForRemoteNotificationsWithDeviceToken: 方法中手动设置 APNS 令牌。如果您想设置 APNS 令牌的类型,而不是依赖自动检测,请参阅:-setAPNSToken:type:. 【参考方案1】:

在 info.plist 中添加 FirebaseAppDelegateProxyEnabled 类型“布尔”值“NO”:

【讨论】:

2天了,终于找到了正确的解决方案。 该属性用于设置应用代理接收到的APNS Token。 FIRMessaging 使用方法调配来确保自动设置 APNS 令牌。但是,如果您通过在应用程序的 Info.plist 中将 FirebaseAppDelegateProxyEnabled 设置为 NO 来禁用 swizzling,则应在应用程序委托的 -application:didRegisterForRemoteNotificationsWithDeviceToken: 方法中手动设置 APNS 令牌。如果您想设置 APNS 令牌的类型,而不是依赖自动检测,请参阅:-setAPNSToken:type:. 如何添加 FirebaseAppDelegateProxyEnabled 转到你的 Flutter 项目 ios 文件夹在 Xcode 中打开它并进入 runner 文件夹,你可以看到 info.plist 文件打开文件并单击信息属性列表加按钮,然后输入 boolean 和 value是 NO 或 0 布尔 => 0 不是 NO【参考方案2】:

您缺少允许您获取通知的 UNUserNotificationDelegate 方法。

extension NotificationManager: UNUserNotificationCenterDelegate 

    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void) 

        switch response.actionIdentifier 

        // NotificationActions is a custom String enum I've defined
        case NotificationActions.HighFive.rawValue:
            print("High Five Delivered!")
        default: break
        
    

    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) 

        // Delivers a notification to an app running in the foreground.
    

这两个委托方法替换了您当前用于接收的旧委托方法(即 didReceiveRemoteNotification)。有关更多信息,请参阅本教程:http://cleanswifter.com/ios-10-local-notifications/

【讨论】:

【参考方案3】:

按照here 的建议,我还必须将此添加到我的AppDelegate

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) 
    Messaging.messaging().apnsToken = deviceToken

【讨论】:

以上是关于Firebase 云消息传递不会创建推送通知,但会获取信息的主要内容,如果未能解决你的问题,请参考以下文章

设备未收到Firebase云消息传递通知

如何使用 Firebase 云消息传递和 Liferay 推送通知

Apple WatchOs 以及用于推送通知的 Firebase 云消息传递

Firebase 云消息传递通知图像定价

没有 AppDelegate 的 SwiftUI 远程推送通知(Firebase 云消息传递)

是否可以在 Firebase 云消息传递中删除或更新推送通知?