Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Client library is throwing the wrong error on .verifyPhoneNumber completion #10839

Open
tssm opened this issue Feb 17, 2023 · 13 comments
Open

Client library is throwing the wrong error on .verifyPhoneNumber completion #10839

tssm opened this issue Feb 17, 2023 · 13 comments

Comments

@tssm
Copy link

tssm commented Feb 17, 2023

Description

We successfully implemented password authentication through Firebase, and now we are adding SMS as a second factor. It correctly works on our web app, but on iOS we are getting the following error (code 17006) on the .verifyPhoneNumber callback:

NSLocalizedDescription=The given sign-in provider is disabled for this Firebase project. Enable it in the Firebase console, under the sign-in method tab of the Auth section.
FIRAuthErrorUserInfoNameKey=ERROR_OPERATION_NOT_ALLOWED

Whatever we are doing wrong, it is hard to debug because as I mentioned before, we successfully implemented it on the web app, so we already have both password authentication and SMS as second factor enabled in our Firebase project. What's more weird, this always happen when the app is released on TestFlight, but only sometimes when we run a build directly from Xcode on a real device.

Here is the minimum code that produces the error, I also tried the async API with the same result:

Auth.auth().signIn(withEmail: email, password: password) { auth, error in
    if let error = error as? NSError {
        if error.code == AuthErrorCode.secondFactorRequired.rawValue {
            let resolver = error.userInfo[AuthErrorUserInfoMultiFactorResolverKey] as! MultiFactorResolver
            if let hint = resolver.hints.first(where: { $0.factorID == PhoneMultiFactorID }) {
                PhoneAuthProvider
                    .provider()
                    .verifyPhoneNumber(
                        with: hint as! PhoneMultiFactorInfo,
                        uiDelegate: nil,
                        multiFactorSession: resolver.session
                    ) { verificationId, error in
                        if let error = error {
                            print(error) // <- this is being hitted
                        } else if let verificationId = verificationId {
                            print("verified!!!!!!!!") // <- this happens some times on sandbox, never on TestFlight
                        } else {
                            print("errror")
                        }
                    }
            }
        }
    }
}

We are using SwiftUI 2, targeting iOS 15, so swizzling is disabled. This is our bare minimum implementation of UIAplicationDelegate:

final class AppDelegate: NSObject, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        FirebaseApp.configure()

        return true
    }

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        Auth.auth().setAPNSToken(deviceToken, type: .unknown)
    }

    func application(_ application: UIApplication, didReceiveRemoteNotification notification: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        if Auth.auth().canHandleNotification(notification) {
            completionHandler(.noData)
            return
        }
    }

    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        let sceneConfig = UISceneConfiguration(name: nil, sessionRole: connectingSceneSession.role)
        sceneConfig.delegateClass = SceneDelegate.self
        return sceneConfig
    }
}

Our UIWindowSceneDelegate is also pretty slim:

final class SceneDelegate: NSObject, UIWindowSceneDelegate {
    func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
        for urlContext in URLContexts {
            Auth.auth().canHandle(urlContext.url)
        }
    }
}

We are using an APNs authentication key, and both the Push notifications and Remote notifications background mode were added as capabilities on Xcode. If we remove the latter, we still get the same error

Reproducing the issue

No response

Firebase SDK Version

10.5.0

Xcode Version

14.2

Installation Method

Swift Package Manager

Firebase Product(s)

Authentication

Targeted Platforms

iOS

Relevant Log Output

No response

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

We actually used the built-in Xcode package manager, so we don't have a Package.resolved file

If using CocoaPods, the project's Podfile.lock

Expand Podfile.lock snippet
Replace this line with the contents of your Podfile.lock!
@google-oss-bot
Copy link

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

@rizafran
Copy link
Contributor

Thanks for reaching out, @tssm. Based on the error message you shared, this typically occurs when the Auth provider you'll be using is disabled in the console. With this, could you double-check first if the phone auth provider is already enabled in your console?

@tssm
Copy link
Author

tssm commented Feb 20, 2023

Thanks for the answer @rizafran. Both email authentication and multifactor are enabled in the Firebase console. Please note that, as I mentioned before, the issue only happens on iOS, our customers are able to log in and receive an SMS as second factor when they log in on the web app.

Today I managed to make it work, somehow. Here are the details:

  1. Swizzling is still disabled by using the GoogleUtilitiesAppDelegateProxyEnabled property on Info.plist
  2. We removed the Push notifications capability of our Xcode project, but kept the implementations of application(_:didReceiveRemoteNotification:fetchCompletionHandler:): in UIApplicationDelegate and scene(_:openURLContexts:) in UIWindowSceneDelegate, otherwise the app crashes during the SMS verification step. Please notice that I deleted application(_:didRegisterForRemoteNotificationsWithDeviceToken:) from the UIApplicationDelegate implementation, but SMS verification still works!
  3. We added a newly generated APNs authentication key to the Firebase console
  4. The legacy Cloud Messaging API is enabled on the console, V1 is disabled. No idea if this makes any difference

Based on this behaviour, I guess the issue is related to the push notifications setup on a pure SwiftUI app, making only the reCAPTCHA method reliable. We would like to avoid showing the reCAPTCHA as much as possible, though.

As an extra, it's weird that we still need to add push notifications logic to the UIApplicationDelegate event when they aren't working at all.

Hopefully this helps to clarify the issue

@rizafran
Copy link
Contributor

Thanks for the info, @tssm. The behavior you're encountering might be unrelated to the error as it's about the disabled Auth provider in the console. I'm curious if you're getting any other errors aside from the error you shared above? Also, could you confirm if you've disabled the FirebaseAppDelegateProxyEnabled in your Info.plist file as stated here? I'm not sure if this also applies, but it is noted on the docs as well that SwiftUI apps should use the UIApplicationDelegateAdaptor or NSApplicationDelegateAdaptor property wrappers to provide a type corresponding to the appropriate app delegate protocol.

@tssm
Copy link
Author

tssm commented Feb 24, 2023

We don't see any other errors. I can confirm swizzling is disabled, although we are using GoogleUtilitiesAppDelegateProxyEnabled in our Info.plist instead of FirebaseAppDelegateProxyEnabled. I tried with the latter, but the result is the same:

[GoogleUtilities/AppDelegateSwizzler][I-SWZ001011] App Delegate Proxy is disabled.

So I'm not sure if there's any difference between both keys. And yes, I can confirm we are using an UIApplicationDelegate, and that we set it with UIApplicationDelegateAdaptor

@rizafran
Copy link
Contributor

Sorry for the late revert. Our engineers have been notified about this issue. This is internally tracked in b/279781096.

@tssm
Copy link
Author

tssm commented Apr 27, 2023

Cool guys, thank you!

@dominique-um
Copy link

I'm having a similar issue. We have Email enabled as a Sign-in Provider, all other providers disabled, and SMS Multi-factor Authentication enabled. Signing in works fine on Android, but on iOS we receive the 17006 error above. If we enable Phone as a Sign-in Provider, we can successfully verifyPhoneNumber and receive the SMS.

@otymartin
Copy link

Im having the same problem on Firebase version 10.12.0 iOS pure SwiftUI. @tssm Did you resolve this? @rizafran ?

@tssm
Copy link
Author

tssm commented Jul 26, 2023

@otymartin kind of, I described the workaround here. I guess you can ignore steps 3 and 4, but keep in mind the result of this is the user will always see the CAPTCHA, quite annoying, but at least they can log in

@jordanebelanger
Copy link

This issue persists: the only way to make SMS two-factor authentication work on iOS, when following the Firebase documentation, is to enable ‘Phone’ as a sign-in provider. This requirement applies only if using APNs instead of reCAPTCHA. If using reCAPTCHA, the normal flow works fine, and you can use SMS two-factor authentication without having ‘Phone’ as a sign-in provider in the Firebase Console.

@paulb777
Copy link
Member

paulb777 commented Aug 9, 2024

Any difference in behavior with Firebase 11.0.0?

@jordanebelanger
Copy link

jordanebelanger commented Aug 12, 2024

Any difference in behavior with Firebase 11.0.0?

I cannot say as I can no longer login at all on v11 (v10 works but with the previously mentioned problem).

I am almost 99% sure we are hitting this specific new issue #13479

edit: I did one test and disabled the phone auth provider (keeping SMS mfa activated), this leads to the following error: "The given sign-in provider is disabled for this Firebase project. Enable it in the Firebase console, under the sign-in method tab of the Auth section"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants