firebase-ios-sdk icon indicating copy to clipboard operation
firebase-ios-sdk copied to clipboard

Auth.auth().canHandleNotification always returns false

Open lukavujnovac opened this issue 1 year ago • 15 comments

Description

Hi,

the issue is Auth.auth().canHandleNotification(...) always returning false and I cannot verify phone auth. I followed the docs and my App Delegate looks as follows:

class AppDelegate: NSObject, UIApplicationDelegate, MessagingDelegate, UNUserNotificationCenterDelegate  {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        FirebaseApp.configure()
        UNUserNotificationCenter.current().delegate = self
        NotificationService().requestAuthorization()
        application.registerForRemoteNotifications()
        Messaging.messaging().delegate = self
        
        return true
    }
    
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        Messaging.messaging().apnsToken = deviceToken
        Auth.auth().setAPNSToken(deviceToken, type: .prod)
    }
    
    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        let firebaseAuth = Auth.auth()
        Messaging.messaging().appDidReceiveMessage(userInfo)
        print(userInfo)
        if Auth.auth().canHandleNotification(userInfo) {
            completionHandler(.noData)
        }
        completionHandler(.noData)
    }
    
    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
        Messaging.messaging().token { token, error in
            if let error {
                log.error("failed to fetch FCM registration token \(error)")
            } else if let token {
                print("fcm \(token)")
                print(token)
            }
        }
    }
    
    
    func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        if Auth.auth().canHandle(url) {
            return true
        }
        return false
    }
}

push notifications are enables background refresh and remote notifications enabled sizzling is disabled.

Reproducing the issue

No specific steps needed

Firebase SDK Version

10.29.0

Xcode Version

15.3

Installation Method

Swift Package Manager

Firebase Product(s)

Authentication

Targeted Platforms

iOS

Relevant Log Output

the notification prints out:

[AnyHashable("com.google.firebase.auth"): {
    warning = "This fake notification should be forwarded to Firebase Auth.";
}]
Error Domain=FIRAuthErrorDomain Code=17054 "If app delegate swizzling is disabled, remote notifications received by UIApplicationDelegate need to be forwarded to FIRAuth's canHandleNotificaton: method." UserInfo={NSLocalizedDescription=If app delegate swizzling is disabled, remote notifications received by UIApplicationDelegate need to be forwarded to FIRAuth's canHandleNotificaton: method., FIRAuthErrorUserInfoNameKey=ERROR_NOTIFICATION_NOT_FORWARDED}

If using Swift Package Manager, the project's Package.resolved

Expand Package.resolved snippet

Replace this line with the contents of your Package.resolved.

If using CocoaPods, the project's Podfile.lock

Expand Podfile.lock snippet

Replace this line with the contents of your Podfile.lock!

lukavujnovac avatar Aug 15 '24 12:08 lukavujnovac

I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.

google-oss-bot avatar Aug 15 '24 12:08 google-oss-bot

Update: this code sometimes works for test phone numbers, but sometimes does not. Any help?

lukavujnovac avatar Aug 19 '24 16:08 lukavujnovac

Hi @lukavujnovac, do you have the Background Modes capability enabled? If so, ensure that the Background fetch and Remote notifications modes are selected.

ncooke3 avatar Aug 19 '24 17:08 ncooke3

Hi @lukavujnovac, do you have the Background Modes capability enabled? If so, ensure that the Background fetch and Remote notifications modes are selected.

Hey @ncooke3, yes I do, I have background fetch, remote notifications and background processing all selected under background modes

lukavujnovac avatar Aug 19 '24 17:08 lukavujnovac

Hi @lukavujnovac, I tried to reproduce the issue and I got the same behavior. I've raised this to our engineering team to investigate what's causing the issue. Thanks.

rizafran avatar Aug 29 '24 10:08 rizafran

Hi @lukavujnovac, I tried to reproduce the issue and I got the same behavior. I've raised this to our engineering team to investigate what's causing the issue. Thanks.

hey @rizafran this code works a few times if I set AuthAPNSTokenType to unknown. After a while I get the same error as above, is it possible it's to prevent spam? I have a paid firebase account which should allow up to 1000 SMSs a day.

lukavujnovac avatar Aug 29 '24 10:08 lukavujnovac

Hi @lukavujnovac, the APNS token type should be .unknown. This will allow the SDK to infer whether the APNS token is a production or a sandbox token based on the environment. I'm going to update our docs accordingly.

When making this change, are you seeing any cases where Auth.auth().canHandleNotification is not working correctly or is this part fixed by switching to .unknown?

Unrelated, but I noticed in your shared snippet that there was a path that calls the completion handler twice. I'm not sure if this could have any side effects in Apple's code, but it may be better to add a return after the first one.

if Auth.auth().canHandleNotification(userInfo) { completionHandler(.noData) } completionHandler(.noData)

ncooke3 avatar Aug 29 '24 21:08 ncooke3

Hi @lukavujnovac, the APNS token type should be .unknown. This will allow the SDK to infer whether the APNS token is a production or a sandbox token based on the environment. I'm going to update our docs accordingly.

When making this change, are you seeing any cases where Auth.auth().canHandleNotification is not working correctly or is this part fixed by switching to .unknown?

Unrelated, but I noticed in your shared snippet that there was a path that calls the completion handler twice. I'm not sure if this could have any side effects in Apple's code, but it may be better to add a return after the first one.

if Auth.auth().canHandleNotification(userInfo) {

        completionHandler(.noData)
    }
    completionHandler(.noData)

hi @ncooke3, that part is partly fixed by using the .unknown. As stated above, code works for a few times before receiving the same error. Could this be some spam protection? I do have a paid firebase account which should allow me up to 1000 SMSs a day. Thanks for the tip!

lukavujnovac avatar Aug 30 '24 06:08 lukavujnovac

Could this be some spam protection?

I don't think so. When the quota is reached, I wouldn't expect to see the Error Domain=FIRAuthErrorDomain Code=17054 "If app delegate swizzling is disabled... error, instead you'll see another error like error code 17052.

When you encounter the "If app delegate swizzling is disabled... error, does the reCAPTCHA flow get presented?

When the test notification is fired, it must be intercepted in a certain amount of time. If you are using the debugger and pausing at breakpoints, it's possible that it may the timeout may be reached. Do you happen to be using the debugger when the error occurs?

ncooke3 avatar Aug 30 '24 14:08 ncooke3

Could this be some spam protection?

I don't think so. When the quota is reached, I wouldn't expect to see the Error Domain=FIRAuthErrorDomain Code=17054 "If app delegate swizzling is disabled... error, instead you'll see another error like error code 17052.

When you encounter the "If app delegate swizzling is disabled... error, does the reCAPTCHA flow get presented?

When the test notification is fired, it must be intercepted in a certain amount of time. If you are using the debugger and pausing at breakpoints, it's possible that it may the timeout may be reached. Do you happen to be using the debugger when the error occurs?

@ncooke3 reCAPTCHA flow only gets triggered if I test on a simulator, and I am unable to proceed with phone auth on the simulator after that, I don't know if that's a separate issue or intended behavior. Every day this code works about 3-5 times, after that I get the error listed above. There are no other changes in the environment, everything is the same for working and non-working cases, but I could not find any differences. If needed, I can give you more info about the project and the firebase console setup.

lukavujnovac avatar Aug 30 '24 17:08 lukavujnovac

Thanks, @lukavujnovac. I was able to reproduce this behavior but I was not able to pinpoint what's going wrong. The first few logins were successful, then I got the "If app delegate swizzling is disabled... error, and when I stopped getting that, I got an error that my device had been blocked temporarily.

ncooke3 avatar Aug 30 '24 22:08 ncooke3

Thanks, @lukavujnovac. I was able to reproduce this behavior but I was not able to pinpoint what's going wrong. The first few logins were successful, then I got the "If app delegate swizzling is disabled... error, and when I stopped getting that, I got an error that my device had been blocked temporarily.

Are there any workarounds for this currently? This is currently a release blocker for me. If you need any additional info from me to help debug lmk.

lukavujnovac avatar Aug 30 '24 22:08 lukavujnovac

The only possible workaround may be to enable swizzling, but I understand that may be infeasible depending on your requirements. While setting the APNS type to .unknown is only a partial fix, this remaining problem is hopefully rare in practice since it seems to be only appear after multiple login attempts.

ncooke3 avatar Aug 31 '24 00:08 ncooke3

Any update on this issue ?

JeremyCorchia avatar Sep 19 '24 09:09 JeremyCorchia

Any update on this issue ?

@JeremyCorchia no, if you are facing the issue set the APNs environment to .unknown, or setup both development and production APNs in the Firebase console.

lukavujnovac avatar Sep 19 '24 09:09 lukavujnovac

Closing due to inactivity. If this remains an issue on the latest major version of Firebase, please let me know and I'm happy to reopen.

ncooke3 avatar Oct 03 '25 20:10 ncooke3