Cómo autenticar mediante el Acceso con Google en iOS

Puedes permitir que los usuarios se autentiquen en Firebase accediendo a su cuenta de Google en tu app.

Antes de comenzar

  1. Agrega Firebase al proyecto de iOS. Incluye los siguientes pods en el Podfile:
    pod 'Firebase/Auth'
    pod 'GoogleSignIn'
    
  2. Si aún no conectaste la app al proyecto de Firebase, puedes hacerlo desde Firebase console.
  3. Habilita el Acceso con Google en Firebase console:
    1. En Firebase console, abre la sección Auth.
    2. En la pestaña Método de acceso, 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

En el delegado de la app, importa los siguientes archivos de encabezado:

import Firebase
import GoogleSignIn

En el controlador de vista de tu vista de acceso, importa los siguientes archivos de encabezado:

import Firebase
import GoogleSignIn

Objective-C

En el delegado de la app, importa los siguientes archivos de encabezado:

@import Firebase;
@import GoogleSignIn;

En el controlador de vista de tu vista de acceso, importa los siguientes archivos de encabezado:

@import Firebase;
@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 para obtener información sobre 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: haz doble clic en el nombre del proyecto en la vista de árbol a la izquierda. Selecciona la 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 tu 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 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):

  2. Declara que el delegado de la app implementa el protocolo GIDSignInDelegate.

    Swift

    En AppDelegate.swift:
    class AppDelegate: UIResponder, UIApplicationDelegate, GIDSignInDelegate {
    

    Objective-C

    En AppDelegate.h:
    @interface AppDelegate : UIResponder<UIApplicationDelegate, GIDSignInDelegate>
    
  3. En el método application:didFinishLaunchingWithOptions: del delegado de la app, configura el objeto FirebaseApp y el delegado de acceso.

    Swift

    // Use Firebase library to configure APIs
    FirebaseApp.configure()
    
    GIDSignIn.sharedInstance().clientID = FirebaseApp.app()?.options.clientID
    GIDSignIn.sharedInstance().delegate = self
    

    Objective-C

    // Use Firebase library to configure APIs
    [FIRApp configure];
    
    [GIDSignIn sharedInstance].clientID = [FIRApp defaultApp].options.clientID;
    [GIDSignIn sharedInstance].delegate = self;
    
  4. 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

    @available(iOS 9.0, *)
    func application(_ application: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any])
      -> Bool {
        return GIDSignIn.sharedInstance().handle(url,
                                sourceApplication:options[UIApplicationOpenURLOptionsKey.sourceApplication] as? String,
                                annotation: [:])
    }
    

    Objective-C

    - (BOOL)application:(nonnull UIApplication *)application
                openURL:(nonnull NSURL *)url
                options:(nonnull NSDictionary<NSString *, id> *)options {
      return [[GIDSignIn sharedInstance] handleURL:url
             sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
                    annotation:options[UIApplicationOpenURLOptionsAnnotationKey]];
    }
    

    Para que la app funcione en iOS 8 y versiones anteriores, también deberás implementar el método obsoleto application:openURL:sourceApplication:annotation:.

    Swift

    func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
        return GIDSignIn.sharedInstance().handle(url,
                                                 sourceApplication: sourceApplication,
                                                 annotation: annotation)
    }
    

    Objective-C

    - (BOOL)application:(UIApplication *)application
                openURL:(NSURL *)url
      sourceApplication:(NSString *)sourceApplication
             annotation:(id)annotation {
      return [[GIDSignIn sharedInstance] handleURL:url
                                 sourceApplication:sourceApplication
                                        annotation:annotation];
    }
    
  5. En el delegado de la app, implementa el protocolo GIDSignInDelegate para administrar el acceso. Para ello, define los siguientes métodos:

    Objective-C

    - (void)signIn:(GIDSignIn *)signIn
    didSignInForUser:(GIDGoogleUser *)user
         withError:(NSError *)error {
      // ...
      if (error == nil) {
        GIDAuthentication *authentication = user.authentication;
        FIRAuthCredential *credential =
        [FIRGoogleAuthProvider credentialWithIDToken:authentication.idToken
                                         accessToken:authentication.accessToken];
        // ...
      } else {
        // ...
      }
    }
    
    - (void)signIn:(GIDSignIn *)signIn
    didDisconnectWithUser:(GIDGoogleUser *)user
         withError:(NSError *)error {
      // Perform any operations when the user disconnects from app here.
      // ...
    }
    

    Swift

    func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error?) {
      // ...
      if let error = error {
        // ...
        return
      }
    
      guard let authentication = user.authentication else { return }
      let credential = GoogleAuthProvider.credential(withIDToken: authentication.idToken,
                                                        accessToken: authentication.accessToken)
      // ...
    }
    
    func sign(_ signIn: GIDSignIn!, didDisconnectWith user: GIDGoogleUser!, withError error: Error!) {
        // Perform any operations when the user disconnects from app here.
        // ...
    }
    
  6. Declara que tu controlador de vistas de acceso implementa el protocolo GIDSignInUIDelegate.

    Swift

    En el controlador de vista:

    class MainViewController: UITableViewController, GIDSignInUIDelegate {
    

    Objective-C

    En el archivo de encabezado del controlador de vista:

    @interface MainViewController : UITableViewController<GIDSignInUIDelegate>
    
  7. En el controlador de vista, anula el método viewDidLoad para configurar el delegado de IU del objeto GIDSignIn y para (opcionalmente) acceder sin solicitar la confirmación del usuario.

    Objective-C

    - (void)viewDidLoad {
      [super viewDidLoad];
    
    [GIDSignIn sharedInstance].uiDelegate = self;
    [[GIDSignIn sharedInstance] signIn];
    
      // TODO(developer) Configure the sign-in button look/feel
      // ...
    }
    

    Swift

    override func viewDidLoad() {
      super.viewDidLoad()
    
    GIDSignIn.sharedInstance().uiDelegate = self
    GIDSignIn.sharedInstance().signIn()
    
      // TODO(developer) Configure the sign-in button look/feel
      // ...
    }
    
  8. Agrega un botón GIDSignInButton a tu diseño, archivo XIB, o crea una instancia automáticamente. Para agregar el botón a tu diseño o archivo XIB, agrega una vista y define su clase personalizada como GIDSignInButton.
  9. 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.

3. Autentica con Firebase

En el método signIn:didSignInForUser:withError:, obtén un token de ID de Google y un token de acceso de Google del objeto GIDAuthentication, y cámbialos por una credencial de Firebase:

Swift

func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error?) {
  // ...
  if let error = error {
    // ...
    return
  }

  guard let authentication = user.authentication else { return }
  let credential = GoogleAuthProvider.credential(withIDToken: authentication.idToken,
                                                    accessToken: authentication.accessToken)
  // ...
}

Objective-C

- (void)signIn:(GIDSignIn *)signIn
didSignInForUser:(GIDGoogleUser *)user
     withError:(NSError *)error {
  // ...
  if (error == nil) {
    GIDAuthentication *authentication = user.authentication;
    FIRAuthCredential *credential =
    [FIRGoogleAuthProvider credentialWithIDToken:authentication.idToken
                                     accessToken:authentication.accessToken];
    // ...
  } else {
    // ...
  }
}

Por último, usa la credencial para autenticar con Firebase:

Swift

Auth.auth().signInAndRetrieveData(with: credential) { (authResult, error) in
  if let error = error {
    // ...
    return
  }
  // User is signed in
  // ...
}

Objective-C

[[FIRAuth auth] signInAndRetrieveDataWithCredential:credential
                                         completion:^(FIRAuthDataResult * _Nullable authResult,
                                                      NSError * _Nullable error) {
  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) con las que accedió el usuario. Esta cuenta nueva se almacena como parte del proyecto de Firebase y puede usarse para identificar a un usuario en todas las apps del proyecto, sin importar el método de acceso que se use.

  • En las apps, puedes obtener la información básica de perfil del usuario a partir del objeto FIRUser. Consulta Cómo administrar usuarios.

  • En las reglas de seguridad de Firebase Realtime Database y Cloud Storage, puedes obtener el ID único del usuario que accedió a partir de la variable auth y usarlo para controlar los datos a los que tiene acceso.

Para permitir que los usuarios accedan a tu app con varios proveedores de autenticación, puedes vincular las credenciales de proveedores de autenticación 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 Maneja errores.

Enviar comentarios sobre…

¿Necesitas ayuda? Visita nuestra página de asistencia.