Autenticar mediante el Acceso con Google en plataformas de Apple

Puedes permitir que tus usuarios se autentiquen en Firebase mediante su cuenta de Google al integrar el Acceso con Google en tu app.

Antes de comenzar

Usa Swift Package Manager para instalar y administrar las dependencias de Firebase.

  1. En Xcode, con tu proyecto de app abierto, navega a File > Add Packages.
  2. Cuando se te solicite, agrega el repositorio del SDK de Firebase para plataformas de Apple:
  3.   https://github.com/firebase/firebase-ios-sdk.git
  4. Elige la biblioteca de Firebase Authentication.
  5. Agrega la marca -ObjC a la sección Other Linker Flags de la configuración de compilación de tu destino.
  6. Cuando termines, Xcode comenzará a resolver y descargar automáticamente tus dependencias en segundo plano.

Agrega el SDK de Acceso con Google a tu proyecto

  1. En Xcode, con tu proyecto de app abierto, navega a File > Add Packages.

  2. Cuando se te solicite, agrega el repositorio del SDK de Acceso con Google:

    https://github.com/google/GoogleSignIn-iOS
    
  3. Cuando termines, Xcode comenzará a resolver y descargar automáticamente tus dependencias en segundo plano.

Habilita el Acceso con Google para tu proyecto de Firebase

Para permitir que los usuarios accedan mediante el Acceso con Google, primero debes habilitar el proveedor correspondiente para tu proyecto de Firebase:

  1. En Firebase console, abre la sección Authentication.
  2. En la pestaña Método de acceso, habilita el proveedor de Google.
  3. Haz clic en Guardar.

  4. Descarga una copia nueva del archivo GoogleService-Info.plist de tu proyecto y cópiala en tu proyecto de Xcode. Reemplaza cualquier versión existente por la nueva (Consulta Agrega Firebase a tu proyecto de iOS).

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 FirebaseAuth
import GoogleSignIn

Objective-C

@import FirebaseCore;
@import GoogleSignIn;

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.

  1. Agrega esquemas de URL personalizadas al proyecto de Xcode:
    1. Abre la configuración del proyecto; para ello, haz 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.
    2. 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 GoogleService-Info.plist y busca la clave REVERSED_CLIENT_ID. Copia el valor de esa clave y pégalo en el recuadro URL Schemes en la página de configuración. No modifiques los otros campos.

      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):

  2. En el método application:didFinishLaunchingWithOptions: del delegado de tu app, configura el objeto FirebaseApp.

    Swift

    FirebaseApp.configure()

    Objective-C

    // Use Firebase library to configure APIs
    [FIRApp configure];
  3. Implementa el método application:openURL:options: del delegado de la app. Esto debería invocar el método handleURL de la instancia GIDSignIn, que manejará correctamente la URL que reciba la aplicación al final del proceso de autenticación.

    Swift

    func application(_ app: 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];
    }
  4. Pasa el controlador de vista de presentación y el ID de cliente de tu app al método signIn del proveedor de Acceso con Google y crea una credencial de Firebase Authentication 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)
    GIDSignIn.sharedInstance.configuration = config
    
    // Start the sign in flow!
    GIDSignIn.sharedInstance.signIn(withPresenting: self) { [unowned self] result, error in
      guard error == nil else {
        // ...
      }
    
      guard let user = result?.user,
        let idToken = user.idToken?.tokenString
      else {
        // ...
      }
    
      let credential = GoogleAuthProvider.credential(withIDToken: idToken,
                                                     accessToken: user.accessToken.tokenString)
    
      // ...
    }

    Objective-C

    GIDConfiguration *config = [[GIDConfiguration alloc] initWithClientID:[FIRApp defaultApp].options.clientID];
    [GIDSignIn.sharedInstance setConfiguration:config];
    
    __weak __auto_type weakSelf = self;
    [GIDSignIn.sharedInstance signInWithPresentingViewController:self
          completion:^(GIDSignInResult * _Nullable result, NSError * _Nullable error) {
      __auto_type strongSelf = weakSelf;
      if (strongSelf == nil) { return; }
    
      if (error == nil) {
        FIRAuthCredential *credential =
        [FIRGoogleAuthProvider credentialWithIDToken:result.user.idToken.tokenString
                                         accessToken:result.user.accessToken.tokenString];
        // ...
      } else {
        // ...
      }
    }];
  5. 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 como GIDSignInButton.
  6. Opcional: Si quieres personalizar el botón, puedes hacer lo siguiente:

    Swift

    1. En el controlador de vista, declara el botón de acceso como una propiedad.
      @IBOutlet weak var signInButton: GIDSignInButton!
    2. Conecta el botón a la propiedad signInButton que acabas de declarar.
    3. Configura las propiedades del objeto GIDSignInButton para personalizar el botón.

    Objective-C

    1. 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;
    2. Conecta el botón a la propiedad signInButton que acabas de declarar.
    3. Configura las propiedades del objeto GIDSignInButton para personalizar el botón.

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) { result, error in

  // At this point, our 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;
  // ...
}];

Próximos pasos

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 User. Consulta cómo 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 tu app mediante 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 manejo de errores para todos los errores de autenticación. Consulta cómo solucionar errores.