Autentica mediante Google con JavaScript

Puedes permitir que tus usuarios se autentiquen con Firebase mediante sus Cuentas de Google. Puedes usar el SDK de Firebase para ejecutar el flujo de acceso a Google o realizarlo de forma manual con la biblioteca de Acceder con Google y pasar el token de ID resultante a Firebase.

Antes de comenzar

  1. Agrega Firebase a tu proyecto de JavaScript.
  2. Habilita Google como método de acceso en Firebase console:
    1. En Firebase console, abre la sección Authentication.
    2. En la pestaña Sign in method, habilita el método de acceso con Google y haz clic en Guardar.

Maneja el flujo de acceso con el SDK de Firebase

Si estás compilando una app web, la manera más fácil de autenticar a tus usuarios en Firebase con sus Cuentas de Google es administrar el flujo de acceso con el SDK de Firebase JavaScript. Si deseas autenticar a un usuario en Node.js o en cualquier otro entorno que no sea de un navegador, debes manejar el flujo de acceso de forma manual.

Para manejar el flujo de acceso con el SDK de Firebase JavaScript, sigue estos pasos:

  1. Crea una instancia del objeto del proveedor de Google:
    WebWeb
    import { GoogleAuthProvider } from "firebase/auth";
    
    const provider = new GoogleAuthProvider();
    var provider = new firebase.auth.GoogleAuthProvider();
  2. Opcional: Especifica los permisos adicionales de OAuth 2.0 que deseas solicitarle al proveedor de autenticación. Para agregar un permiso, llama a addScope. Por ejemplo:
    WebWeb
    provider.addScope('https://www.googleapis.com/auth/contacts.readonly');
    provider.addScope('https://www.googleapis.com/auth/contacts.readonly');
    Consulta la documentación del proveedor de autenticación.
  3. Opcional: Para ajustar el flujo de OAuth del proveedor según su idioma de preferencia sin pasar de forma explícita los parámetros OAuth personalizados pertinentes, actualiza el código de idioma en la instancia Auth antes de iniciar el flujo de OAuth. Por ejemplo:
    WebWeb
    import { getAuth } from "firebase/auth";
    
    const auth = getAuth();
    auth.languageCode = 'it';
    // To apply the default browser preference instead of explicitly setting it.
    // auth.useDeviceLanguage();
    firebase.auth().languageCode = 'it';
    // To apply the default browser preference instead of explicitly setting it.
    // firebase.auth().useDeviceLanguage();
  4. Opcional: Especifica los parámetros personalizados adicionales del proveedor de OAuth que quieres enviar junto con la solicitud de OAuth. Para agregar un parámetro personalizado, llama a setCustomParameters en el proveedor inicializado con un objeto que contenga la clave que se indica en la documentación del proveedor de OAuth y su valor correspondiente. Por ejemplo:
    WebWeb
    provider.setCustomParameters({
      'login_hint': 'user@example.com'
    });
    provider.setCustomParameters({
      'login_hint': 'user@example.com'
    });
    No se permiten los parámetros de OAuth necesarios reservados y se ignorarán. Consulta la referencia del proveedor de autenticación para obtener más información.
  5. Autentica con Firebase a través del objeto del proveedor de Google. Puedes pedirle a los usuarios que accedan con sus cuentas de Google a través de una ventana emergente o redireccionándolos a la página de acceso. En dispositivos móviles, se prefiere el método de redireccionamiento.
    • Para acceder con una ventana emergente, llama a signInWithPopup:
      WebWeb
      import { getAuth, signInWithPopup, GoogleAuthProvider } from "firebase/auth";
      
      const auth = getAuth();
      signInWithPopup(auth, provider)
        .then((result) => {
          // This gives you a Google Access Token. You can use it to access the Google API.
          const credential = GoogleAuthProvider.credentialFromResult(result);
          const token = credential.accessToken;
          // The signed-in user info.
          const user = result.user;
          // IdP data available using getAdditionalUserInfo(result)
          // ...
        }).catch((error) => {
          // Handle Errors here.
          const errorCode = error.code;
          const errorMessage = error.message;
          // The email of the user's account used.
          const email = error.customData.email;
          // The AuthCredential type that was used.
          const credential = GoogleAuthProvider.credentialFromError(error);
          // ...
        });
      firebase.auth()
        .signInWithPopup(provider)
        .then((result) => {
          /** @type {firebase.auth.OAuthCredential} */
          var credential = result.credential;
      
          // This gives you a Google Access Token. You can use it to access the Google API.
          var token = credential.accessToken;
          // The signed-in user info.
          var user = result.user;
          // IdP data available in result.additionalUserInfo.profile.
            // ...
        }).catch((error) => {
          // Handle Errors here.
          var errorCode = error.code;
          var errorMessage = error.message;
          // The email of the user's account used.
          var email = error.email;
          // The firebase.auth.AuthCredential type that was used.
          var credential = error.credential;
          // ...
        });
      Además, ten en cuenta que puedes recuperar el token de OAuth del proveedor de Google que se puede usar para obtener datos adicionales mediante las API de Google.

      Aquí también puedes detectar y resolver errores. Para obtener una lista de códigos de error, consulta los documentos de referencia de autenticación.

    • Para acceder mediante el redireccionamiento a la página de acceso, llama a signInWithRedirect: Sigue las prácticas recomendadas cuando uses “signInWithRedirect”.
      WebWeb
      import { getAuth, signInWithRedirect } from "firebase/auth";
      
      const auth = getAuth();
      signInWithRedirect(auth, provider);
      firebase.auth().signInWithRedirect(provider);
      Luego, para recuperar el token de OAuth del proveedor de Google, puedes llamar a getRedirectResult cuando se cargue tu página:
      WebWeb
      import { getAuth, getRedirectResult, GoogleAuthProvider } from "firebase/auth";
      
      const auth = getAuth();
      getRedirectResult(auth)
        .then((result) => {
          // This gives you a Google Access Token. You can use it to access Google APIs.
          const credential = GoogleAuthProvider.credentialFromResult(result);
          const token = credential.accessToken;
      
          // The signed-in user info.
          const user = result.user;
          // IdP data available using getAdditionalUserInfo(result)
          // ...
        }).catch((error) => {
          // Handle Errors here.
          const errorCode = error.code;
          const errorMessage = error.message;
          // The email of the user's account used.
          const email = error.customData.email;
          // The AuthCredential type that was used.
          const credential = GoogleAuthProvider.credentialFromError(error);
          // ...
        });
      firebase.auth()
        .getRedirectResult()
        .then((result) => {
          if (result.credential) {
            /** @type {firebase.auth.OAuthCredential} */
            var credential = result.credential;
      
            // This gives you a Google Access Token. You can use it to access the Google API.
            var token = credential.accessToken;
            // ...
          }
          // The signed-in user info.
          var user = result.user;
          // IdP data available in result.additionalUserInfo.profile.
            // ...
        }).catch((error) => {
          // Handle Errors here.
          var errorCode = error.code;
          var errorMessage = error.message;
          // The email of the user's account used.
          var email = error.email;
          // The firebase.auth.AuthCredential type that was used.
          var credential = error.credential;
          // ...
        });
      Aquí también puedes detectar y resolver errores. Para obtener una lista de códigos de error, consulta los documentos de referencia de autenticación.

Si habilitaste el parámetro de configuración Una cuenta por dirección de correo electrónico en Firebase console, aparecerá el error auth/account-exists-with-different-credential junto con un objeto AuthCredential (token de ID de Google) cuando un usuario trate de acceder a un proveedor (como Google) con un correo electrónico que ya está vinculado al proveedor de otro usuario de Firebase (como Facebook). Para completar el acceso al proveedor, el usuario primero debe acceder al proveedor existente (Facebook) y, luego, establecer el vínculo con la AuthCredential anterior (token de ID de Google).

Si usas signInWithPopup, puedes manejar los errores auth/account-exists-with-different-credential con un código como el siguiente:

import {
  getAuth,
  linkWithCredential,
  signInWithPopup,
  GoogleAuthProvider,
} from "firebase/auth";

try {
  // Step 1: User tries to sign in using Google.
  let result = await signInWithPopup(getAuth(), new GoogleAuthProvider());
} catch (error) {
  // Step 2: User's email already exists.
  if (error.code === "auth/account-exists-with-different-credential") {
    // The pending Google credential.
    let pendingCred = error.credential;

    // Step 3: Save the pending credential in temporary storage,

    // Step 4: Let the user know that they already have an account
    // but with a different provider, and let them choose another
    // sign-in method.
  }
}

// ...

try {
  // Step 5: Sign the user in using their chosen method.
  let result = await signInWithPopup(getAuth(), userSelectedProvider);

  // Step 6: Link to the Google credential.
  // TODO: implement `retrievePendingCred` for your app.
  let pendingCred = retrievePendingCred();

  if (pendingCred !== null) {
    // As you have access to the pending credential, you can directly call the
    // link method.
    let user = await linkWithCredential(result.user, pendingCred);
  }

  // Step 7: Continue to app.
} catch (error) {
  // ...
}

Modo de redireccionamiento

Este error se maneja de manera similar en el modo de redireccionamiento, con la diferencia de que la credencial pendiente debe almacenarse en caché entre acciones de redireccionamiento de páginas (por ejemplo, el uso de almacenamiento de sesión).

También puedes autenticar con Firebase mediante una Cuenta de Google. Para ello, debes manejar el flujo de acceso con la biblioteca de Acceder con Google:

  1. Para integrar Acceder con Google a tu app, sigue los pasos de la guía de integración. Asegúrate de configurar el Acceso con Google a través del ID de cliente de Google generado para tu proyecto de Firebase. Puedes encontrar el ID de cliente de Google del proyecto en la página Credenciales de Developers Console del proyecto.
  2. En la devolución de llamada de resultado de acceso, reemplaza el token de ID de la respuesta de autenticación de Google por una credencial de Firebase y úsala para autenticar con Firebase:
    function handleCredentialResponse(response) {
      // Build Firebase credential with the Google ID token.
      const idToken = response.credential;
      const credential = GoogleAuthProvider.credential(idToken);
    
      // Sign in with credential from the Google user.
      signInWithCredential(auth, credential).catch((error) => {
        // Handle Errors here.
        const errorCode = error.code;
        const errorMessage = error.message;
        // The email of the user's account used.
        const email = error.email;
        // The credential that was used.
        const credential = GoogleAuthProvider.credentialFromError(error);
        // ...
      });
    }

Para realizar una autenticación con Firebase en una aplicación de Node.js:

  1. Inicia la sesión del usuario con su cuenta de Google y obtén su token de ID de Google. Hay varias maneras de hacer esto. Por ejemplo:
    • Si tu app tiene un frontend de navegación, usa el Acceso con Google como se describió en la sección para manejar el flujo de acceso de manera manual. Obtén el token de ID de Google de la respuesta de la autenticación:
      var id_token = googleUser.getAuthResponse().id_token
      Luego, envía este token a la app de Node.js.
    • Si la app se ejecuta en un dispositivo que tiene capacidades de entrada limitada, como una TV, puedes usar el flujo de Acceso con Google para TV y otros dispositivos.
  2. Después de obtener el token de ID de Google del usuario, úsalo para crear un objeto de credencial y haz que el usuario acceda con él:
    WebWeb
    import { getAuth, signInWithCredential, GoogleAuthProvider } from "firebase/auth";
    
    // Build Firebase credential with the Google ID token.
    const credential = GoogleAuthProvider.credential(id_token);
    
    // Sign in with credential from the Google user.
    const auth = getAuth();
    signInWithCredential(auth, credential).catch((error) => {
      // Handle Errors here.
      const errorCode = error.code;
      const errorMessage = error.message;
      // The email of the user's account used.
      const email = error.customData.email;
      // The AuthCredential type that was used.
      const credential = GoogleAuthProvider.credentialFromError(error);
      // ...
    });
    // Build Firebase credential with the Google ID token.
    var credential = firebase.auth.GoogleAuthProvider.credential(id_token);
    
    // Sign in with credential from the Google user.
    firebase.auth().signInWithCredential(credential).catch((error) => {
      // Handle Errors here.
      var errorCode = error.code;
      var errorMessage = error.message;
      // The email of the user's account used.
      var email = error.email;
      // The firebase.auth.AuthCredential type that was used.
      var credential = error.credential;
      // ...
    });

Autentica con Firebase en una extensión de Chrome

Si desarrollas una app de extensión de Chrome, consulta la guía de Documentos fuera de pantalla.

Cuando crees un proyecto, Firebase le otorgará un subdominio único: https://my-app-12345.firebaseapp.com.

También se usará como mecanismo de redireccionamiento para el acceso con OAuth. Todos los proveedores de OAuth admitidos deberían permitir el dominio. Sin embargo, es probable que los usuarios vean ese dominio cuando accedan a Google antes de que se los redireccione a la aplicación; p. ej.: Continúa a: https://my-app-12345.firebaseapp.com.

Para evitar que se muestre el subdominio, puedes configurar un dominio personalizado con Firebase Hosting:

  1. Sigue los pasos 1 a 3 de Configura tu dominio para Hosting. Cuando verificas la propiedad de tu dominio, Hosting aprovisiona un certificado SSL para el dominio personalizado.
  2. Agrega tu dominio personalizado a la lista de dominios autorizados en Firebase console: auth.custom.domain.com.
  3. En la consola para desarrolladores de Google o en la página de configuración de OAuth, incluye en la lista de entidades permitidas la URL de la página de redireccionamiento a la que se podrá acceder en tu dominio personalizado: https://auth.custom.domain.com/__/auth/handler.
  4. Cuando inicialices la biblioteca JavaScript, especifica el dominio personalizado en el campo authDomain:
    var config = {
      apiKey: '...',
      // Changed from 'PROJECT_ID.firebaseapp.com'.
      authDomain: 'auth.custom.domain.com',
      databaseURL: 'https://PROJECT_ID.firebaseio.com',
      projectId: 'PROJECT_ID',
      storageBucket: 'PROJECT_ID.firebasestorage.app',
      messagingSenderId: 'SENDER_ID'
    };
    firebase.initializeApp(config);

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, para conocer el estado de autenticación del usuario, te recomendamos configurar un observador en el objeto Auth. Luego podrás obtener la información de perfil básica del usuario a partir del objeto User. Consulta Administra usuarios en Firebase.

  • 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 de la siguiente manera:

WebWeb
import { getAuth, signOut } from "firebase/auth";

const auth = getAuth();
signOut(auth).then(() => {
  // Sign-out successful.
}).catch((error) => {
  // An error happened.
});
firebase.auth().signOut().then(() => {
  // Sign-out successful.
}).catch((error) => {
  // An error happened.
});