Push-уведомления не работают в Firebase 4.0
я обновил свои стручки сегодня до новой Firebase 4.0. Я прошел через предложенные изменения и схватил код из примера Github. Я буду честен, я в недоумении, я беру токен FCM и отправляю сообщение с консоли firebase, и я ничего не получаю.
Я обновляю, и он говорит, что сообщение было отправлено, но я проверяю консоль и устройство, и ничего нет. Что я упускаю?
вот мой appdelegate:
//
// Created by Erik Grosskurth on 4/24/17.
//
import UIKit
import FirebaseAnalytics
import FirebaseInstanceID
import FirebaseMessaging
import UserNotifications
import SystemConfiguration
import MobileCoreServices
import Quickblox
import QuickbloxWebRTC
let kQBApplicationID:UInt = 3545252534
let kQBAuthKey = "udfgsegsetrgsextr"
let kQBAuthSecret = "setbsetbsetbsetrbset"
let kQBAccountKey = "sbrtsbrtbsrtbsrtbrt"
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
let gcmMessageIDKey = "gcm.message_id"
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// [START register_for_notifications]
FirebaseApp.configure()
Messaging.messaging().delegate = self
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()
if (Messaging.messaging().fcmToken != nil) {
DataModel.sharedInstance.sessionInfo.FirebaseAccessToken = Messaging.messaging().fcmToken!
print("FCM token: (DataModel.sharedInstance.sessionInfo.FirebaseAccessToken)")
}else {
print("token was nil")
}
// [END register_for_notifications]
//Quickblox config
QBSettings.setApplicationID(kQBApplicationID)
QBSettings.setAuthKey(kQBAuthKey)
QBSettings.setAuthSecret(kQBAuthSecret)
QBSettings.setAccountKey(kQBAccountKey)
// Set settings for zone
QBSettings.setApiEndpoint("https://api.quickblox.com", chatEndpoint: "chat.quickblox.com", forServiceZone: .production)
// Activate zone
QBSettings.setServiceZone(.production)
QBSettings.setKeepAliveInterval(30)
QBSettings.setAutoReconnectEnabled(true)
QBRTCConfig.setStatsReportTimeInterval(1)
QBRTCConfig.setDialingTimeInterval(5)
QBRTCConfig.setAnswerTimeInterval(60)
return true
}
// [START receive_message]
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
Messaging.messaging().appDidReceiveMessage(userInfo)
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: (messageID)")
}
print(userInfo)
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
Messaging.messaging().appDidReceiveMessage(userInfo)
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: (messageID)")
}
print(userInfo)
completionHandler(UIBackgroundFetchResult.newData)
}
// when APNs has assigned the device a unique token
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
print("didRegisterForRemoteNotificationsWithDeviceToken()")
Messaging.messaging().apnsToken = deviceToken
//Messaging.messaging().setAPNSToken(deviceToken, type: MessagingAPNSTokenType.sandbox)
//Messaging.messaging().setAPNSToken(deviceToken, type: MessagingAPNSTokenType.prod)
//Messaging.messaging().setAPNSToken(deviceToken, type: MessagingAPNSTokenType.unknown)
let deviceTokenString = deviceToken.reduce("", { + String(format: "%02X", )})
DataModel.sharedInstance.sessionInfo.APNSAccessToken = deviceTokenString
print("APNS Access Token: (deviceTokenString)")
}
// [END receive_message]
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("Unable to register for remote notifications: (error.localizedDescription)")
}
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) {
QBChat.instance().disconnect { (error) in
if error != nil {
print("error: (String(describing: error))")
} else {
print("success for applicationDidEnterBackground")
}
}
}
func applicationWillEnterForeground(_ application: UIApplication) {
let qbUser = QBUUser()
qbUser.id = DataModel.sharedInstance.qbLoginParams.id
qbUser.password = DataModel.sharedInstance.sessionInfo.QBPassword
QBChat.instance().connect(with: qbUser) { (error) in
if error != nil {
print("error: (String(describing: error))")
} else {
print("success for applicationWillEnterForeground")
}
}
}
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) {
QBChat.instance().disconnect { (error) in
if error != nil {
print("error: (String(describing: error))")
} else {
print("success for applicationWillTerminate")
}
}
}
// LOCK IN PORTRAIT MODE
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return UIInterfaceOrientationMask(rawValue: UIInterfaceOrientationMask.portrait.rawValue)
}
}
// [START ios_10_message_handling]
@available(iOS 10, *)
extension AppDelegate : UNUserNotificationCenterDelegate {
// Receive displayed notifications for iOS 10 devices.
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
let userInfo = notification.request.content.userInfo
// With swizzling disabled you must let Messaging know about the message, for Analytics
Messaging.messaging().appDidReceiveMessage(userInfo)
// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: (messageID)")
}
// Print full message.
print(userInfo)
// Change this to your preferred presentation option
completionHandler([])
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: (messageID)")
}
// Print full message.
print(userInfo)
completionHandler()
}
}
// [END ios_10_message_handling]
extension AppDelegate : MessagingDelegate {
// [START refresh_token]
func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String) {
DataModel.sharedInstance.sessionInfo.FirebaseAccessToken = fcmToken
print("Firebase registration token: (fcmToken)")
}
// [END refresh_token]
// [START ios_10_data_message]
// Receive data messages on iOS 10+ directly from FCM (bypassing APNs) when the app is in the foreground.
// To enable direct data messages, you can set Messaging.messaging().shouldEstablishDirectChannel to true.
func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) {
print("Received data message: (remoteMessage.appData)")
}
// [END ios_10_data_message]
}
здесь журналы:
2017-05-31 16:49:56.937067-0400 Telemed[1843:937699] [Firebase/Analytics][I-ACS003016] Firebase Analytics App Delegate Proxy is disabled. To log deep link campaigns manually, call the methods in FIRAnalytics+AppDelegate.h.
2017-05-31 16:49:56.937 Telemed[1843] <Warning> [Firebase/Analytics][I-ACS003016] Firebase Analytics App Delegate Proxy is disabled. To log deep link campaigns manually, call the methods in FIRAnalytics+AppDelegate.h.
2017-05-31 16:49:57.023568-0400 Telemed[1843:937706] [Firebase/Analytics][I-ACS005000] The AdSupport Framework is not currently linked. Some features will not function properly. Learn more at
2017-05-31 16:49:57.023 Telemed[1843] <Warning> [Firebase/Analytics][I-ACS005000] The AdSupport Framework is not currently linked. Some features will not function properly. Learn more at
2017-05-31 16:49:57.028454-0400 Telemed[1843:937697] [Firebase/Analytics][I-ACS023007] Firebase Analytics v.4000000 started
2017-05-31 16:49:57.028 Telemed[1843] <Notice> [Firebase/Analytics][I-ACS023007] Firebase Analytics v.4000000 started
2017-05-31 16:49:57.029042-0400 Telemed[1843:937697] [Firebase/Analytics][I-ACS023008] To enable debug logging set the following application argument: -FIRAnalyticsDebugEnabled (see )
2017-05-31 16:49:57.029 Telemed[1843] <Notice> [Firebase/Analytics][I-ACS023008] To enable debug logging set the following application argument: -FIRAnalyticsDebugEnabled (see )
FCM token: myTokenIsHere
2017-05-31 16:49:57.101756-0400 Telemed[1843:937699] [Firebase/Analytics][I-ACS032003] iAd framework is not linked. Search Ad Attribution Reporter is disabled.
2017-05-31 16:49:57.102 Telemed[1843] <Warning> [Firebase/Analytics][I-ACS032003] iAd framework is not linked. Search Ad Attribution Reporter is disabled.
2017-05-31 16:49:57.103700-0400 Telemed[1843:937697] [Firebase/Analytics][I-ACS023012] Firebase Analytics enabled
2017-05-31 16:49:57.103 Telemed[1843] <Notice> [Firebase/Analytics][I-ACS023012] Firebase Analytics enabled
Destroyed Session but Saved Login
2017-05-31 16:49:57.158678-0400 Telemed[1843:937637] [MC] System group container for systemgroup.com.apple.configurationprofiles path is /private/var/containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles
2017-05-31 16:49:57.159102-0400 Telemed[1843:937637] [MC] Reading from public effective user settings.
didRegisterForRemoteNotificationsWithDeviceToken()
APNS Access Token: 091F01B...
>>>------> **решена
ДЛЯ ГЛУБОКОГО ПОГРУЖЕНИЯ В УСТРАНЕНИЕ НЕПОЛАДОК И ОКОНЧАТЕЛЬНЫЙ FACEPALM В КОНЦЕ... СЛЕДУЙТЕ ЭТОЙ ТЕМЕ: https://github.com/firebase/quickstart-ios/issues/290
ОСОБАЯ БЛАГОДАРНОСТЬ РИЗ ЗА СВОЕ ВРЕМЯ В ВЫЯСНЕНИИ ВОПРОСА!!
1 ответов
Firebase Cloud Messaging довольно сложно правильно настроить на iOS, потому что вы должны убедиться, что ваша конфигурация APNs работает, а затем добавить FCM поверх этого.
Настройка APNs
ключи аутентификации APNs также очень хороши apple, потому что они не истекают, работают как в песочнице, так и в производственных средах ,и тот же ключ (как ) можно использовать для отправки push-уведомлений все приложения под этим Apple Учетная запись разработчика.
он также вводит новую область для потенциального отказа:опечатки. Вы можете ввести случайный идентификатор пакета, и пока в Xcode настроена правильная "команда", ваше приложение с радостью получит маркер устройства APNs.
отправка уведомления на этот токен устройства через APNs (я использовал этот скрипт для отправки тестовых уведомлений по ключам HTTP/2 + Auth) даст DeviceTokenNotForTopic
ошибка, так что это должно помочь вам выяснить, что пошло неправильный.
памятка
- убедитесь, что Ваш идентификатор пакета приложений соответствует идентификатору пакета, который вы отправляете в
- убедитесь, что у вас есть файл entitlements, по крайней мере
aps-environment
ключ установлен вdevelopment
(это автоматически обновляется для вас в сборках выпуска, Xcode) - при использовании "автоматической" конфигурации( т. е. swizzling) в других SDK, таких как Firebase, убедитесь, что вы получаете токен APNs в
application:didRegisterForRemoteNotificationsWithDeviceToken:
. Это как минимум подтверждает, что ваша настройка APNs в порядке (но все же у вас может быть опечатка)
настройка FCM
убедитесь, что вы используете это приложение, как BUNDLE_ID
ключ в plist. Я видел, как разработчики думают, что, поскольку ключи APNs должны отлично работать во всех своих приложениях, это то же самое GoogleService-Info.plist
отлично подходит для приложений, но это не так.
тестирование
Я бы также рекомендовал отправить себе тест уведомления с помощью HTTP API FCM от терминала, чтобы помочь отладить проблему. В отличие от Firebase Notifications Console, он даст вам любые необработанные ошибки, с которыми он сталкивается. Вот пример:
curl -X "POST" "https://fcm.googleapis.com/fcm/send" \
-H "Authorization: key=SERVER_KEY" \
-H "Content-Type: application/json" \
-d $'{
"notification": {
"body": "Testing with direct FCM API",
"title": "Test Message",
"badge": "0",
"sound": "default"
},
"registration_ids": [
"FCM_TOKEN"
]
}'
заполнить SERVER_KEY
со значением в консоли Firebase > параметры проекта > облачные сообщения > ключ сервера. Заменить FCM_TOKEN
С вашим маркером FCM.
Я использую Лапа для отправки тестовых уведомлений в Мои приложения, когда я работаю над FCM пакет SDK.