iOS 中的推送通知突然无法通过 Firebase 传递
Posted
技术标签:
【中文标题】iOS 中的推送通知突然无法通过 Firebase 传递【英文标题】:Push notifications in iOS suddenly not delivering via Firebase 【发布时间】:2020-06-29 20:48:02 【问题描述】:最近我停止接收 Firebase Cloud Messaging APNs 通知。我决定更新到最新版本的 Firebase pod,而我的 AppDelegate.swift
有一些功能已弃用,因此它现在看起来像这样:
import UIKit
import SwiftyJSON
import IQKeyboardManagerSwift
import Firebase
import FirebaseInstanceID
import FirebaseMessaging
import UserNotifications
import AVFoundation
import Crittercism
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, MessagingDelegate, UNUserNotificationCenterDelegate
var window: UIWindow?
var isPulltoRefreshInProgress: Bool = Bool(false)
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
Crittercism.enable(withAppID: Config.sharedInstance.apteligentAppID())
//To find Home Directory
print("Home Directory - \(NSHomeDirectory())")
IQKeyboardManager.shared.enable = true
IQKeyboardManager.shared.enableAutoToolbar = false
IQKeyboardManager.shared.shouldShowToolbarPlaceholder = false
// IQKeyboardManager.shared.shouldResignOnTouchOutside = true
// UIApplication.shared.statusBarStyle = .lightContent
configureForPushNotification()
registrationForNotification(application: application )
self.startOver()
return true
func registrationForNotification(application: UIApplication)
// ios 10 support
if #available(iOS 10, *)
DLog("registrationForNotification")
UNUserNotificationCenter.current().delegate = self
UNUserNotificationCenter.current().requestAuthorization(options:[.badge, .alert, .sound]) (granted, error) in
application.registerForRemoteNotifications()
else
application.registerForRemoteNotifications(matching: [.badge, .sound, .alert])
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void)
Tokens.sharedInstance.isNotificationCame = true
NotificationCenter.default.post(name: NSNotification.Name(NotificationCenterIDs.kPushNotificationReceivedNotification), object:self)
if application.applicationState == UIApplication.State.active
DLog("App is in foreground when notification received")
// app was already in the foreground
else
DLog("App was just brought from background to foreground via PUSH")
// app was just brought from background to foreground via PUSH
self.startOver()
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void)
// let application = UIApplication.shared
// if(application.applicationState == .active)
// DLog("user tapped the notification bar when the app is in foreground")
if let window = self.window
if let viewController = UIStoryboard(name: StoryboardControllerIDs.kStoryboardId, bundle: nil).instantiateViewController(withIdentifier: StoryboardController.kNotificationsViewController) as? NotificationsViewController
if let rootViewController = window.rootViewController as? UINavigationController
// DLog("Root: " + String(describing: type(of: rootViewController)))
Tokens.sharedInstance.isNotificationCame = true
rootViewController.pushViewController(viewController, animated: true)
//
// if(application.applicationState == .inactive)
//
// DLog("user tapped the notification bar when the app is in background")
//
/* Change root view controller to a specific viewcontroller */
// let storyboard = UIStoryboard(name: "Main", bundle: nil)
// let vc = storyboard.instantiateViewController(withIdentifier: "ViewControllerStoryboardID") as? ViewController
// self.window?.rootViewController = vc
completionHandler()
func configureForPushNotification()
var fileName : String = "GoogleServiceQA-Info"
let currentConfiguration = Bundle.main.object(forInfoDictionaryKey: "Config")! as! String
if currentConfiguration.lowercased() == "production"
fileName = "GoogleServiceProd-Info"
let filePath = Bundle.main.path(forResource: fileName, ofType: "plist")!
let options = FirebaseOptions(contentsOfFile: filePath)
FirebaseApp.configure(options: options!)
Messaging.messaging().delegate = self
// if let refreshedToken = InstanceID.instanceID().token()
// print("InstanceID token: \(refreshedToken)")
// DeviceTokenConstants.deviceToken = refreshedToken
//
InstanceID.instanceID().instanceID (result, error) in
if let error = error
DLog("Error fetching remote instange ID: \(error)")
else if let result = result
DLog("configureForPushNotification - Remote instance ID token: \(result.token)")
DeviceTokenConstants.deviceToken = result.token
NotificationCenter.default.addObserver(self, selector:
#selector(tokenRefreshNotification), name:
NSNotification.Name.InstanceIDTokenRefresh, object: nil)
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)
//Getting errors in Xcode10 for iOS12
let hexString = deviceToken.map String(format: "%02.2hhx", $0) .joined()
DLog("===DEVICE-TOKEN: \(hexString)")
// In debug mode
Messaging.messaging().apnsToken = deviceToken
Messaging.messaging().setAPNSToken(deviceToken, type: .sandbox)
Messaging.messaging().setAPNSToken(deviceToken, type: .prod)
// In release mode
// InstanceID.instanceID().setAPNSToken(deviceToken, type: InstanceIDAPNSTokenType.prod)
// This method will be called when app received push notifications in foreground
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void)
completionHandler([.alert, .badge, .sound])
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String)
print("Firebase registration token: \(fcmToken)")
DeviceTokenConstants.deviceToken = fcmToken
FireBaseToken.didReceived = true
@objc func tokenRefreshNotification(_ notification: Notification)
InstanceID.instanceID().instanceID (result, error) in
if let error = error
print("Error fetching remote instange ID: \(error)")
else if let result = result
print("tokenRefreshNotification - Remote instance ID token: \(result.token)")
DeviceTokenConstants.deviceToken = result.token
let dataDict:[String: String] = ["token": result.token]
NotificationCenter.default.post(name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict)
// Deprecated code
// if let refreshedToken = InstanceID.instanceID().token()
// print("InstanceID token: \(refreshedToken)")
// DeviceTokenConstants.deviceToken = refreshedToken
//
// Connect to FCM since connection may have failed when attempted before having a token.
// connectToFcm()
此代码中是否有某些内容可能会阻止发送通知,或者这是 iOS 应用程序之外的外部问题?我可以看到在我的控制台中为设备令牌和 fcm 令牌打印了令牌,所以我觉得 iOS 应用程序中的设置不是问题。我确保我的 iPhone 中没有禁用应用通知。
【问题讨论】:
【参考方案1】:如果您使用keyid而不是证书,您可以尝试将您的调试模式更改为发布模式,然后您可以尝试查看是否收到推送,或者您可以上传到TestFlight并检查是否收到推送。 但是最好使用证书而不是可以在调试和发布模式下使用的 keyid。
【讨论】:
在 APNs 证书中的认证?如果是这样,那么这就是我正在使用的 你有发布和调试apn认证吗? 我在控制台上传了一个开发 APN 证书,而发行版有自己的项目,该项目只导入了生产 APNs 证书 两者分配的捆绑包 ID 略有不同,因此它们的设置方式允许它们被视为 2 个不同的应用程序。【参考方案2】:我从您的代码中不明白为什么它不起作用,您是否尝试过关注firebase's guide 的信函?它从来没有给我带来任何问题。
【讨论】:
我想是我上传的APNS证书。这需要先得到确认。一旦他们向我发送正确的证书,就会更新您。我可能必须在 Firebase 控制台的生产 APNs 证书中上传推送证书。以上是关于iOS 中的推送通知突然无法通过 Firebase 传递的主要内容,如果未能解决你的问题,请参考以下文章
为啥推送通知不能在 iOS 中使用 Firebase 从设备到设备?
iOS Swift 使用 Firebase 云消息发送丰富的推送通知
在应用程序被杀死后,使用 HTTP 请求通过 Firebase(FCM)向 iOS 设备发送推送通知 [重复]