Agrega acceso a tu app web fácilmente con FirebaseUI

FirebaseUI es una biblioteca creada a partir del SDK de Firebase Authentication que proporciona flujos directos de IU para usar en tu app. FirebaseUI proporciona los siguientes beneficios:

  • Proveedores múltiples: Flujos de acceso para correo electrónico y contraseña, vínculos mediante correo electrónico, autenticación telefónica, Acceso con Google y acceso con Facebook, Twitter y GitHub.
  • Vinculación de cuentas: Flujos para vincular de forma segura cuentas de usuarios a través de proveedores de identidad.
  • Personalización: Anula estilos de CSS de FirebaseUI para cumplir con los requisitos de tu app. Además, FirebaseUI es de código abierto, por lo que puedes hacer tu propia bifurcación del proyecto y personalizarla libremente según tus necesidades.
  • Opción de acceso automático o de registro con One Tap: Integración automática con la opción de registro con One Tap, que permite hacerlo rápidamente en todos los dispositivos.
  • IU localizada: Internacionalización en más de 40 idiomas
  • Actualización de usuarios anónimos: Posibilidad de actualizar usuarios anónimos a través del acceso/registro. Para obtener más información, visita la sección Actualización de usuarios anónimos.

Antes de comenzar

  1. Agrega Firebase Authentication a tu aplicación web y asegúrate de usar la compatibilidad con la v9 (recomendado) o el SDK anterior (consulta la barra lateral anterior).

  2. Incluye FirebaseUI mediante una de las siguientes opciones:

    1. CDN

      En Firebase console, incluye la siguiente secuencia de comandos y el archivo CSS en la etiqueta <head> de la página, debajo del fragmento de inicialización:

      <script src="https://www.gstatic.com/firebasejs/ui/6.0.1/firebase-ui-auth.js"></script>
      <link type="text/css" rel="stylesheet" href="https://www.gstatic.com/firebasejs/ui/6.0.1/firebase-ui-auth.css" />
      
    2. Módulo npm

      Usa el siguiente comando para instalar FirebaseUI y sus dependencias mediante npm:

      $ npm install firebaseui --save
      

      Agrega require a los siguientes módulos dentro de tus archivos de origen:

      var firebase = require('firebase');
      var firebaseui = require('firebaseui');
      
    3. Componente de Bower

      Usa el siguiente comando para instalar FirebaseUI y sus dependencias mediante Bower:

      $ bower install firebaseui --save
      

      Incluye los archivos necesarios en el código HTML si tu servidor HTTP entrega los archivos de bower_components/:

      <script src="bower_components/firebaseui/dist/firebaseui.js"></script>
      <link type="text/css" rel="stylesheet" href="bower_components/firebaseui/dist/firebaseui.css" />
      

Inicializa FirebaseUI

Después de importar el SDK, inicializa la IU de Auth.

// Initialize the FirebaseUI Widget using Firebase.
var ui = new firebaseui.auth.AuthUI(firebase.auth());

Configura métodos de acceso

Antes de que puedas usar Firebase para que los usuarios accedan, debes habilitar y configurar los métodos de acceso que deseas admitir.

Dirección de correo electrónico y contraseña

  1. En Firebase console, abre la sección Authentication y habilita la autenticación con correo electrónico y contraseña.

  2. Agrega el ID del proveedor de correo electrónico a la lista signInOptions de FirebaseUI.

    ui.start('#firebaseui-auth-container', {
      signInOptions: [
        firebase.auth.EmailAuthProvider.PROVIDER_ID
      ],
      // Other config options...
    });
    
  3. Opcional: Se puede configurar EmailAuthProvider para que el usuario ingrese un nombre visible (true en la configuración predeterminada).

    ui.start('#firebaseui-auth-container', {
      signInOptions: [
        {
          provider: firebase.auth.EmailAuthProvider.PROVIDER_ID,
          requireDisplayName: false
        }
      ]
    });
    
  1. En Firebase console, abre la sección Authentication. En la pestaña Método de acceso, habilita el proveedor de Correo electrónico/Contraseña. Ten en cuenta que se debe habilitar el acceso mediante correo electrónico/contraseña para utilizar el acceso con un vínculo de correo electrónico.

  2. En la misma sección, habilita el método de acceso mediante Vínculo de correo electrónico (acceso sin contraseña) y haz clic en Guardar.

  3. Agrega el ID del proveedor de correo electrónico a la lista signInOptions de FirebaseUI junto con el vínculo de correo electrónico signInMethod.

    ui.start('#firebaseui-auth-container', {
      signInOptions: [
        {
          provider: firebase.auth.EmailAuthProvider.PROVIDER_ID,
          signInMethod: firebase.auth.EmailAuthProvider.EMAIL_LINK_SIGN_IN_METHOD
        }
      ],
      // Other config options...
    });
    
  4. Cuando proceses la IU de acceso condicionalmente (para las apps de una sola página), usa ui.isPendingRedirect() a fin de detectar si la URL corresponde a un vínculo de acceso con correo electrónico y si se debe procesar la IU para completar el acceso.

    // Is there an email link sign-in?
    if (ui.isPendingRedirect()) {
      ui.start('#firebaseui-auth-container', uiConfig);
    }
    // This can also be done via:
    if (firebase.auth().isSignInWithEmailLink(window.location.href)) {
      ui.start('#firebaseui-auth-container', uiConfig);
    }
    
  5. Opcional: Se puede configurar EmailAuthProvider para que el acceso mediante vínculo de correo electrónico permita o impida que el usuario complete el acceso en todos los dispositivos.

    Se puede definir una devolución de llamada emailLinkSignIn opcional para mostrar la configuración de firebase.auth.ActionCodeSettings que se usará cuando se envíe el vínculo. Esto permite especificar el manejo del vínculo, el vínculo dinámico personalizado, la información adicional del estado en el vínculo directo, etc. Si no se proporciona, se usa la URL actual y se activa un flujo solo en la Web.

    El acceso mediante vínculo de correo electrónico de FirebaseUI‑web es compatible con FirebaseUI‑Android y FirebaseUI‑iOS, y los usuarios que inicien el flujo desde FirebaseUI‑Android pueden abrir el vínculo y completar el acceso con FirebaseUI‑web. Lo mismo sucede con el flujo contrario.

    ui.start('#firebaseui-auth-container', {
      signInOptions: [
        {
          provider: firebase.auth.EmailAuthProvider.PROVIDER_ID,
          signInMethod: firebase.auth.EmailAuthProvider.EMAIL_LINK_SIGN_IN_METHOD,
          // Allow the user the ability to complete sign-in cross device,
          // including the mobile apps specified in the ActionCodeSettings
          // object below.
          forceSameDevice: false,
          // Used to define the optional firebase.auth.ActionCodeSettings if
          // additional state needs to be passed along request and whether to open
          // the link in a mobile app if it is installed.
          emailLinkSignIn: function() {
            return {
              // Additional state showPromo=1234 can be retrieved from URL on
              // sign-in completion in signInSuccess callback by checking
              // window.location.href.
              url: 'https://www.example.com/completeSignIn?showPromo=1234',
              // Custom FDL domain.
              dynamicLinkDomain: 'example.page.link',
              // Always true for email link sign-in.
              handleCodeInApp: true,
              // Whether to handle link in iOS app if installed.
              iOS: {
                bundleId: 'com.example.ios'
              },
              // Whether to handle link in Android app if opened in an Android
              // device.
              android: {
                packageName: 'com.example.android',
                installApp: true,
                minimumVersion: '12'
              }
            };
          }
        }
      ]
    });
    

Proveedores de OAuth (Google, Facebook, Twitter y GitHub)

  1. En Firebase console, abre la sección Authentication y habilita el acceso con el proveedor de OAuth específico. Asegúrate de que se especifiquen los ID y el secreto de cliente de OAuth apropiados.

  2. En la misma sección Authentication, asegúrate de que el dominio en el que aparecerá tu página de acceso también se agregue a la lista de dominios autorizados.

  3. Agrega el ID de proveedor de OAuth a la lista signInOptions de FirebaseUI.

    ui.start('#firebaseui-auth-container', {
      signInOptions: [
        // List of OAuth providers supported.
        firebase.auth.GoogleAuthProvider.PROVIDER_ID,
        firebase.auth.FacebookAuthProvider.PROVIDER_ID,
        firebase.auth.TwitterAuthProvider.PROVIDER_ID,
        firebase.auth.GithubAuthProvider.PROVIDER_ID
      ],
      // Other config options...
    });
    
  4. Opcional: Para especificar permisos personalizados o parámetros OAuth personalizados por proveedor, puedes pasar un objeto en lugar del valor del proveedor:

    ui.start('#firebaseui-auth-container', {
      signInOptions: [
        {
          provider: firebase.auth.GoogleAuthProvider.PROVIDER_ID,
          scopes: [
            'https://www.googleapis.com/auth/contacts.readonly'
          ],
          customParameters: {
            // Forces account selection even when one account
            // is available.
            prompt: 'select_account'
          }
        },
        {
          provider: firebase.auth.FacebookAuthProvider.PROVIDER_ID,
          scopes: [
            'public_profile',
            'email',
            'user_likes',
            'user_friends'
          ],
          customParameters: {
            // Forces password re-entry.
            auth_type: 'reauthenticate'
          }
        },
        firebase.auth.TwitterAuthProvider.PROVIDER_ID, // Twitter does not support scopes.
        firebase.auth.EmailAuthProvider.PROVIDER_ID // Other providers don't need to be given as object.
      ]
    });
    

Número de teléfono

  1. En Firebase console, abre la sección Authentication y habilita el acceso con número de teléfono.

  2. Asegúrate de que el dominio en el que aparecerá tu página de acceso también se agregue a la lista de dominios autorizados.

  3. Agrega el ID de proveedor del número de teléfono a la lista signInOptions de FirebaseUI.

    ui.start('#firebaseui-auth-container', {
      signInOptions: [
        firebase.auth.PhoneAuthProvider.PROVIDER_ID
      ],
      // Other config options...
    });
    
  4. Opcional: PhoneAuthProvider se puede configurar con parámetros de reCAPTCHA personalizados, independientemente de que reCAPTCHA sea visible (la configuración predeterminada es normal). Consulta los documentos de la API de reCAPTCHA para obtener más información.

    También se puede configurar el país predeterminado en la entrada del número de teléfono. Consulta la lista de códigos de países admitidos para conocer todos los códigos. Si no se especifica, la entrada de número de teléfono se configurará para Estados Unidos (+1) de manera predeterminada.

    Actualmente, se admiten las siguientes opciones.

    ui.start('#firebaseui-auth-container', {
      signInOptions: [
        {
          provider: firebase.auth.PhoneAuthProvider.PROVIDER_ID,
          recaptchaParameters: {
            type: 'image', // 'audio'
            size: 'normal', // 'invisible' or 'compact'
            badge: 'bottomleft' //' bottomright' or 'inline' applies to invisible.
          },
          defaultCountry: 'GB', // Set default country to the United Kingdom (+44).
          // For prefilling the national number, set defaultNationNumber.
          // This will only be observed if only phone Auth provider is used since
          // for multiple providers, the NASCAR screen will always render first
          // with a 'sign in with phone number' button.
          defaultNationalNumber: '1234567890',
          // You can also pass the full phone number string instead of the
          // 'defaultCountry' and 'defaultNationalNumber'. However, in this case,
          // the first country ID that matches the country code will be used to
          // populate the country selector. So for countries that share the same
          // country code, the selected country may not be the expected one.
          // In that case, pass the 'defaultCountry' instead to ensure the exact
          // country is selected. The 'defaultCountry' and 'defaultNationaNumber'
          // will always have higher priority than 'loginHint' which will be ignored
          // in their favor. In this case, the default country will be 'GB' even
          // though 'loginHint' specified the country code as '+1'.
          loginHint: '+11234567890'
        }
      ]
    });
    

Acceso

Para iniciar el flujo de acceso de FirebaseUI, pasa la instancia subyacente de Auth a fin de inicializar la instancia de FirebaseUI.

// Initialize the FirebaseUI Widget using Firebase.
var ui = new firebaseui.auth.AuthUI(firebase.auth());

Define el elemento HTML en el que se mostrará el widget de acceso de FirebaseUI.

<!-- The surrounding HTML is left untouched by FirebaseUI.
     Your app may use that space for branding, controls and other customizations.-->
<h1>Welcome to My Awesome App</h1>
<div id="firebaseui-auth-container"></div>
<div id="loader">Loading...</div>

Especifica la configuración de FirebaseUI (es decir, los proveedores admitidos en personalizaciones de IU así como la realización correcta de devoluciones de llamada, entre otros).

var uiConfig = {
  callbacks: {
    signInSuccessWithAuthResult: function(authResult, redirectUrl) {
      // User successfully signed in.
      // Return type determines whether we continue the redirect automatically
      // or whether we leave that to developer to handle.
      return true;
    },
    uiShown: function() {
      // The widget is rendered.
      // Hide the loader.
      document.getElementById('loader').style.display = 'none';
    }
  },
  // Will use popup for IDP Providers sign-in flow instead of the default, redirect.
  signInFlow: 'popup',
  signInSuccessUrl: '<url-to-redirect-to-on-success>',
  signInOptions: [
    // Leave the lines as is for the providers you want to offer your users.
    firebase.auth.GoogleAuthProvider.PROVIDER_ID,
    firebase.auth.FacebookAuthProvider.PROVIDER_ID,
    firebase.auth.TwitterAuthProvider.PROVIDER_ID,
    firebase.auth.GithubAuthProvider.PROVIDER_ID,
    firebase.auth.EmailAuthProvider.PROVIDER_ID,
    firebase.auth.PhoneAuthProvider.PROVIDER_ID
  ],
  // Terms of service url.
  tosUrl: '<your-tos-url>',
  // Privacy policy url.
  privacyPolicyUrl: '<your-privacy-policy-url>'
};

Por último, procesa la interfaz de Auth de FirebaseUI:

// The start method will wait until the DOM is loaded.
ui.start('#firebaseui-auth-container', uiConfig);

Actualización de usuarios anónimos

Habilita la actualización de usuarios anónimos

Cuando un usuario anónimo accede o se registra con una cuenta permanente, debes asegurar que pueda continuar con lo que estaban haciendo antes de acceder. Para hacerlo, simplemente configura autoUpgradeAnonymousUsers en true cuando configures la IU de acceso (esta opción está inhabilitada de forma predeterminada).

Resolución de conflictos de fusión de actualizaciones de usuarios anónimos

A veces, un usuario que originalmente accedió de forma anónima trata de actualizar su sesión con un usuario de Firebase existente. Como un usuario existente no puede vincularse a otro usuario existente, FirebaseUI activará la devolución de llamada signInFailure con el código de error firebaseui/anonymous-upgrade-merge-conflict cuando ocurra lo anterior. El objeto de error también incluirá la credencial permanente. Para completar el acceso, se debe activar el acceso con la credencial permanente en la devolución de llamada. Antes de que puedas acceder a través de auth.signInWithCredential(error.credential), debes guardar los datos del usuario anónimo y borrarlo. Luego, después de completar el acceso, copia los datos nuevamente al usuario no anónimo. El ejemplo a continuación ilustra el funcionamiento de este flujo.

// Temp variable to hold the anonymous user data if needed.
var data = null;
// Hold a reference to the anonymous current user.
var anonymousUser = firebase.auth().currentUser;
ui.start('#firebaseui-auth-container', {
  // Whether to upgrade anonymous users should be explicitly provided.
  // The user must already be signed in anonymously before FirebaseUI is
  // rendered.
  autoUpgradeAnonymousUsers: true,
  signInSuccessUrl: '<url-to-redirect-to-on-success>',
  signInOptions: [
    firebase.auth.GoogleAuthProvider.PROVIDER_ID,
    firebase.auth.FacebookAuthProvider.PROVIDER_ID,
    firebase.auth.EmailAuthProvider.PROVIDER_ID,
    firebase.auth.PhoneAuthProvider.PROVIDER_ID
  ],
  callbacks: {
    // signInFailure callback must be provided to handle merge conflicts which
    // occur when an existing credential is linked to an anonymous user.
    signInFailure: function(error) {
      // For merge conflicts, the error.code will be
      // 'firebaseui/anonymous-upgrade-merge-conflict'.
      if (error.code != 'firebaseui/anonymous-upgrade-merge-conflict') {
        return Promise.resolve();
      }
      // The credential the user tried to sign in with.
      var cred = error.credential;
      // Copy data from anonymous user to permanent user and delete anonymous
      // user.
      // ...
      // Finish sign-in after data is copied.
      return firebase.auth().signInWithCredential(cred);
    }
  }
});

Pasos siguientes