Możesz umożliwić użytkownikom uwierzytelnianie w Firebase za pomocą kont Facebook, integrując w aplikacji logowanie przez Facebooka lub logowanie ograniczone przez Facebooka.
Zanim zaczniesz
Do instalacji zależności Firebase i do zarządzania nimi możesz używać menedżera pakietów Swift.
- Po otwarciu projektu aplikacji wybierz w Xcode opcję File > Add Packages (Plik > Dodaj pakiety).
- Gdy pojawi się prośba, dodaj repozytorium pakietu SDK Firebase na platformy Apple:
- Wybierz bibliotekę Firebase Authentication.
- Dodaj flagę -ObjCdo sekcji Other Linker Flags (Inne flagi linkera) w ustawieniach kompilacji projektu.
- Gdy skończysz, Xcode zacznie automatycznie wyszukiwać i pobierać zależności w tle.
https://github.com/firebase/firebase-ios-sdk.git
Następnie wykonaj kilka czynności konfiguracyjnych:
- W witrynie Facebook dla deweloperów uzyskaj identyfikator aplikacji i klucz tajny aplikacji.
- Włącz logowanie przez Facebooka:- W Firebasekonsoli otwórz sekcję Uwierzytelnianie.
- Na karcie Metoda logowania włącz metodę logowania Facebook i określ identyfikator aplikacji oraz klucz tajny aplikacji uzyskane z Facebooka.
- Następnie sprawdź, czy identyfikator URI przekierowania OAuth (np. my-app-12345.firebaseapp.com/__/auth/handler) jest wymieniony jako jeden z identyfikatorów URI przekierowania OAuth na stronie ustawień aplikacji na Facebooku w sekcji Ustawienia produktu > Logowanie przez Facebooka na stronie Facebook dla deweloperów.
 
Implementowanie logowania przez Facebooka
Aby użyć „klasycznego” logowania przez Facebooka, wykonaj te czynności. Możesz też użyć ograniczonego logowania na Facebooku, jak pokazano w następnej sekcji.
- Zintegruj logowanie przez Facebooka z aplikacją, postępując zgodnie z 
    dokumentacją dla deweloperów. Podczas inicjowania obiektu FBSDKLoginButtonustaw delegata, który będzie odbierać zdarzenia logowania i wylogowywania. Przykład:W delegacie zaimplementujSwiftlet loginButton = FBSDKLoginButton() loginButton.delegate = self Objective-CFBSDKLoginButton *loginButton = [[FBSDKLoginButton alloc] init]; loginButton.delegate = self; didCompleteWithResult:error:.Swiftfunc loginButton(_ loginButton: FBSDKLoginButton!, didCompleteWith result: FBSDKLoginManagerLoginResult!, error: Error!) { if let error = error { print(error.localizedDescription) return } // ... } Objective-C- (void)loginButton:(FBSDKLoginButton *)loginButton didCompleteWithResult:(FBSDKLoginManagerLoginResult *)result error:(NSError *)error { if (error == nil) { // ... } else { NSLog(error.localizedDescription); } } 
- Zaimportuj moduł FirebaseCorew plikuUIApplicationDelegate, a także inne moduły Firebase używane przez delegata aplikacji. Aby na przykład użyć właściwości Cloud Firestore i Authentication:SwiftUIimport SwiftUI import FirebaseCore import FirebaseFirestore import FirebaseAuth // ... Swiftimport FirebaseCore import FirebaseFirestore import FirebaseAuth // ... Objective-C@import FirebaseCore; @import FirebaseFirestore; @import FirebaseAuth; // ... 
- Skonfiguruj współdzieloną instancję FirebaseAppw metodzieapplication(_:didFinishLaunchingWithOptions:)delegata aplikacji:SwiftUI// Use Firebase library to configure APIs FirebaseApp.configure() Swift// Use Firebase library to configure APIs FirebaseApp.configure() Objective-C// Use Firebase library to configure APIs [FIRApp configure]; 
- Jeśli używasz SwiftUI, musisz utworzyć delegata aplikacji i dołączyć go do struktury Appza pomocąUIApplicationDelegateAdaptorlubNSApplicationDelegateAdaptor. Musisz też wyłączyć zamianę delegata aplikacji. Więcej informacji znajdziesz w instrukcjach dotyczących SwiftUI.SwiftUI@main struct YourApp: App { // register app delegate for Firebase setup @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate var body: some Scene { WindowGroup { NavigationView { ContentView() } } } } 
- Po zalogowaniu się użytkownika w implementacji didCompleteWithResult:error:uzyskaj token dostępu dla zalogowanego użytkownika i wymień go na dane logowania Firebase:Swiftlet credential = FacebookAuthProvider .credential(withAccessToken: AccessToken.current!.tokenString) Objective-CFIRAuthCredential *credential = [FIRFacebookAuthProvider credentialWithAccessToken:[FBSDKAccessToken currentAccessToken].tokenString]; 
Implementowanie ograniczonego logowania na Facebooku
Aby zamiast „klasycznego” logowania przez Facebooka używać logowania ograniczonego, wykonaj te czynności.
- Zintegruj w swojej aplikacji logowanie ograniczone na Facebooku, postępując zgodnie z dokumentacją dla deweloperów.
- W przypadku każdego żądania logowania wygeneruj unikalny ciąg losowy – „nonce” – który posłuży Ci do sprawdzenia, czy otrzymany token identyfikatora został przyznany w odpowiedzi na żądanie uwierzytelnienia aplikacji. Ten krok jest ważny, ponieważ zapobiega atakom metodą powtórzenia.
    Możesz wygenerować bezpieczny kryptograficznie ciąg losowy za pomocą funkcji SecRandomCopyBytes(_:_:_), jak w tym przykładzie:W żądaniu logowania wyślesz hasz SHA-256 wartości nonce, który Facebook przekaże w odpowiedzi bez zmian. Firebase weryfikuje odpowiedź, haszując oryginalny nonce i porównując go z wartością przekazaną przez Facebooka.Swiftprivate func randomNonceString(length: Int = 32) -> String { precondition(length > 0) var randomBytes = [UInt8](repeating: 0, count: length) let errorCode = SecRandomCopyBytes(kSecRandomDefault, randomBytes.count, &randomBytes) if errorCode != errSecSuccess { fatalError( "Unable to generate nonce. SecRandomCopyBytes failed with OSStatus \(errorCode)" ) } let charset: [Character] = Array("0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._") let nonce = randomBytes.map { byte in // Pick a random character from the set, wrapping around if needed. charset[Int(byte) % charset.count] } return String(nonce) } Objective-C// Adapted from https://auth0.com/docs/api-auth/tutorials/nonce#generate-a-cryptographically-random-nonce - (NSString *)randomNonce:(NSInteger)length { NSAssert(length > 0, @"Expected nonce to have positive length"); NSString *characterSet = @"0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._"; NSMutableString *result = [NSMutableString string]; NSInteger remainingLength = length; while (remainingLength > 0) { NSMutableArray *randoms = [NSMutableArray arrayWithCapacity:16]; for (NSInteger i = 0; i < 16; i++) { uint8_t random = 0; int errorCode = SecRandomCopyBytes(kSecRandomDefault, 1, &random); NSAssert(errorCode == errSecSuccess, @"Unable to generate nonce: OSStatus %i", errorCode); [randoms addObject:@(random)]; } for (NSNumber *random in randoms) { if (remainingLength == 0) { break; } if (random.unsignedIntValue < characterSet.length) { unichar character = [characterSet characterAtIndex:random.unsignedIntValue]; [result appendFormat:@"%C", character]; remainingLength--; } } } return [result copy]; } Swift@available(iOS 13, *) private func sha256(_ input: String) -> String { let inputData = Data(input.utf8) let hashedData = SHA256.hash(data: inputData) let hashString = hashedData.compactMap { String(format: "%02x", $0) }.joined() return hashString } Objective-C- (NSString *)stringBySha256HashingString:(NSString *)input { const char *string = [input UTF8String]; unsigned char result[CC_SHA256_DIGEST_LENGTH]; CC_SHA256(string, (CC_LONG)strlen(string), result); NSMutableString *hashed = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH * 2]; for (NSInteger i = 0; i < CC_SHA256_DIGEST_LENGTH; i++) { [hashed appendFormat:@"%02x", result[i]]; } return hashed; } 
- Podczas konfigurowania FBSDKLoginButtonustaw delegata, który będzie otrzymywać zdarzenia logowania i wylogowywania, ustaw tryb śledzenia naFBSDKLoginTrackingLimitedi dołącz nonce. Przykład:W delegacie zaimplementujSwiftfunc setupLoginButton() { let nonce = randomNonceString() currentNonce = nonce loginButton.delegate = self loginButton.loginTracking = .limited loginButton.nonce = sha256(nonce) } Objective-C- (void)setupLoginButton { NSString *nonce = [self randomNonce:32]; self.currentNonce = nonce; self.loginButton.delegate = self; self.loginButton.loginTracking = FBSDKLoginTrackingLimited self.loginButton.nonce = [self stringBySha256HashingString:nonce]; } didCompleteWithResult:error:.Swiftfunc loginButton(_ loginButton: FBSDKLoginButton!, didCompleteWith result: FBSDKLoginManagerLoginResult!, error: Error!) { if let error = error { print(error.localizedDescription) return } // ... } Objective-C- (void)loginButton:(FBSDKLoginButton *)loginButton didCompleteWithResult:(FBSDKLoginManagerLoginResult *)result error:(NSError *)error { if (error == nil) { // ... } else { NSLog(error.localizedDescription); } } 
- Zaimportuj moduł FirebaseCorew plikuUIApplicationDelegate, a także inne moduły Firebase używane przez delegata aplikacji. Aby na przykład użyć właściwości Cloud Firestore i Authentication:SwiftUIimport SwiftUI import FirebaseCore import FirebaseFirestore import FirebaseAuth // ... Swiftimport FirebaseCore import FirebaseFirestore import FirebaseAuth // ... Objective-C@import FirebaseCore; @import FirebaseFirestore; @import FirebaseAuth; // ... 
- Skonfiguruj współdzieloną instancję FirebaseAppw metodzieapplication(_:didFinishLaunchingWithOptions:)delegata aplikacji:SwiftUI// Use Firebase library to configure APIs FirebaseApp.configure() Swift// Use Firebase library to configure APIs FirebaseApp.configure() Objective-C// Use Firebase library to configure APIs [FIRApp configure]; 
- Jeśli używasz SwiftUI, musisz utworzyć delegata aplikacji i dołączyć go do struktury Appza pomocąUIApplicationDelegateAdaptorlubNSApplicationDelegateAdaptor. Musisz też wyłączyć zamianę delegata aplikacji. Więcej informacji znajdziesz w instrukcjach dotyczących SwiftUI.SwiftUI@main struct YourApp: App { // register app delegate for Firebase setup @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate var body: some Scene { WindowGroup { NavigationView { ContentView() } } } } 
- Gdy użytkownik zaloguje się, w implementacji didCompleteWithResult:error:użyj tokena identyfikatora z odpowiedzi Facebooka z niezaszyfrowanym jednorazowym kodem, aby uzyskać dane logowania Firebase:Swift// Initialize a Firebase credential. let idTokenString = AuthenticationToken.current?.tokenString let nonce = currentNonce let credential = OAuthProvider.credential(withProviderID: "facebook.com", idToken: idTokenString!, rawNonce: nonce) Objective-C// Initialize a Firebase credential. NSString *idTokenString = FBSDKAuthenticationToken.currentAuthenticationToken.tokenString; NSString *rawNonce = self.currentNonce; FIROAuthCredential *credential = [FIROAuthProvider credentialWithProviderID:@"facebook.com" IDToken:idTokenString rawNonce:rawNonce]; 
Uwierzytelnianie za pomocą Firebase
Na koniec uwierzytelnij się w Firebase za pomocą danych logowania Firebase:
Swift
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 // ... }
Objective-C
[[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; // ... }];
Dalsze kroki
Gdy użytkownik zaloguje się po raz pierwszy, zostanie utworzone nowe konto użytkownika i powiązane z danymi logowania, czyli nazwą użytkownika i hasłem, numerem telefonu lub informacjami o dostawcy uwierzytelniania, za pomocą których użytkownik się zalogował. Nowe konto jest przechowywane w projekcie Firebase i może służyć do identyfikowania użytkownika we wszystkich aplikacjach w projekcie, niezależnie od sposobu logowania.
- 
W aplikacjach możesz uzyskać podstawowe informacje o profilu użytkownika z obiektu User. Zobacz Zarządzanie użytkownikami.
- W Firebase Realtime Database i Cloud Storage regułach bezpieczeństwa możesz pobrać unikalny identyfikator zalogowanego użytkownika ze zmiennej - authi użyć go do kontrolowania, do jakich danych użytkownik ma dostęp.
Możesz zezwolić użytkownikom na logowanie się w aplikacji za pomocą wielu dostawców uwierzytelniania, łącząc dane logowania dostawcy uwierzytelniania z istniejącym kontem użytkownika.
Aby wylogować użytkownika, wywołaj funkcję 
signOut:.
Swift
let firebaseAuth = Auth.auth() do { try firebaseAuth.signOut() } catch let signOutError as NSError { print("Error signing out: %@", signOutError) }
Objective-C
NSError *signOutError; BOOL status = [[FIRAuth auth] signOut:&signOutError]; if (!status) { NSLog(@"Error signing out: %@", signOutError); return; }
Możesz też dodać kod obsługi błędów dla pełnego zakresu błędów uwierzytelniania. Patrz Obsługa błędów.