简体   繁体   English

使用电话号码的 Firebase 身份验证返回内部错误

[英]Firebase Auth using phone number returns an internal error

I set up my app to be able to send Apple Notifications using firebase and I verified that it works using the console.我将我的应用程序设置为能够使用 firebase 发送 Apple 通知,并且我验证了它可以使用控制台工作。 Now I want to do phone authentication which is built on top of APN.现在我想做建立在 APN 之上的电话认证。

So I wrote this:所以我写了这个:

PhoneAuthProvider.provider().verifyPhoneNumber(phoneNumber) { verificationID, error in
  if error != nil {
    print("Verification code not sent \(error!)")
  } else {
    print ("Successful.")
  }

And I get:我得到:

Error Domain=FIRAuthErrorDomain Code=17999 "An internal error has occurred, print and inspect the error details for more information." UserInfo={NSUnderlyingError=0x170046db0 {Error Domain=FIRAuthInternalErrorDomain Code=3 "(null)" UserInfo={FIRAuthErrorUserInfoDeserializedResponseKey={
    code = 500;
    message = "<null>";
}}}, error_name=ERROR_INTERNAL_ERROR, NSLocalizedDescription=An internal error has occurred, print and inspect the error details for more information.}

Any idea?任何的想法? Should I file a bug against firebase?我应该针对 firebase 提交错误吗?

I am using iOS SDK 4.0.0 (latest zip I could find.)我正在使用 iOS SDK 4.0.0(我能找到的最新 zip。)

UPDATE:更新:

I disabled method swizzling by adding FirebaseAppDelegateProxyEnabled to info.plist and set it to NO我通过将FirebaseAppDelegateProxyEnabled添加到info.plist并将其设置为NO来禁用方法调配

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    // Pass device token to auth.
    Auth.auth().setAPNSToken(deviceToken, type: .prod)
}

Tested with latest Firebase iOS SDK ie 4.0.0 and Xcode 8.3使用最新的Firebase iOS SDK 进行测试,即 4.0.0Xcode 8.3

Firstly , remove this key FirebaseAppDelegateProxyEnabled from info.plist.首先,从 info.plist 中删除这个键FirebaseAppDelegateProxyEnabled This is not needed.这是不需要的。

Now in AppDelegate.swift add following functions现在在AppDelegate.swift添加以下功能

import Firebase
import UserNotifications

@UIApplicationMain

class AppDelegate: UIResponder, UIApplicationDelegate , UNUserNotificationCenterDelegate{
    var window: UIWindow?
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

        if #available(iOS 10.0, *) {
            // For iOS 10 display notification (sent via APNS)
            UNUserNotificationCenter.current().delegate = self
            let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
            UNUserNotificationCenter.current().requestAuthorization(
                options: authOptions,
                completionHandler: {_, _ in })
        } else {
            let settings: UIUserNotificationSettings =
                UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
            application.registerUserNotificationSettings(settings)
        }

        application.registerForRemoteNotifications()
        FirebaseApp.configure()
        return true
    }
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    // Pass device token to auth.
    let firebaseAuth = Auth.auth()

    //At development time we use .sandbox
    firebaseAuth.setAPNSToken(deviceToken, type: AuthAPNSTokenType.sandbox)

    //At time of production it will be set to .prod
}

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    let firebaseAuth = Auth.auth()

    if (firebaseAuth.canHandleNotification(userInfo)){
        print(userInfo)
        return
    }
}*

Send a verification code to the user's phone:向用户手机发送验证码:

In the class where you want to integrate Phone Authentication write :在要集成电话身份验证的类中写入:

Note : I have added +91 as its country code for India.注意:我添加了+91作为印度的国家代码。 You can add country code according to your region.您可以根据您所在的地区添加国家代码。

 PhoneAuthProvider.provider().verifyPhoneNumber("+919876543210") { (verificationID, error) in
       if ((error) != nil) {
             // Verification code not sent.
             print(error)
       } else {
              // Successful. User gets verification code 
              // Save verificationID in UserDefaults
             UserDefaults.standard.set(verificationID, forKey: "firebase_verification")
             UserDefaults.standard.synchronize()
             //And show the Screen to enter the Code.
       }               

Sign in the user with the verification code :使用验证码登录用户

 let verificationID = UserDefaults.standard.value(forKey: "firebase_verification")
 let credential = PhoneAuthProvider.provider().credential(withVerificationID: verificationID! as! String, verificationCode: self.txtEmailID.text!)

   Auth.auth().signIn(with: credential, completion: {(_ user: User, _ error: Error?) -> Void in
         if error != nil {
            // Error
          }else {
             print("Phone number: \(user.phoneNumber)")
              var userInfo: Any? = user.providerData[0]
                    print(userInfo)
                }
         } as! AuthResultCallback)

In my case it was the apns token type that was wrong:就我而言,这是错误的 apns 令牌类型:

Auth.auth().setAPNSToken(deviceToken, type: AuthAPNSTokenType.prod)

should have been:本来应该:

Auth.auth().setAPNSToken(deviceToken, type: AuthAPNSTokenType.sandbox)

Double check that the app bundle ID in Xcode matches the bundle ID in Firebase exactly .仔细检查 Xcode 中的 app bundle ID 是否与 Firebase 中的 bundle ID完全匹配。 And by exactly , make sure their case matches - Xcode likes to use mixed case by default for the app name part of the bundle ID.确切地说,确保它们的大小写匹配 - 默认情况下,Xcode 喜欢对包 ID 的应用程序名称部分使用大小写混合。

If you end up changing the bundle ID in Xcode, make sure to manually delete the provisioning profile for the app before generating a new one in Xcode, or it will repeatedly fail (Apple apparently ignores case on profile names).如果您最终在 Xcode 中更改了 bundle ID,请确保在 Xcode 中生成新的配置文件之前手动删除应用程序的配置文件,否则它将反复失败(Apple 显然忽略了配置文件名称的大小写)。

Well, in my case I have sending wrong self.verificationID to FIRAuthCredential .好吧,就我而言,我向self.verificationID发送了错误的FIRAuthCredential If you are having this error, then please print your verificationID and check, is that the same one you are sending to FIRAuthCredential .如果您遇到此错误,请打印您的verificationID FIRAuthCredential并检查是否与您发送到FIRAuthCredential的相同。

Here is my code in objC :这是我在objC代码:

[[FIRPhoneAuthProvider provider] verifyPhoneNumber:self.phoneNumberTextField.text
                                            UIDelegate:nil
                                            completion:^(NSString * _Nullable verificationID, NSError * _Nullable error) {
                                                if (error) {
                                                    NSLog(@"error %@", error.localizedDescription);
                                                    return;
                                                }
                                                NSLog(@"verificationID %@", verificationID);
                                                self.verificationID = [NSString stringWithFormat:@"%@", verificationID];

//                                                NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
//                                                [defaults setObject:verificationID forKey:@"authVerificationID"];
//                                                NSString *verificationID = [defaults stringForKey:@"authVerificationID"];

                                                // Sign in using the verificationID and the code sent to the user
                                                // ...
                                            }];

I accidentally send wrong verificationID here :我不小心在这里发送了错误的验证 ID:

self.verificationID = [NSString stringWithFormat:@"verificationID",];

Right one is this :正确的是:

self.verificationID = [NSString stringWithFormat:@"%@", verificationID];

And then I send it to FIRAuthCredential like this :然后我像这样将它发送到FIRAuthCredential

FIRAuthCredential *credential = [[FIRPhoneAuthProvider provider]
                                     credentialWithVerificationID:self.verificationID
                                     verificationCode:self.pinCodeTextField.text];

    [[FIRAuth auth] signInWithCredential:credential
                              completion:^(FIRUser *user, NSError *error) {
                                  if (error) {
                                      NSLog(@"error %@", error);
                                      return;
                                  }
                                  NSLog(@"Success");
                                  // User successfully signed in. Get user data from the FIRUser object
                                  // ...
                              }];

Which return success successfully.这回success成功。 Hope it will help to others.希望它能对其他人有所帮助。

i am solve it easy make type .sandbox我正在解决它很容易制作类型 .sandbox

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    // Pass device token to auth.
    let firebaseAuth = Auth.auth()
    //At development time we use .sandbox
    firebaseAuth.setAPNSToken(deviceToken, type: AuthAPNSTokenType.sandbox)
}

and remove this line from code并从代码中删除这一行

Auth.auth().settings.isAppVerificationDisabledForTesting = TRUE

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM