Xcode 8.3 Swift 3 FCM 通知上的 Firebase 问题 iOS 10.3 不起作用
Posted
技术标签:
【中文标题】Xcode 8.3 Swift 3 FCM 通知上的 Firebase 问题 iOS 10.3 不起作用【英文标题】:Firebase Issues iOS 10.3 on Xcode 8.3 Swift 3 FCM notifications not working 【发布时间】:2017-05-30 15:28:59 【问题描述】:我正在使用 Swift 3 为 iOS 10.3.2 开发 Xcode 8.3.2,我的项目使用 firebase 云消息传递,当我的 p12 证书已过期,我按照 Firebase 文档的建议将我的证书 p12 更新为 p8,但是昨天当我使用控制台 firebase 进行测试,它正在工作,但今天没有,日志正常打印我:
2017-05-30 10:13:23.932066-0400 lol[5576:1530669] WARNING: Firebase Analytics App Delegate Proxy is disabled. To log deep link campaigns manually, call the methods in FIRAnalytics+AppDelegate.h.
2017-05-30 10:13:23.949512-0400 lol[5576:1530669] Firebase automatic screen reporting is enabled. Call +[FIRAnalytics setScreenName:setScreenClass:] to set the screen name or override the default screen class name. To disable automatic screen reporting, set the flag FirebaseAutomaticScreenReportingEnabled to NO in the Info.plist
2017-05-30 10:13:24.368364-0400 lol[5576:1530669] [Crashlytics] Version 3.8.2 (118)
2017-05-30 10:13:24.397942-0400 lol[5576:1530669] [MC] System group container for systemgroup.com.apple.configurationprofiles path is /private/var/containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles
2017-05-30 10:13:24.398433-0400 lol[5576:1530669] [MC] Reading from public effective user settings.
initializeFCM
Notification access accepted.
2017-05-30 10:13:24.679: <FIRInstanceID/WARNING> Failed to fetch APNS token Error Domain=com.firebase.iid Code=1001 "(null)"
2017-05-30 10:13:24.681: <FIRMessaging/INFO> FIRMessaging library version 1.2.0
2017-05-30 10:13:24.683213-0400 lol[5576:1530706] [Firebase/Crash][I-CRA000004] Successfully initialized
2017-05-30 10:13:24.683 lol[5576] <Notice> [Firebase/Crash][I-CRA000004] Successfully initialized
2017-05-30 10:13:24.685110-0400 lol[5576:1530706] <FIRAnalytics/INFO> Firebase Analytics v.3600000 started
2017-05-30 10:13:24.685 lol[5576:] <FIRAnalytics/INFO> Firebase Analytics v.3600000 started
2017-05-30 10:13:24.685438-0400 lol[5576:1530706] <FIRAnalytics/INFO> To enable debug logging set the following application argument: -FIRAnalyticsDebugEnabled
2017-05-30 10:13:24.685 lol[5576:] <FIRAnalytics/INFO> To enable debug logging set the following application argument: -FIRAnalyticsDebugEnabled
"GCM TOKEN = Optional(\"it's working: PLEASE HELP ***\")"
"didRegisterForRemoteNotificationsWithDeviceToken: DATA"
"*** deviceToken: <66666666 it's working: PLEASE HELP *** 99999999>"
2017-05-30 10:13:24.837: <FIRInstanceID/WARNING> APNS Environment in profile: development
"Firebase Token:" Optional("it's working: PLEASE HELP ***")
2017-05-30 10:13:24.932076-0400 lol[5576:1530727] <FIRAnalytics/INFO> Firebase Analytics enabled
2017-05-30 10:13:24.932 lol[5576:] <FIRAnalytics/INFO> Firebase Analytics enabled
"Connected to FCM."
新的奇怪日志是:
2017-05-30 10:13:24.679: <FIRInstanceID/WARNING> Failed to fetch APNS token Error Domain=com.firebase.iid Code=1001 "(null)"
我的代码是:
//
// AppDelegate.swift
// lol
//
// Created by Dennis Mostajo on 06/06/16. ---> 666 the number of the beast! O_O!
// Copyright © 2016 Dennis Mostajo. All rights reserved.
//
import UIKit
import FirebaseAnalytics
import FirebaseInstanceID
import FirebaseMessaging
import UserNotifications
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
// Override point for customization after application launch.
self.initializeFCM(application)
let token = FIRInstanceID.instanceID().token()
debugPrint("GCM TOKEN = \(String(describing: token))")
return true
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error)
debugPrint("didFailToRegisterForRemoteNotificationsWithError: \(error)")
func applicationReceivedRemoteMessage(_ remoteMessage: FIRMessagingRemoteMessage)
debugPrint("remoteMessage:\(remoteMessage.appData)")
func initializeFCM(_ application: UIApplication)
print("initializeFCM")
//-------------------------------------------------------------------------//
if #available(ios 10.0, *) // enable new way for notifications on iOS 10
let center = UNUserNotificationCenter.current()
center.delegate = self
center.requestAuthorization(options: [.badge, .alert , .sound]) (accepted, error) in
if !accepted
print("Notification access denied.")
else
print("Notification access accepted.")
UIApplication.shared.registerForRemoteNotifications();
else
let type: UIUserNotificationType = [UIUserNotificationType.badge, UIUserNotificationType.alert, UIUserNotificationType.sound];
let setting = UIUserNotificationSettings(types: type, categories: nil);
UIApplication.shared.registerUserNotificationSettings(setting);
UIApplication.shared.registerForRemoteNotifications();
FIRApp.configure()
NotificationCenter.default.addObserver(self, selector: #selector(self.tokenRefreshNotificaiton),
name: NSNotification.Name.firInstanceIDTokenRefresh, object: nil)
func registrationhandler(_ registrationToken: String!, error: NSError!)
if (registrationToken != nil)
debugPrint("registrationToken = \(String(describing: registrationToken))")
else
debugPrint("Registration to GCM failed with error: \(error.localizedDescription)")
func tokenRefreshNotificaiton(_ notification: Foundation.Notification)
if let refreshedToken = FIRInstanceID.instanceID().token()
debugPrint("InstanceID token: \(refreshedToken)")
connectToFcm()
func connectToFcm()
// Won't connect since there is no token
guard FIRInstanceID.instanceID().token() != nil else
return;
// Disconnect previous FCM connection if it exists.
FIRMessaging.messaging().disconnect()
FIRMessaging.messaging().connect (error) in
if (error != nil)
debugPrint("Unable to connect with FCM. \(String(describing: error))")
else
debugPrint("Connected to FCM.")
func application(_ application: UIApplication, didRegister notificationSettings: UIUserNotificationSettings)
debugPrint("didRegister notificationSettings")
if (notificationSettings.types == .alert || notificationSettings.types == .badge || notificationSettings.types == .sound)
application.registerForRemoteNotifications()
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData)
debugPrint("didRegisterForRemoteNotificationsWithDeviceToken: NSDATA")
let token = String(format: "%@", deviceToken as CVarArg)
debugPrint("*** deviceToken: \(token)")
#if RELEASE_VERSION
FIRInstanceID.instanceID().setAPNSToken(deviceToken as Data, type:FIRInstanceIDAPNSTokenType.prod)
#else
FIRInstanceID.instanceID().setAPNSToken(deviceToken as Data, type:FIRInstanceIDAPNSTokenType.sandbox)
#endif
debugPrint("Firebase Token:",FIRInstanceID.instanceID().token() as Any)
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void)
//Handle the notification ON APP foreground
debugPrint("*** willPresent notification")
debugPrint("*** notification: \(notification)")
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void)
//Handle the notification ON BACKGROUND
debugPrint("*** didReceive response Notification ")
debugPrint("*** response: \(response)")
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)
debugPrint("didRegisterForRemoteNotificationsWithDeviceToken: DATA")
let token = String(format: "%@", deviceToken as CVarArg)
debugPrint("*** deviceToken: \(token)")
#if RELEASE_VERSION
FIRInstanceID.instanceID().setAPNSToken(deviceToken as Data, type:FIRInstanceIDAPNSTokenType.prod)
#else
FIRInstanceID.instanceID().setAPNSToken(deviceToken as Data, type:FIRInstanceIDAPNSTokenType.sandbox)
#endif
debugPrint("Firebase Token:",FIRInstanceID.instanceID().token() as Any)
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (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
FIRMessaging.messaging().appDidReceiveMessage(userInfo)
if let messageID = userInfo["gcm.message_id"]
debugPrint("Message ID: \(messageID)")
debugPrint("*** userInfo: \(userInfo)")
// Print full message.
completionHandler(.newData)
func application(_ application: UIApplication, didReceive notification: UILocalNotification)
if application.applicationState != UIApplicationState.active
if let gcmMessageType = GCMMessageType(rawValue: notificationType)
debugPrint("didReceiveLocalNotification")
debugPrint("notification:\(notification)")
//application.applicationIconBadgeNumber = 0
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 invalidate graphics rendering callbacks. 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.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
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.
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.
connectToFcm()
func applicationWillTerminate(_ application: UIApplication)
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
我犯了一些错误?,或者我需要配置一些东西?,更多的东西应该增加 iOS 9 和 iOS 10.3 之间的差异,或者添加到firebase 设置,非常感谢您的帮助
//--------------------------------------------- -------------------------------------------------- -------------------------------------------//
编辑:
再次嗨,我已将 Firebase 更新到最新版本 4.0.0,在我的代码中进行这些更新:
func initializeFCM(_ application: UIApplication)
print("initializeFCM")
//-------------------------------------------------------------------------//
if #available(iOS 10.0, *) // enable new way for notifications on iOS 10
let center = UNUserNotificationCenter.current()
center.delegate = self
center.requestAuthorization(options: [.badge, .alert , .sound]) (accepted, error) in
if !accepted
print("Notification access denied.")
else
print("Notification access accepted.")
UIApplication.shared.registerForRemoteNotifications();
else
let type: UIUserNotificationType = [UIUserNotificationType.badge, UIUserNotificationType.alert, UIUserNotificationType.sound];
let setting = UIUserNotificationSettings(types: type, categories: nil);
UIApplication.shared.registerUserNotificationSettings(setting);
UIApplication.shared.registerForRemoteNotifications();
//-------------------------------------------------------------------------//
FirebaseApp.configure()
Messaging.messaging().shouldEstablishDirectChannel = true
NotificationCenter.default.addObserver(self, selector: #selector(self.tokenRefreshNotificaiton),
name: NSNotification.Name.InstanceIDTokenRefresh, object: nil)
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData)
debugPrint("didRegisterForRemoteNotificationsWithDeviceToken: NSDATA")
let token = String(format: "%@", deviceToken as CVarArg)
debugPrint("*** deviceToken: \(token)")
Messaging.messaging().apnsToken = deviceToken as Data
debugPrint("Firebase Token:",InstanceID.instanceID().token() as Any)
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)
debugPrint("didRegisterForRemoteNotificationsWithDeviceToken: DATA")
let token = String(format: "%@", deviceToken as CVarArg)
debugPrint("*** deviceToken: \(token)")
Messaging.messaging().apnsToken = deviceToken
debugPrint("Firebase Token:",InstanceID.instanceID().token() as Any)
func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage)
debugPrint("--->messaging:\(messaging)")
debugPrint("--->didReceive Remote Message:\(remoteMessage.appData)")
guard let data =
try? JSONSerialization.data(withJSONObject: remoteMessage.appData, options: .prettyPrinted),
let prettyPrinted = String(data: data, encoding: .utf8) else return
print("Received direct channel message:\n\(prettyPrinted)")
几个警告日志消失了,但是当我以前台和后台方式进行测试时,此日志会打印我:
2017-06-01 17:40:12.897916-0400 lol[8275:2217196] [Firebase/Messaging][I-FCM002019] FIRMessaging received data-message, but FIRMessagingDelegate's-messaging:didReceiveMessage: not implemented
2017-06-01 17:40:12.898 lol[8275] <Warning> [Firebase/Messaging][I-FCM002019] FIRMessaging received data-message, but FIRMessagingDelegate's-messaging:didReceiveMessage: not implemented
"###> 1.2 AppDelegate DidEnterBackground"
2017-06-01 17:40:29.943006-0400 lol[8275:2217037] Could not signal service com.apple.WebKit.WebContent: 113: Could not find specified service
2017-06-01 17:40:29.944689-0400 lol[8275:2217037] Could not signal service com.apple.WebKit.Networking: 113: Could not find specified service
2017-06-01 17:40:30.000428-0400 lol[8275:2217203] dnssd_clientstub read_all(27) DEFUNCT
"###> 1.3 AppDelegate DidBecomeActive"
2017-06-01 17:40:30.760941-0400 lol[8275:2217443] [Firebase/Messaging][I-FCM002019] FIRMessaging received data-message, but FIRMessagingDelegate's-messaging:didReceiveMessage: not implemented
2017-06-01 17:40:30.761 lol[8275] <Warning> [Firebase/Messaging][I-FCM002019] FIRMessaging received data-message, but FIRMessagingDelegate's-messaging:didReceiveMessage: not implemented
我试过了,但它仍然显示那些日志并且它没有显示任何通知:
我有什么遗漏吗?谢谢您的回答!
【问题讨论】:
这里有些问题: @ikanimo 我已经更新了我的问题,有什么想法或帮助吗?,再次感谢 您是如何将 .p12 转换为 .p8 的? 您无法将 .p12 证书转换为 .p8 证书,您必须从头开始创建一个新证书,***.com/questions/39672297/… 【参考方案1】:您需要将推送通知证书添加到 Cloud Messaging 中的 FCM 控制台。只有这样它才能向您的应用程序发送通知。此外,请确保您已在 iOS 应用的功能中启用推送通知。
更新:
extension AppDelegate: MessagingDelegate
// Registering for Firebase notifications
func configureFirebase(application: UIApplication)
FirebaseApp.configure()
Messaging.messaging().delegate = self
// Register for remote notifications. This shows a permission dialog on first run, to
// show the dialog at a more appropriate time move this registration accordingly.
// [START register_for_notifications]
if #available(iOS 10.0, *)
// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.current().delegate = self
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
options: authOptions,
completionHandler: _, _ in )
else
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
print("-----firebase token: \(String(describing: Messaging.messaging().fcmToken)) ----")
//MARK: FCM Token Refreshed
func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String)
// FCM token updated, update it on Backend Server
func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage)
print("remoteMessage: \(remoteMessage)")
//Called when a notification is delivered to a foreground app.
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void)
completionHandler([.alert, .badge, .sound])
//Called to let your app know which action was selected by the user for a given notification.
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void)
print("User Info = \(response.notification.request.content.userInfo)")
completionHandler()
在您的AppDelegate
的didFinishLaunchingWithOptions
内致电configureFirebase(application:)
。
【讨论】:
我做了所有这些,但错误仍然存在,谢谢FIRMessaging.messaging().remoteMessageDelegate = self
尝试在initializeFCM()
之后的center.delegate = self
行之后添加上面的行。另外,请确保您的 AppDelegate 确认 FIRMessagingDelegate
协议。
我已经更新了我的问题,有什么想法或帮助吗?,再次感谢!
@user_Dennis_Mostajo 您需要遵守 MessagingDelegate 协议-func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) // to conform to MessagingDelegate
。在你的 AppDelegate 中添加这个函数
我添加了,如果你修改编辑,我在代码的最后部分实现了那个功能,包括一个调试打印,但仍然打印那个警告日志,我不知道为什么不能识别委托属性以上是关于Xcode 8.3 Swift 3 FCM 通知上的 Firebase 问题 iOS 10.3 不起作用的主要内容,如果未能解决你的问题,请参考以下文章
Socket.IO 错误:zlib 没有这样的模块(Swift 3,Xcode 8.3)
目标 C 项目中的 Xcode 8.3 Swift 版本错误 (SWIFT_VERSION)
Swift 3、iOS 10+、xCode 8.3+、Quickblox - 在保持纵横比/视频分辨率的同时切换全屏远程流