电话号码(续11)

手动测试

您可以直接在应用中开始使用虚构的电话号码。这样一来,您就可以在开发阶段执行手动测试,而不会遇到配额问题或受到限制。您也可以直接通过 iOS 模拟器或未安装 Google Play 服务的 Android 模拟器进行测试。

当您提供虚构电话号码并发送验证码时,系统实际上不会发送短信。作为替代,您需要提供事先配置的验证码来完成登录。

完成登录后,系统会使用该电话号码创建一位 Firebase 用户。该用户的行为和属性与真实电话号码用户相同,并且可通过同样的方式使用 Realtime Database/Cloud Firestore 和其他服务。在此过程中生成的 ID 令牌与真实电话号码用户的令牌具有相同的签名。

您还可以利用自定义声明为此类用户设置测试角色,以将其作为虚构用户区分开来(如果您想进一步限制其访问权限)。

集成测试

除了手动测试外,Firebase Authentication 还提供了 API,帮助您编写用于进行电话号码身份验证测试的集成测试。这些 API 通过停用 reCAPTCHA 要求(在 Web 应用中)和静默推送通知(在 iOS 应用中)来停用应用验证。因此,您可以在这些流程中进行自动测试,并且实现起来更加容易。此外,借助这些 API,您还可以在 Android 上测试即时验证流程。

对于 iOS 应用,您必须在调用 verifyPhoneNumber 之前将 appVerificationDisabledForTesting 设置设为 TRUE。这样做不需要任何 APNs 令牌,也不需要在后台发送静默推送通知,因此更便于您在模拟器中进行测试。此外,这也会停用 reCAPTCHA 后备流程。

请注意,停用应用验证后,使用非虚构电话号码将无法完成登录。此 API 只能使用虚构的电话号码。

Swift

let phoneNumber = "+16505554567"

// This test verification code is specified for the given test phone number in the developer console.
let testVerificationCode = "123456"

Auth.auth().settings.isAppVerificationDisabledForTesting = true
PhoneAuthProvider.provider().verifyPhoneNumber(phoneNumber, uiDelegate:nil) {
                                                            verificationID, error in
    if let error = error {
      // Handles error
      self.handleError(error)
      return
    }
    let credential = PhoneAuthProvider.provider().credential(withVerificationID: verificationID ?? "",
                                                               verificationCode: testVerificationCode)
    Auth.auth().signIn(with: credential) { authResult, error in
      if let error = error {
        // Handles error
        self.handleError(error)
        return
      }
      _user = authResult.user
    };
};

Objective-C

NSString *phoneNumber = @"+16505554567";

// This test verification code is specified for the given test phone number in the developer console.
NSString *testVerificationCode = @"123456";

[FIRAuth auth].settings.appVerificationDisabledForTesting = YES;
[[FIRPhoneAuthProvider provider] verifyPhoneNumber:phoneNumber
                                        completion:^(NSString *_Nullable verificationID,
                                                     NSError *_Nullable error) {
    if (error) {
      // Handles error
      [self handleError:error];
      return;
    }
    FIRAuthCredential *credential =
        [FIRPhoneAuthProvider credentialWithVerificationID:verificationID
                                          verificationCode:testVerificationCode];
    [FIRAuth auth] signInWithAndRetrieveDataWithCredential:credential
                                                completion:^(FIRUser *_Nullable user,
                                                             NSError *_Nullable error) {
      if (error) {
        // Handles error
        [self handleError:error];
        return;
      }
      _user = user;
    }];
}];

附录:使用电话号码登录而不调配

Firebase Authentication 使用方法调配自动获取应用的 APNs 令牌,处理 Firebase 发送给应用的静默推送通知,并自动拦截在验证期间来自 reCAPTCHA 验证页面的自定义方案重定向。

如果您不想使用调配,可以通过向应用的 Info.plist 文件添加标志 FirebaseAppDelegateProxyEnabled 并将其设置为 NO 来停用调配。请注意,将此标志设置为 NO 也会为其他 Firebase 产品(包括 Firebase Cloud Messaging)停用调配。

如果停用调配,您必须明确将 APNs 设备令牌、推送通知和自定义方案重定向网址传递给 Firebase Authentication。

如果您要构建 SwiftUI 应用,还应明确将 APNs 设备令牌、推送通知和自定义方案重定向网址传递给 Firebase Authentication。

要获取 APNs 设备令牌,请实现 application(_:didRegisterForRemoteNotificationsWithDeviceToken:) 方法,并在其中将设备令牌传递给 Auth 的 setAPNSToken(_:type:) 方法。

Swift

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

  // Further handling of the device token if needed by the app
  // ...
}

Objective-C

``` - (void)application:(UIApplication )application didRegisterForRemoteNotificationsWithDeviceToken:(NSData )deviceToken {