يمكنك السماح للمستخدمين بتسجيل الدخول إلى تطبيقك باستخدام موفري مصادقة متعددين عن طريق ربط بيانات اعتماد موفر المصادقة بحساب مستخدم موجود. يمكن التعرف على المستخدمين من خلال معرف مستخدم Firebase نفسه بغض النظر عن موفر المصادقة الذي استخدموه لتسجيل الدخول. على سبيل المثال، يمكن للمستخدم الذي سجل الدخول باستخدام كلمة مرور ربط حساب Google وتسجيل الدخول بأي من الطريقتين في المستقبل. أو يمكن لمستخدم مجهول ربط حساب Facebook ثم تسجيل الدخول لاحقًا باستخدام Facebook لمواصلة استخدام تطبيقك.
قبل ان تبدأ
أضف دعمًا لاثنين أو أكثر من موفري المصادقة (ربما بما في ذلك المصادقة المجهولة) إلى تطبيقك.
ربط بيانات اعتماد موفر المصادقة بحساب المستخدم
لربط بيانات اعتماد موفر المصادقة بحساب مستخدم موجود:
- قم بتسجيل دخول المستخدم باستخدام أي مزود أو طريقة مصادقة.
- أكمل تدفق تسجيل الدخول لموفر المصادقة الجديد بما يصل إلى، على سبيل المثال لا الحصر، استدعاء إحدى أساليب
FIRAuth.signInWith
. على سبيل المثال، احصل على رمز معرف Google المميز للمستخدم، أو رمز الوصول إلى Facebook، أو البريد الإلكتروني وكلمة المرور. احصل على
FIRAuthCredential
لموفر المصادقة الجديد:تسجيل الدخول إلى جوجل
سويفت
guard let authentication = user?.authentication, let idToken = authentication.idToken else { return } let credential = GoogleAuthProvider.credential(withIDToken: idToken, accessToken: authentication.accessToken)
ج موضوعية
FIRAuthCredential *credential = [FIRGoogleAuthProvider credentialWithIDToken:result.user.idToken.tokenString accessToken:result.user.accessToken.tokenString];
تسجيل الدخول الى الفيسبوك
سويفت
let credential = FacebookAuthProvider .credential(withAccessToken: AccessToken.current!.tokenString)
ج موضوعية
FIRAuthCredential *credential = [FIRFacebookAuthProvider credentialWithAccessToken:[FBSDKAccessToken currentAccessToken].tokenString];
تسجيل الدخول بكلمة المرور - البريد الإلكتروني
سويفت
let credential = EmailAuthProvider.credential(withEmail: email, password: password)
ج موضوعية
FIRAuthCredential *credential = [FIREmailAuthProvider credentialWithEmail:email password:password];
قم بتمرير كائن
FIRAuthCredential
إلى طريقةlinkWithCredential:completion:
بالمستخدم الذي قام بتسجيل الدخول:سويفت
user.link(with: credential) { authResult, error in // ... } }
ج موضوعية
[[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 // ... }
ج موضوعية
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 // ... }
ج موضوعية
[[FIRAuth auth].currentUser unlinkFromProvider:providerID completion:^(FIRUser *_Nullable user, NSError *_Nullable error) { // ... }];