Para permitir que tus usuarios se autentiquen con Firebase mediante su Cuenta de Google, integra el Acceso con Google en tu app.
Antes de comenzar
- Agrega Firebase a tu proyecto de Apple. Incluye los siguientes pods en el
Podfile
:pod 'FirebaseAuth' pod 'GoogleSignIn'
- Si aún no has conectado la app a tu proyecto de Firebase, puedes hacerlo desde Firebase console.
- Habilita Google como método de acceso en Firebase console:
- En Firebase console, abre la sección Autenticación.
- En la pestaña Sign in method, habilita el método de Google y haz clic en Guardar.
1. Importa los archivos de encabezado requeridos
Para comenzar, debes importar a la app los archivos de encabezado del SDK de Firebase y del SDK de Acceso con Google.
Swift
import FirebaseCore import GoogleSignIn
Objective-C
@import FirebaseCore; @import GoogleSignIn;
2. Implementa el Acceso con Google
Sigue estos pasos para implementar el Acceso con Google. Consulta la documentación para desarrolladores sobre el Acceso con Google si quieres obtener información acerca de cómo usar el Acceso con Google en iOS.
- Agrega esquemas de URL personalizadas al proyecto de Xcode:
- Abre la configuración del proyecto. Para ello, haz doble clic en el nombre del proyecto en la vista de árbol a la izquierda. Selecciona tu app en la sección OBJETIVOS, haz clic en la pestaña Información y expande la sección Tipos de URL.
- Haz clic en el botón + y agrega un esquema de URL para el ID de cliente
invertido. A fin de obtener este valor, abre el
archivo de configuración
y busca la claveGoogleService-Info.plist REVERSED_CLIENT_ID
. Copia el valor de esa clave y pégalo en el recuadro Esquemas de URL en la página de configuración. Deja los demás campos en blanco.Cuando termines, la configuración debería ser similar a la que se muestra a continuación (pero con los valores específicos de tu aplicación):
- En el método
application:didFinishLaunchingWithOptions:
del delegado de tu app, configura el objetoFirebaseApp
.Swift
// Use Firebase library to configure APIs FirebaseApp.configure()
Objective-C
// Use Firebase library to configure APIs [FIRApp configure];
- Implementa el método
application:openURL:options:
del delegado de la app. Esto debería invocar el métodohandleURL
de la instanciaGIDSignIn
, que manejará correctamente la URL que reciba la aplicación al final del proceso de autenticación.Swift
@available(iOS 9.0, *) func application(_ application: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any]) -> Bool { return GIDSignIn.sharedInstance.handle(url) }
Objective-C
- (BOOL)application:(nonnull UIApplication *)application openURL:(nonnull NSURL *)url options:(nonnull NSDictionary<NSString *, id> *)options { return [[GIDSignIn sharedInstance] handleURL:url]; }
- Pasa el controlador de vista de presentación y el ID de cliente de tu app al método
de Acceso con Google y crea una credencial de autenticación de Firebase a partir del
token de autenticación de Google resultante:
Swift
guard let clientID = FirebaseApp.app()?.options.clientID else { return } // Create Google Sign In configuration object. let config = GIDConfiguration(clientID: clientID) // Start the sign in flow! GIDSignIn.sharedInstance.signIn(with: config, presenting: self) { [unowned self] user, error in if let error = error { // ... return } guard let authentication = user?.authentication, let idToken = authentication.idToken else { return } let credential = GoogleAuthProvider.credential(withIDToken: idToken, accessToken: authentication.accessToken) // ... }
Objective-C
GIDConfiguration *config = [[GIDConfiguration alloc] initWithClientID:[FIRApp defaultApp].options.clientID]; __weak __auto_type weakSelf = self; [GIDSignIn.sharedInstance signInWithConfiguration:config presentingViewController:self callback:^(GIDGoogleUser * _Nullable user, NSError * _Nullable error) { __auto_type strongSelf = weakSelf; if (strongSelf == nil) { return; } if (error == nil) { GIDAuthentication *authentication = user.authentication; FIRAuthCredential *credential = [FIRGoogleAuthProvider credentialWithIDToken:authentication.idToken accessToken:authentication.accessToken]; // ... } else { // ... } }];
- Agrega un botón
GIDSignInButton
a tu storyboard o archivo XIB, o crea una instancia de manera programática. Para agregar el botón a tu storyboard o archivo XIB, agrega una vista y define su clase personalizada comoGIDSignInButton
. - Opcional: Si quieres personalizar el botón, puedes hacer lo siguiente:
Swift
- En el controlador de vista, declara el botón de acceso como una propiedad.
@IBOutlet weak var signInButton: GIDSignInButton!
- Conecta el botón a la propiedad
signInButton
que acabas de declarar. - Configura las propiedades del objeto GIDSignInButton para personalizar el botón.
Objective-C
- En el archivo de encabezado de tu controlador de vista, declara el botón de acceso como una propiedad.
@property(weak, nonatomic) IBOutlet GIDSignInButton *signInButton;
- Conecta el botón a la propiedad
signInButton
que acabas de declarar. - Configura las propiedades del objeto GIDSignInButton para personalizar el botón.
- En el controlador de vista, declara el botón de acceso como una propiedad.
3. Autentica con Firebase
Por último, completa el proceso de acceso de Firebase con la credencial de autenticación que creaste en el paso anterior.
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; // ... }];
Pasos siguientes
Cuando un usuario accede por primera vez, se crea una cuenta de usuario nueva y se la vincula con las credenciales (el nombre de usuario y la contraseña, el número de teléfono o la información del proveedor de autenticación) que el usuario utilizó para acceder. Esta cuenta nueva se almacena como parte de tu proyecto de Firebase y se puede usar para identificar a un usuario en todas las apps del proyecto, sin importar cómo acceda.
-
En tus apps, puedes obtener la información básica de perfil del usuario a partir del objeto
FIRUser
. Consulta Administrar usuarios. En tus reglas de seguridad de Firebase Realtime Database y Cloud Storage, puedes obtener el ID del usuario único que accedió a partir de la variable
auth
y usarlo para controlar a qué datos podrá acceder.
Para permitir que los usuarios accedan a la app con varios proveedores de autenticación, puedes vincular las credenciales de estos proveedores con una cuenta de usuario existente.
Para salir de la sesión de un usuario, llama a 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; }
Tal vez sea conveniente que agregues código de administración de errores para todos los errores de autenticación. Consulta cómo solucionar errores.