Push Notifications не отправляет из FCM после изменения APN Cert
У меня не было проблем с отправкой push-уведомлений от FCM в мое приложение iOS до истечения срока действия одного из моих сертификатов. После его изменения FCM больше не доставляет сообщения. Я прочитал эту статью (https://firebase.googleblog.com/2017/01/debugging-firebase-cloud-messaging-on.html), и вот шаги проверки, которые я прошел до сих пор, но я избиваю голову на стене теперь...
- Прокомментировал любые функции connectToFCM
- Загруженный Pusher и успешно может отправлять уведомления на устройство с помощью сертификата APN
- Успешно сделал скрученные звонки в FCM с успехом (ответ ниже)
- { "multicast_id": 7774794018682407760, "успех": 1, "провал": 0, "canonical_ids": 0, "Результаты": [{ "message_id": "0: 1493321644068397% b76e8527b76e8527" }]}
- Пробовал воссоздать как сертификаты разработки, так и производства
- Пробовал экспортировать их из брелка с паролем и без него
У кого-нибудь есть опыт работы с этой сверхъестественной вещью и есть советы о том, как действовать?
Также стоит отметить, что я не могу удалить сертификаты APN, я вижу этот параметр, но он неактивен, и я не могу его выбрать.
Ответы
Ответ 1
Это полезно для понимания потока.
изображение любезно предоставлено Блог Firebase
Вы проверили, что APN отправляет в приложение. Таким образом, сертификат в порядке.
Из в блог, который вы связали, получив успешный ответ, сделав завиток, означает, что сообщение получено FCM. Это не означает, что сообщение направляется в APN.
Отправить сообщение непосредственно с помощью панели уведомлений Firebase, чтобы узнать, взаимодействует ли FCM с APN.
Если это работает, возникает проблема с вашим форматом сообщений.
Если это не работает.
Убедитесь, что:
-
для приоритета сообщения установлено значение high
, поэтому они отправляются немедленно.
-
"content_available": true
-
удалить и переустановить приложение
-
проверьте код сервера.
Ответ 2
Вместо использования сертификатов APNS для push-уведомления вы можете создать один APN-ключ и использовать его для всех приложений.
APNs
Используйте службу уведомлений Apple Push для ваших уведомлений. Один ключ используется для всех ваших приложений. Для получения дополнительной информации см. Руководство по программированию локального и удаленного уведомлений.
Даже FCM поддерживает это. теперь вы можете избежать головной боли при создании сертификата APNS для каждого идентификатора приложения.
Ответ 3
Обновите свои сертификаты APN (производство и разработка) в YourProjectSetting = > cloudmessaging = > Конфигурация приложения iOS. Firebase Cloud Messaging может использовать либо аутентификационный ключ APNs, либо сертификат APN для подключения к APN
Примечание. подтвердите свои учетные данные Project (SenderID, Legacy server key, Server key).
Запрос HTTP POST: для отправки уведомлений.
https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u......7Udno5aA
{
"registration_ids": ["regId1","regId2"],
"data": {
"title": "App Name",
"message": "Hello this is for testing",
"body": "Hello this is for testing"
},
"content-available": true,
"priority": "high",
"notification": {
"title": "App Name",
"message": "Hello this is for testing",
"body": "Hello this is for testing"
}
}
Добавьте следующий код в свой AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.fcmInitialSetup(application)
return true
}
func fcmInitialSetup(_ application: UIApplication){
// [START register_for_notifications]
if #available(iOS 10.0, *) {
let uns: UIUserNotificationSettings = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(uns)
application.registerForRemoteNotifications()
} else {
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(settings)
}
application.registerForRemoteNotifications()
// [END register_for_notifications]
FIRApp.configure()
// Add observer for InstanceID token refresh callback.
NotificationCenter.default.addObserver(self, selector: #selector(self.tokenRefreshNotification), name: NSNotification.Name.firInstanceIDTokenRefresh, object: nil)
if let token = FIRInstanceID.instanceID().token() {
sendTokenToServer(token)
}
}
func sendTokenToServer(_ currentToken: String) {
print("sendTokenToServer() Token: \(currentToken)")
// Send token to server ONLY IF NECESSARY
print("InstanceID token: \(currentToken)")
self.token = currentToken
UserDefaults.standard.set(self.token, forKey: "token")
UserDefaults.standard.synchronize()
if self.token != nil{
let userInfo = ["token": self.token]
NotificationCenter.default.post(
name: Notification.Name(rawValue: self.rkey), object: nil, userInfo: userInfo)
}
}
// NOTE: Need to use this when swizzling is disabled
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let tokenChars = (deviceToken as NSData).bytes.bindMemory(to: CChar.self, capacity: deviceToken.count)
var tokenString = ""
for i in 0..<deviceToken.count {
tokenString += String(format: "%02.2hhx", arguments: [tokenChars[i]])
}
FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenType.unknown)
print("Device Token:", tokenString)
print("FIRInstanceID.instanceID().token() Token:", FIRInstanceID.instanceID().token())
if let tokenData = FIRInstanceID.instanceID().token(){
UserDefaults.standard.set(tokenData, forKey: "token")
UserDefaults.standard.synchronize()
let userInfo = ["token": tokenData]
}
}
func tokenRefreshNotification(_ notification: Notification) {
// NOTE: It can be nil here
// print("Token:\(FIRInstanceID.instanceID().token()!)")
if let refreshedToken = FIRInstanceID.instanceID().token() {
print("InstanceID token: \(refreshedToken)")
UserDefaults.standard.set(refreshedToken, forKey: "token")
UserDefaults.standard.synchronize()
print("update now \(self.token)")
if self.token != nil{
let userInfo = ["token": self.token]
NotificationCenter.default.post(
name: Notification.Name(rawValue: self.rkey), object: nil, userInfo: userInfo)
}
}
// Connect to FCM since connection may have failed when attempted before having a token.
connectToFcm()
}
// [END refresh_token]
func connectToFcm() {
FIRMessaging.messaging().connect { (error) in
if (error != nil) {
print("Unable to connect with FCM. \(error)")
} else {
print("Connected to FCM.")
}
}
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
print(userInfo)
}
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
print("Within open URL")
return true
}
// [START receive_apns_token_error]
func application( _ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError
error: Error ) {
print("Registration for remote notification failed with error: \(error.localizedDescription)")
// [END receive_apns_token_error]
let userInfo = ["error": error.localizedDescription]
NotificationCenter.default.post(
name: Notification.Name(rawValue: rkey), object: nil, userInfo: userInfo)
}
func registrationHandler(_ token: String!, error: NSError!) {
if (token != nil) {
self.token = token!
print("Registration Token: \(self.token)")
UserDefaults.standard.set(self.token, forKey: "token")
UserDefaults.standard.synchronize()
let userInfo = ["token": self.token]
NotificationCenter.default.post(
name: Notification.Name(rawValue: self.rkey), object: nil, userInfo: userInfo)
} else {
print("Registration to GCM failed with error: \(error.localizedDescription)")
let userInfo = ["error": error.localizedDescription]
NotificationCenter.default.post(
name: Notification.Name(rawValue: self.rkey), object: nil, userInfo: userInfo)
}
}
func registerForPushNotifications(_ application: UIApplication) {
let notificationSettings = UIUserNotificationSettings(
types: [.badge, .sound, .alert], categories: nil)
application.registerUserNotificationSettings(notificationSettings)
}
func application(_ application: UIApplication, didRegister notificationSettings: UIUserNotificationSettings) {
if notificationSettings.types != UIUserNotificationType() {
application.registerForRemoteNotifications()
}
}
// [START receive_message]
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
// Print message ID. add Toast
print(userInfo);
print(application.keyWindow?.visibleViewController() ?? "")
print("Message ID: \(userInfo["gcm.message_id"]!)")
// Print full message.
print("%@", userInfo)
}
// [END receive_message]
func applicationDidBecomeActive(_ application: UIApplication) {
connectToFcm()
}
// [START disconnect_from_fcm]
func applicationDidEnterBackground(_ application: UIApplication) {
// FIRMessaging.messaging().disconnect()
// print("Disconnected from FCM.")
}
func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
}
// [END disconnect_from_fcm]
// [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
// Print message ID.
print("Message ID: \(userInfo["gcm.message_id"]!)")
// Print message ID. add Toast
// Print full message.
print("%@", userInfo)
// Print full message.
print("%@", userInfo)
}
}
extension AppDelegate : FIRMessagingDelegate {
// Receive data message on iOS 10 devices.
func applicationReceivedRemoteMessage(_ remoteMessage: FIRMessagingRemoteMessage) {
print("%@", remoteMessage.appData)
}
}
// [END ios_10_message_handling]
Ссылка: https://firebase.google.com/docs/cloud-messaging/ios/device-group
Надеюсь, это поможет вам.