将多个身份验证提供方与一个账号相关联

您可以通过将多个身份验证提供方凭据关联至现有用户账号,让用户可以使用多个身份验证提供方登录您的应用。无论用户使用哪个身份验证提供方登录,系统均可通过同一 Firebase 用户 ID 识别用户。例如,使用密码登录的用户可以关联 Google 账号,以后便可使用这两种方法中的任意一种登录。或者,匿名用户可以关联 Facebook 账号,以后就可以使用 Facebook 账号登录并继续使用您的应用。

准备工作

为您的应用增加对两个或多个身份验证提供方(可能包括匿名身份验证)的支持。

如需将身份验证提供方凭据与现有用户账号关联,请按以下步骤操作:

  1. 使用任意身份验证提供方或方法让用户登录。

  2. 为新的身份验证提供方逐步完成登录流程,直到调用某一 signInWith- 方法之前为止。例如,获取用户的 Google ID 令牌、Facebook 访问令牌或电子邮件地址和密码。

  3. 为新的身份验证提供方获取 Credential 对象:

    // Google Sign-in
    final credential = GoogleAuthProvider.credential(idToken: idToken);
    
    // Email and password sign-in
    final credential =
        EmailAuthProvider.credential(email: emailAddress, password: password);
    
    // Etc.
    
  4. Credential 对象传递给登录用户的 linkWithCredential() 方法:

    try {
      final userCredential = await FirebaseAuth.instance.currentUser
          ?.linkWithCredential(credential);
    } on FirebaseAuthException catch (e) {
      switch (e.code) {
        case "provider-already-linked":
          print("The provider has already been linked to the user.");
          break;
        case "invalid-credential":
          print("The provider's credential is not valid.");
          break;
        case "credential-already-in-use":
          print("The account corresponding to the credential already exists, "
              "or is already linked to a Firebase User.");
          break;
        // See the API reference for the full list of error codes.
        default:
          print("Unknown error.");
      }
      ```
    

如果对 linkWithCredential() 的调用成功,用户现在便可使用关联的任意身份验证提供方进行登录,并使用相同的 Firebase 数据。

您可以取消身份验证提供方服务与账号的关联,这样用户就无法再通过该提供方服务登录了。

如需解除身份验证提供方与用户账号的关联,请将提供方 ID 传递给 unlink() 方法。您可以从 User 对象的 providerData 属性中获取与用户相关联的身份验证提供方的 ID。

try {
  await FirebaseAuth.instance.currentUser?.unlink(providerId);
} on FirebaseAuthException catch (e) {
  switch (e.code) {
    case "no-such-provider":
      print("The user isn't linked to the provider or the provider "
          "doesn't exist.");
      break;
    default:
      print("Unknown error.");
  }
}