ios - iOS 中的推送通知突然无法通过 Firebase 传递
问题描述
最近我停止接收 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 中没有禁用应用程序通知。
解决方案
如果您使用 keyid 而不是认证,您可以尝试将您的调试模式更改为发布模式,然后您可以尝试查看是否收到推送,或者您可以上传到 TestFlight 并检查是否收到推送。但是,最好使用证书而不是可以在调试和发布模式下使用的 keyid。
推荐阅读
- excel - 我如何才能在 excel 中只清除此代码中突出显示的先前单元格?
- google-apps-script - 如何停止 Google 表格中同时触发/冲突的功能?
- typescript - 如何将具有计算属性的对象转换为类型?
- php - 如何使用授权令牌(承载)在 laravel-8 中重置密码?
- logstash - 来自行的 Grok 模式 - 自定义日期
- sql - 在 PostgreSQL 中按“最快”对带有“timestamptz”的行进行排序
- amazon-web-services - ECS awsvpc 容器无法访问
- mysql - 如何使用 chrome 扩展名执行 SQL 数据库?
- android - 插件不能有不同的 kotlin 版本?无法初始化类 org.jetbrains.kotlin.gradle.internal.KotlinSourceSetProviderImplKt
- excel - 在使用 vba 将数据粘贴到外部 Excel 文件之前,如何取消对它的保护?