Search code examples
firebasegoogle-cloud-functionsfirebase-cloud-messagingcapacitorandroid-push-notification

Error: The registration token is not a valid FCM registration token


I have an Android App (Angular + Ionic) that uses Firebase to sent notifications. The app has been working for a while with no problems. I recently made some changes to the DB service of the app - nothing to do with the Firebase notifications at all. Now, some notifications are not being sent. Sometimes they are not even registered in the Realtime DB (used to trigger the Cloud Function that sends out the notification) and sometime it is registered in the DB, triggers the function, and the function throws an error:

Error: The registration token is not a valid FCM registration token

The notification is pushed seconds after registration. When I compare the token received in Registration with the token presented by the Function in the log - it is identical. I have no idea what is causing this behavior, any direction please?

Registration code:

PushNotifications.addListener("registration", (token: Token) => {      
      if (token && !this.tokenProcessed) {
        this.tokenProcessed = true;
        console.log('My token: ' + JSON.stringify(token));
        this.onFCMTokenChanged.next(token.value);
      }
    });

Console log output:

My token: {"value":"D8636BCC62A673B4D574736AFCA1F73AF7C34EBBB7D99A38E05CDB6963FEAE8B"}

GCS Log output: enter image description here


Solution

  • This happened due to unfinished Firebase configurations in the project side for iOS: In file: ios/App/Podfile Add the Firebase/Messaging pod:

    target 'App' do
    capacitor_pods
    # Add your Pods here
    pod 'Firebase/Messaging'
    end
    

    From the ios/App folder, run: pod install

    ios/App/App/AppDelegate.swift file:

    import UIKit
    import Capacitor
    import Firebase 
    
    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {
    
        var window: UIWindow?
    
        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
            // Override point for customization after application launch.
            FirebaseApp.configure() // Amir added
            return true
        }
    
        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.
        }
    
        func applicationWillTerminate(_ application: UIApplication) {
            // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
        }
    
        func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
            // Called when the app was launched with a url. Feel free to add additional processing here,
            // but if you want the App API to support tracking app url opens, make sure to keep this call
            return ApplicationDelegateProxy.shared.application(app, open: url, options: options)
        }
    
        func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
            // Called when the app was launched with an activity, including Universal Links.
            // Feel free to add additional processing here, but if you want the App API to support
            // tracking app url opens, make sure to keep this call
            return ApplicationDelegateProxy.shared.application(application, continue: userActivity, restorationHandler: restorationHandler)
        }
    
    /*
    
        func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
            NotificationCenter.default.post(name: .capacitorDidRegisterForRemoteNotifications, object: deviceToken)
            
         }
        
    
        func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
            NotificationCenter.default.post(name: .capacitorDidFailToRegisterForRemoteNotifications, object: error)
        }
    */
    
        func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        Messaging.messaging().apnsToken = deviceToken
        Messaging.messaging().token(completion: { (token, error) in
            if let error = error {
                NotificationCenter.default.post(name: .capacitorDidFailToRegisterForRemoteNotifications, object: error)
            } else if let token = token {
                NotificationCenter.default.post(name: .capacitorDidRegisterForRemoteNotifications, object: token)
            }
        })
        }
    
        func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
            NotificationCenter.default.post(name: .capacitorDidFailToRegisterForRemoteNotifications, object: error)
        }
    
    }
    

    For some reason, my GoogleService-Info.plist file was available in the ios/App/App folder in Finder, but not showing in the project navigator in xcode. I had to right-click on the App folder and select "Add file to project..."

    In xcode - clean build folder (Product -> Clean build folder). Re-build the project into your device.