คุณสามารถอนุญาตให้ผู้ใช้ลงชื่อเข้าใช้แอปของคุณโดยใช้ผู้ให้บริการตรวจสอบสิทธิ์หลายรายได้โดยการเชื่อมโยงข้อมูลประจำตัวของผู้ให้บริการตรวจสอบสิทธิ์กับบัญชีผู้ใช้ที่มีอยู่ ผู้ใช้สามารถระบุตัวผู้ใช้ได้ด้วย ID ผู้ใช้ Firebase เดียวกัน ไม่ว่าผู้ให้บริการตรวจสอบสิทธิ์ที่พวกเขาใช้ลงชื่อเข้าใช้จะเป็นคนใดก็ตาม ตัวอย่างเช่น ผู้ใช้ที่ลงชื่อเข้าใช้ด้วยรหัสผ่านสามารถเชื่อมโยงบัญชี Google และลงชื่อเข้าใช้ด้วยวิธีใดวิธีหนึ่งได้ในอนาคต หรือผู้ใช้ที่ไม่ระบุชื่อสามารถเชื่อมโยงบัญชี Facebook จากนั้นลงชื่อเข้าใช้ด้วย Facebook เพื่อใช้แอปของคุณต่อไปได้ในภายหลัง
ก่อนที่คุณจะเริ่ม
เพิ่มการรองรับผู้ให้บริการตรวจสอบสิทธิ์ตั้งแต่ 2 รายขึ้นไป (อาจรวมถึงการตรวจสอบสิทธิ์แบบไม่ระบุชื่อ) ให้กับแอปของคุณ
เชื่อมโยงข้อมูลประจำตัวของผู้ให้บริการรับรองความถูกต้องกับบัญชีผู้ใช้
หากต้องการเชื่อมโยงข้อมูลประจำตัวของผู้ให้บริการรับรองความถูกต้องกับบัญชีผู้ใช้ที่มีอยู่:
- ลงชื่อเข้าใช้ผู้ใช้โดยใช้ผู้ให้บริการหรือวิธีการตรวจสอบความถูกต้อง
- ดำเนินการขั้นตอนการลงชื่อเข้าใช้สำหรับผู้ให้บริการการตรวจสอบสิทธิ์รายใหม่ให้เสร็จสมบูรณ์ แต่ไม่รวมการเรียกหนึ่งในเมธอด
FIRAuth.signInWith
ตัวอย่างเช่น รับโทเค็น Google ID ของผู้ใช้, โทเค็นการเข้าถึง Facebook หรืออีเมลและรหัสผ่าน รับ
FIRAuthCredential
สำหรับผู้ให้บริการการตรวจสอบความถูกต้องรายใหม่:ลงชื่อเข้าใช้ Google
สวิฟท์
guard let authentication = user?.authentication, let idToken = authentication.idToken else { return } let credential = GoogleAuthProvider.credential(withIDToken: idToken, accessToken: authentication.accessToken)
วัตถุประสงค์-C
FIRAuthCredential *credential = [FIRGoogleAuthProvider credentialWithIDToken:result.user.idToken.tokenString accessToken:result.user.accessToken.tokenString];
เข้าสู่ระบบเฟสบุ๊ค
สวิฟท์
let credential = FacebookAuthProvider .credential(withAccessToken: AccessToken.current!.tokenString)
วัตถุประสงค์-C
FIRAuthCredential *credential = [FIRFacebookAuthProvider credentialWithAccessToken:[FBSDKAccessToken currentAccessToken].tokenString];
ลงชื่อเข้าใช้อีเมล-รหัสผ่าน
สวิฟท์
let credential = EmailAuthProvider.credential(withEmail: email, password: password)
วัตถุประสงค์-C
FIRAuthCredential *credential = [FIREmailAuthProvider credentialWithEmail:email password:password];
ส่งผ่านออบเจ็กต์
FIRAuthCredential
ไปยังเมธอดlinkWithCredential:completion:
ของผู้ใช้ที่ลงชื่อเข้าใช้:สวิฟท์
user.link(with: credential) { authResult, error in // ... } }
วัตถุประสงค์-C
[[FIRAuth auth].currentUser linkWithCredential:credential completion:^(FIRAuthDataResult *result, NSError *_Nullable error) { // ... }];
การเรียกไปยัง
linkWithCredential:completion:
จะล้มเหลวหากข้อมูลประจำตัวเชื่อมโยงกับบัญชีผู้ใช้อื่นอยู่แล้ว ในสถานการณ์นี้ คุณต้องจัดการการรวมบัญชีและข้อมูลที่เกี่ยวข้องตามความเหมาะสมสำหรับแอปของคุณ:สวิฟท์
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 // ... }
วัตถุประสงค์-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 // ... }];
หากการเรียก linkWithCredential:completion:
สำเร็จ ขณะนี้ผู้ใช้สามารถลงชื่อเข้าใช้โดยใช้ผู้ให้บริการการตรวจสอบสิทธิ์ที่เชื่อมโยงและเข้าถึงข้อมูล Firebase เดียวกันได้
ยกเลิกการเชื่อมโยงผู้ให้บริการรับรองความถูกต้องจากบัญชีผู้ใช้
คุณสามารถยกเลิกการเชื่อมโยงผู้ให้บริการตรวจสอบสิทธิ์จากบัญชีได้ เพื่อให้ผู้ใช้ไม่สามารถลงชื่อเข้าใช้ด้วยผู้ให้บริการรายนั้นได้อีกต่อไป
หากต้องการยกเลิกการเชื่อมโยงผู้ให้บริการรับรองความถูกต้องจากบัญชีผู้ใช้ ให้ส่งรหัสผู้ให้บริการไปยังวิธี unlink
คุณสามารถรับรหัสผู้ให้บริการของผู้ให้บริการการตรวจสอบสิทธิ์ที่เชื่อมโยงกับผู้ใช้ได้จากพร็อพเพอร์ตี้ providerData
สวิฟท์
Auth.auth().currentUser?.unlink(fromProvider: providerID!) { user, error in // ... }
วัตถุประสงค์-C
[[FIRAuth auth].currentUser unlinkFromProvider:providerID completion:^(FIRUser *_Nullable user, NSError *_Nullable error) { // ... }];