Vincenzo
Vincenzo

Reputation: 6358

Push notifications are not delivered anymore after relaunching app from Xcode Swift

I'm finally able to send push notifications via Firebase between my two apps. The problem is that on App1 only works when fresh installed on device. If I stop and run again the project push notifications are not delivered anymore even if fcmTokenhasn't changed, and in App2 I get error :

POST: 
    {"multicast_id":6763498783850594663,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"NotRegistered"}]}

meaning Firebase didn't find a valid fcmTokento send the push to. While on App1 first install console print :

didReceiveRegistrationToken: Firebase registration token: eI8nx-zroBU:APA91bG9gZeukgfsxobw4C3mg0Jhro06ALUQqtJwjfYxIwv4hIvjFwNWpSc_0JHPtl2FAGb-Jqwk7GL5pgki_Q_awOngA8yP66IG9fpWKQjEuS330N_c3yMAQvDUBCVo7wbFET_oEqLu

is correct to have as I set it up in didReceiveRegistrationToken delegate method, on second launch didReceiveRegistrationToken gives the same token as before. As I understood if a new fcmToken is delivered is didRefreshRegistrationTokenthat gets called, but I have no prints from that delegate method, so seems that earlier fcmToken is still valid. Can you see where I set it up wrong?

didFinishLaunchingWithOptions:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        window?.tintColor = UIColor.blue
        // Use Firebase library to configure APIs
        FirebaseApp.configure()
        Messaging.messaging().delegate = self
        Crashlytics().debugMode = true
        Fabric.with([Crashlytics.self])
        // setting up notification delegate
        if #available(iOS 10.0, *) {
            //iOS 10.0 and greater
            UNUserNotificationCenter.current().delegate = self
            let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
            //Solicit permission from the user to receive notifications
            UNUserNotificationCenter.current().requestAuthorization(options: authOptions, completionHandler: { granted, error in
                DispatchQueue.main.async {
                    if granted {
                        print("didFinishLaunchingWithOptions iOS 10: Successfully registered for APNs")
                        UIApplication.shared.registerForRemoteNotifications() // declaring it work perfetcly
                        UIApplication.shared.applicationIconBadgeNumber = 0
                    } else {
                        //Do stuff if unsuccessful...
                        print("didFinishLaunchingWithOptions iOO 10: Error in registering for APNs: \(String(describing: error))")
                    }
                }
            })
        } else {
            //iOS 9
            let type: UIUserNotificationType = [UIUserNotificationType.badge, UIUserNotificationType.alert, UIUserNotificationType.sound]
            let setting = UIUserNotificationSettings(types: type, categories: nil)
            UIApplication.shared.registerUserNotificationSettings(setting)
            UIApplication.shared.registerForRemoteNotifications() // declaring it work perfetcly
            UIApplication.shared.applicationIconBadgeNumber = 0
            print("didFinishLaunchingWithOptions iOS 9: Successfully registered for APNs")
        }
        //get application instance ID
//        InstanceID.instanceID().instanceID { (result, error) in
//            if let error = error {
//                print("didFinishLaunchingWithOptions: Error fetching remote instance ID: \(error)")
//            } else if let result = result {
//                print("didFinishLaunchingWithOptions: Remote instance ID token: \(result.token)")
//            }
//        }
        // setting up remote control values
        let _ = RCValues.sharedInstance
        GIDSignIn.sharedInstance().clientID = FirebaseApp.app()?.options.clientID
        Crashlytics().debugMode = true
        Fabric.with([Crashlytics.self])
        //        // TODO: Move this to where you establish a user session
        //        self.logUser()
        var error: NSError?
        do {
            try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
        } catch let error1 as NSError{
            error = error1
            print("could not set session. err:\(error!.localizedDescription)")
        }
        do {
            try AVAudioSession.sharedInstance().setActive(true)
        } catch let error1 as NSError{
            error = error1
            print("could not active session. err:\(error!.localizedDescription)")
        }
        // goggle only
        GIDSignIn.sharedInstance().clientID = FirebaseApp.app()?.options.clientID
//        GIDSignIn.sharedInstance().delegate = self
        // Facebook SDK
        return FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
//        return true
    }

didRegisterForRemoteNotificationsWithDeviceToken:

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        let tokenParts = deviceToken.map { data -> String in
            return String(format: "%02.2hhx", data)
        }
        let token = tokenParts.joined()
        print(" didRegisterForRemoteNotificationsWithDeviceToken : devcice token is: \(token)")
        Messaging.messaging().apnsToken = deviceToken
    }

didReceiveRegistrationToken:

func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
        print("didReceiveRegistrationToken: Firebase registration token: \(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.
        AppDelegate.fcmToken = fcmToken

        if userDetails.fullName != nil {
            userDetails.fcmToken = fcmToken
            Firebase.updateToken(completed: { (true) in
                print("AppDelegate.didFinishLaunchingWithOptions: token updloaded to Firebase, will now save it to CoreData")
            }, token: fcmToken)
        }
        // Note: This callback is fired at each app startup and whenever a new token is generated.
    }

didRefreshRegistrationToken:

func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String) {
        let dataDict:[String: String] = ["token": fcmToken]
        NotificationCenter.default.post(name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict)
//        print("Refreshed Token: \(fcmToken)")
        AppDelegate.fcmToken = fcmToken
        if userDetails.fullName != nil {
            userDetails.fcmToken = fcmToken
            Firebase.updateToken(completed: { (true) in
                print("AppDelegate.didRefreshRegistrationToken: token updloaded to Firebase, will now save it to CoreData")
            }, token: fcmToken)
        }
    }

Upvotes: 1

Views: 598

Answers (1)

Vincenzo
Vincenzo

Reputation: 6358

Problem seem to be solved. After updating the pods, it now works as expected. I had to delete App1 from device and reinstalling it as fast my first attempt to just run the project again the problem was still there. After cleaning the build, deleting the app from device and reinstalling it it now keeps receiving push notifications after I relaunch the project. Hope this will help others, as I struggled a lot to implement device to device push notifications, and haven't found many helpful info about it.

Upvotes: 1

Related Questions