Verknüpfen Sie mehrere Authentifizierungsanbieter mit einem Konto auf Apple-Plattformen

Sie können Benutzern erlauben, sich mit mehreren Authentifizierungsanbietern bei Ihrer App anzumelden, indem Sie die Anmeldeinformationen des Authentifizierungsanbieters mit einem vorhandenen Benutzerkonto verknüpfen. Benutzer sind durch dieselbe Firebase-Benutzer-ID identifizierbar, unabhängig davon, welchen Authentifizierungsanbieter sie für die Anmeldung verwendet haben. Beispielsweise kann ein Benutzer, der sich mit einem Passwort angemeldet hat, ein Google-Konto verknüpfen und sich in Zukunft mit einer der beiden Methoden anmelden. Oder ein anonymer Benutzer kann ein Facebook-Konto verknüpfen und sich später bei Facebook anmelden, um Ihre App weiter zu verwenden.

Bevor Sie beginnen

Fügen Sie Ihrer App Unterstützung für zwei oder mehr Authentifizierungsanbieter (möglicherweise einschließlich anonymer Authentifizierung) hinzu.

So verknüpfen Sie die Anmeldeinformationen des Authentifizierungsanbieters mit einem vorhandenen Benutzerkonto:

  1. Melden Sie den Benutzer mit einem beliebigen Authentifizierungsanbieter oder einer beliebigen Methode an.
  2. Schließen Sie den Anmeldeablauf für den neuen Authentifizierungsanbieter bis zum Aufrufen einer der FIRAuth.signInWith -Methoden ab, schließen diese jedoch nicht ein. Rufen Sie beispielsweise das Google-ID-Token, das Facebook-Zugriffstoken oder die E-Mail-Adresse und das Passwort des Benutzers ab.
  3. Holen Sie sich ein FIRAuthCredential für den neuen Authentifizierungsanbieter:

    Google-Anmeldung
    Schnell
    guard
      let authentication = user?.authentication,
      let idToken = authentication.idToken
    else {
      return
    }
    
    let credential = GoogleAuthProvider.credential(withIDToken: idToken,
                                                   accessToken: authentication.accessToken)
    
    Ziel c
    FIRAuthCredential *credential =
    [FIRGoogleAuthProvider credentialWithIDToken:result.user.idToken.tokenString
                                     accessToken:result.user.accessToken.tokenString];
    
    Facebook Login
    Schnell
    let credential = FacebookAuthProvider
      .credential(withAccessToken: AccessToken.current!.tokenString)
    
    Ziel c
    FIRAuthCredential *credential = [FIRFacebookAuthProvider
        credentialWithAccessToken:[FBSDKAccessToken currentAccessToken].tokenString];
    
    E-Mail-Passwort-Anmeldung
    Schnell
    let credential = EmailAuthProvider.credential(withEmail: email, password: password)
    
    Ziel c
    FIRAuthCredential *credential =
        [FIREmailAuthProvider credentialWithEmail:email
                                                 password:password];
    
  4. Übergeben Sie das FIRAuthCredential Objekt an die Methode linkWithCredential:completion: des angemeldeten Benutzers:

    Schnell
        user.link(with: credential) { authResult, error in
      // ...
    }
    }
    
    Ziel c
        [[FIRAuth auth].currentUser linkWithCredential:credential
        completion:^(FIRAuthDataResult *result, NSError *_Nullable error) {
      // ...
    }];
    

    Der Aufruf von linkWithCredential:completion: schlägt fehl, wenn die Anmeldeinformationen bereits mit einem anderen Benutzerkonto verknüpft sind. In dieser Situation müssen Sie das Zusammenführen der Konten und zugehörigen Daten entsprechend Ihrer App handhaben:

    Schnell

    let prevUser = Auth.auth().currentUser
    Auth.auth().signIn(with: credential) { authResult, error in
        if let error = error {
          let authError = error as NSError
          if isMFAEnabled, authError.code == AuthErrorCode.secondFactorRequired.rawValue {
            // The user is a multi-factor user. Second factor challenge is required.
            let resolver = authError
              .userInfo[AuthErrorUserInfoMultiFactorResolverKey] as! MultiFactorResolver
            var displayNameString = ""
            for tmpFactorInfo in resolver.hints {
              displayNameString += tmpFactorInfo.displayName ?? ""
              displayNameString += " "
            }
            self.showTextInputPrompt(
              withMessage: "Select factor to sign in\n\(displayNameString)",
              completionBlock: { userPressedOK, displayName in
                var selectedHint: PhoneMultiFactorInfo?
                for tmpFactorInfo in resolver.hints {
                  if displayName == tmpFactorInfo.displayName {
                    selectedHint = tmpFactorInfo as? PhoneMultiFactorInfo
                  }
                }
                PhoneAuthProvider.provider()
                  .verifyPhoneNumber(with: selectedHint!, uiDelegate: nil,
                                     multiFactorSession: resolver
                                       .session) { verificationID, error in
                    if error != nil {
                      print(
                        "Multi factor start sign in failed. Error: \(error.debugDescription)"
                      )
                    } else {
                      self.showTextInputPrompt(
                        withMessage: "Verification code for \(selectedHint?.displayName ?? "")",
                        completionBlock: { userPressedOK, verificationCode in
                          let credential: PhoneAuthCredential? = PhoneAuthProvider.provider()
                            .credential(withVerificationID: verificationID!,
                                        verificationCode: verificationCode!)
                          let assertion: MultiFactorAssertion? = PhoneMultiFactorGenerator
                            .assertion(with: credential!)
                          resolver.resolveSignIn(with: assertion!) { authResult, error in
                            if error != nil {
                              print(
                                "Multi factor finanlize sign in failed. Error: \(error.debugDescription)"
                              )
                            } else {
                              self.navigationController?.popViewController(animated: true)
                            }
                          }
                        }
                      )
                    }
                  }
              }
            )
          } else {
            self.showMessagePrompt(error.localizedDescription)
            return
          }
          // ...
          return
        }
        // User is signed in
        // ...
    }
                // Merge prevUser and currentUser accounts and data
                // ...
            }
    

    Ziel c

    FIRUser *prevUser = [FIRAuth auth].currentUser;
    [[FIRAuth auth] signInWithCredential:credential
                              completion:^(FIRAuthDataResult * _Nullable authResult,
                                           NSError * _Nullable error) {
        if (isMFAEnabled && error && error.code == FIRAuthErrorCodeSecondFactorRequired) {
          FIRMultiFactorResolver *resolver = error.userInfo[FIRAuthErrorUserInfoMultiFactorResolverKey];
          NSMutableString *displayNameString = [NSMutableString string];
          for (FIRMultiFactorInfo *tmpFactorInfo in resolver.hints) {
            [displayNameString appendString:tmpFactorInfo.displayName];
            [displayNameString appendString:@" "];
          }
          [self showTextInputPromptWithMessage:[NSString stringWithFormat:@"Select factor to sign in\n%@", displayNameString]
                               completionBlock:^(BOOL userPressedOK, NSString *_Nullable displayName) {
           FIRPhoneMultiFactorInfo* selectedHint;
           for (FIRMultiFactorInfo *tmpFactorInfo in resolver.hints) {
             if ([displayName isEqualToString:tmpFactorInfo.displayName]) {
               selectedHint = (FIRPhoneMultiFactorInfo *)tmpFactorInfo;
             }
           }
           [FIRPhoneAuthProvider.provider
            verifyPhoneNumberWithMultiFactorInfo:selectedHint
            UIDelegate:nil
            multiFactorSession:resolver.session
            completion:^(NSString * _Nullable verificationID, NSError * _Nullable error) {
              if (error) {
                [self showMessagePrompt:error.localizedDescription];
              } else {
                [self showTextInputPromptWithMessage:[NSString stringWithFormat:@"Verification code for %@", selectedHint.displayName]
                                     completionBlock:^(BOOL userPressedOK, NSString *_Nullable verificationCode) {
                 FIRPhoneAuthCredential *credential =
                     [[FIRPhoneAuthProvider provider] credentialWithVerificationID:verificationID
                                                                  verificationCode:verificationCode];
                 FIRMultiFactorAssertion *assertion = [FIRPhoneMultiFactorGenerator assertionWithCredential:credential];
                 [resolver resolveSignInWithAssertion:assertion completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
                   if (error) {
                     [self showMessagePrompt:error.localizedDescription];
                   } else {
                     NSLog(@"Multi factor finanlize sign in succeeded.");
                   }
                 }];
               }];
              }
            }];
         }];
        }
      else if (error) {
        // ...
        return;
      }
      // User successfully signed in. Get user data from the FIRUser object
      if (authResult == nil) { return; }
      FIRUser *user = authResult.user;
      // ...
    }];
                                        // Merge prevUser and currentUser accounts and data
                                        // ...
                                    }];
    

Wenn der Aufruf von linkWithCredential:completion: erfolgreich ist, kann sich der Benutzer jetzt mit einem beliebigen verknüpften Authentifizierungsanbieter anmelden und auf dieselben Firebase-Daten zugreifen.

Sie können die Verknüpfung eines Authentifizierungsanbieters mit einem Konto aufheben, sodass sich der Benutzer nicht mehr bei diesem Anbieter anmelden kann.

Um die Verknüpfung eines Authentifizierungsanbieters mit einem Benutzerkonto aufzuheben, übergeben Sie die Anbieter-ID an die Methode unlink . Sie können die Anbieter-IDs der mit einem Benutzer verknüpften Authentifizierungsanbieter aus der Eigenschaft providerData abrufen.

Schnell

Auth.auth().currentUser?.unlink(fromProvider: providerID!) { user, error in
  // ...
}

Ziel c

[[FIRAuth auth].currentUser unlinkFromProvider:providerID
                                    completion:^(FIRUser *_Nullable user, NSError *_Nullable error) {
  // ...
}];