Despite getting the APN key for Push Notifications, for some reason, my app does not receive notifications.
Push Notifications and Background modes are all enabled.
The bundle ID is the same in the app and in the GoogleService-Info.plist
file.
FCM gets generated, but, when I try to test, it does not work.
FirebaseAppDelegateProxyEnabled
is also set to NO
.
Am I doing something wrong? This is my code, please:
import SwiftUI
import SwiftData
import Firebase
import UserNotifications
import FirebaseCore
import FirebaseMessaging
@main
struct SomeApp: App {
//Firebase
@UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
//Network Monitor
@StateObject var networkMonitor = NetworkMonitor()
var body: some Scene {
WindowGroup {
ContentView()
.environment(\.font, Font.custom("Avenir Next", size: 14))
.environmentObject(networkMonitor)
}
}
}
//Firebase
class AppDelegate: NSObject, UIApplicationDelegate {
let gcmMessageIDKey = "gcm.message_id"
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
FirebaseApp.configure()
Messaging.messaging().delegate = self
UNUserNotificationCenter.current()
.requestAuthorization(
options: [.alert, .sound, .badge]) { granted, _ in
print("Permission granted: \(granted)")
guard granted else { return }
UNUserNotificationCenter.current().getNotificationSettings { settings in
print("Notification settings: \(settings)")
guard settings.authorizationStatus == .authorized else { return }
DispatchQueue.main.async {
application.registerForRemoteNotifications()
}
}
}
return true
}
func application(_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult)
-> Void) {
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
guard let aps = userInfo["aps"] as? [String: AnyObject] else {
completionHandler(.failed)
return
}
print("got something, aka the \(aps)")
// Print full message.
print(userInfo)
completionHandler(UIBackgroundFetchResult.newData)
}
func application(_ application: UIApplication,
didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("Unable to register for remote notifications: \(error.localizedDescription)")
}
func application(_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
print("device token")
let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) }
let token = tokenParts.joined()
print("Device Token: \(token)")
}
}
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 full message.
print(userInfo)
// Change this to your preferred presentation option
completionHandler([[.banner, .badge, .sound]])
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
print(userInfo)
completionHandler()
}
}
extension AppDelegate: MessagingDelegate {
// [START refresh_token]
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
print("Firebase registration token: \(String(describing: fcmToken))")
let dataDict: [String: String] = ["token": fcmToken ?? ""]
NotificationCenter.default.post(
name: Notification.Name("FCMToken"),
object: nil,
userInfo: dataDict
)
// TODO: If necessary send token to application server.
// Note: This callback is fired at each app startup and whenever a new token is generated.
}
// [END refresh_token]
}
Console Log:
Permission granted: true
Notification settings: <UNNotificationSettings: 0x3023d9290;
authorizationStatus: Authorized,
notificationCenterSetting: Enabled,
soundSetting: Enabled,
badgeSetting: Enabled,
lockScreenSetting: Enabled,
carPlaySetting: NotSupported,
announcementSetting: Disabled,
criticalAlertSetting: NotSupported,
timeSensitiveSetting: NotSupported,
alertSetting: Enabled,
scheduledDeliverySetting: Disabled,
directMessagesSetting: NotSupported,
showsPreviewsSetting: Always,
alertStyle: Banner,
groupingSetting: Default providesAppNotificationSettings: No>
device token
Device Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
By GOD’S Grace, this finally did it for me:
import SwiftUI
import SwiftData
import Firebase
import UserNotifications
import FirebaseCore
import FirebaseMessaging
@main
struct SomeApp: App {
//Firebase
@UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDelegate {
let gcmMessageIDKey = "gcm.message_id"
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
FirebaseApp.configure()
// Set UNUserNotificationCenter delegate
UNUserNotificationCenter.current().delegate = self
// Request notification authorization
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
print("Permission granted: \(granted)")
guard granted else { return }
UNUserNotificationCenter.current().getNotificationSettings { settings in
print("Notification settings: \(settings)")
guard settings.authorizationStatus == .authorized else { return }
DispatchQueue.main.async {
application.registerForRemoteNotifications()
}
}
}
Messaging.messaging().delegate = self
return true
}
func application(_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
print("Device Token: \(deviceToken.map { String(format: "%02.2hhx", $0) }.joined())")
// Pass device token to FCM
Messaging.messaging().apnsToken = deviceToken
}
func application(_ application: UIApplication,
didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("Failed to register for remote notifications: \(error.localizedDescription)")
}
func application(_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
print(userInfo)
completionHandler(UIBackgroundFetchResult.newData)
}
// MARK: - UNUserNotificationCenterDelegate
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
let userInfo = notification.request.content.userInfo
print(userInfo)
// Change this to your preferred presentation option
completionHandler([[.banner, .badge, .sound]])
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
print(userInfo)
completionHandler()
}
}
extension AppDelegate: MessagingDelegate {
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
print("Firebase registration token: \(String(describing: fcmToken))")
let dataDict: [String: String] = ["token": fcmToken ?? ""]
NotificationCenter.default.post(name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict)
// TODO: If necessary send token to application server.
}
}