'Firebase Cloud Messaging on iOS: 'application:didRegisterForRemoteNotificationsWithDeviceToken' must be present, but is never called
I'm adding Firebase Cloud Messaging in an iOS app (iOS 15.2.1 on a 7th Gen iPad), and I am able to get it to work, but have taken a step that the Firebase docs don't specify, and I don't understand why it's working and why it doesn't work when I don't do this.
First, I'm following these Firebase docs. These docs make no mention of needing to have an application:didRegisterForRemoteNotificationsWithDeviceToken method in the App Delegate. However, if I don't have this method present, I consistently get this error spewed to the console whenever I try to access the token with Messaging.messaging().token:
2022-01-31 22:00:57.448319-0800 authNavFirebaseUISample[4755:1363959] 8.10.0 - [Firebase/Messaging][I-FCM002022] APNS device token not set before retrieving FCM Token for Sender ID 'XXXXXXXXXXXX'. Notifications to this FCM Token will not be delivered over APNS.Be sure to re-retrieve the FCM token once the APNS device token is set.
When I do add in this method, I no longer get that error when accessing the token via Messaging.messaging().token. Furthermore, when this method is present, I can successfully send test notifications via the Notification Composer.
What's particularly strange about all of this is that the actual application:didRegisterForRemoteNotificationsWithDeviceToken is never actually invoked. However, its presence is required and without it, I get that error spew and Notification Composer doesn't work.
I've added relevant code snippets below. Any ideas? Thanks!
App Delegate
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
FirebaseApp.configure()
NotificationHelpers.setupRemoteNotifications(application)
return true
}
// NOTE: Why is this needed?!?!
// If this method isn't present, each time we try to retrieve the FCM (Firebase Cloud
// Messaging) token, we get:
// APNS device token not set before retrieving FCM Token for Sender ID 'XXXXXXXXXXXX'. Notifications to
// this FCM Token will not be delivered over APNS.Be sure to re-retrieve the FCM token once the APNS
// device token is set.
// Adding this method prevents that. However, the method never actually gets executed. (Try putting a
// print statement in there, it won't print.) But if you remove the method, then we get the above error.
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
}
func application(
_ application: UIApplication,
configurationForConnecting connectingSceneSession: UISceneSession,
options: UIScene.ConnectionOptions
) -> UISceneConfiguration {
let sceneConfig = UISceneConfiguration(name: nil, sessionRole: connectingSceneSession.role)
sceneConfig.delegateClass = MySceneDelegate.self
return sceneConfig
}
}
NotificationHelpers
class NotificationHelpers {
static func setupRemoteNotifications(_ application: UIApplication) -> Void {
let delegate = NotificationsDelegate()
// For iOS 10 and above display notification (sent via APNS)
UNUserNotificationCenter.current().delegate = delegate
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
options: authOptions,
completionHandler: { _, _ in }
)
application.registerForRemoteNotifications()
Messaging.messaging().delegate = delegate
}
}
Token accessing code (invoked from button press in app)
Button("retrieve FCM") {
// Get token here, but really can be from anywhere
Messaging.messaging().token { token, error in
if let error = error {
print("Error fetching FCM registration token: \(error)")
} else if let token = token {
print("FCM registration token: \(token)")
}
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
