Adicione login ao seu app da Web com facilidade usando o FirebaseUI

A FirebaseUI é uma biblioteca criada no SDK do Firebase Authentication que fornece fluxos de IU drop-in para uso no seu app. A FirebaseUI oferece os benefícios a seguir:

  • Vários provedores: fluxos de login com e-mail/senha, link de e-mail, autenticação por telefone, além de Login do Google, do Facebook, do Twitter e do GitHub.
  • Vinculação de contas: fluxos para vincular as contas do usuário de maneira segura nos provedores de identidade.
  • Personalização: modifique os estilos de CSS do FirebaseUI para que eles correspondam aos requisitos do seu app. Além disso, como o FirebaseUI é um recurso de código aberto, você pode bifurcar o projeto e personalizá-lo de acordo com suas necessidades.
  • inscrição com um toque e login automático: a integração automática da inscrição com um toque (em inglês) agiliza o login entre dispositivos.
  • IU localizada: internacionalização para mais de 40 idiomas.
  • Upgrade de usuários anônimos: capacidade de fazer upgrade de usuários anônimos com o uso de login/inscrição. Para mais informações, consulte a seção Como fazer o upgrade de usuários anônimos.

Antes de começar

  1. Adicione o Firebase Authentication ao seu aplicativo da Web, se tiver certeza de que está usando a v9 compatível (recomendado) ou um SDK mais antigo (consulte a barra lateral acima).

  2. Inclua o FirebaseUI com uma das opções a seguir:

    1. CDN

      Inclua o script a seguir e o arquivo CSS na tag <head> da sua página, abaixo do snippet de inicialização do Console do Firebase:

      <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

      Instale o FirebaseUI e as dependências dele usando o npm com o seguinte comando:

      $ npm install firebaseui --save
      

      Use require para exigir os módulos a seguir nos arquivos de origem:

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

      Instale o FirebaseUI e as dependências dele usando o Bower com o seguinte comando:

      $ bower install firebaseui --save
      

      Inclua os arquivos necessários no seu HTML caso seu servidor HTTP exiba os arquivos em bower_components/:

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

Inicializar o FirebaseUI

Após importar o SDK, inicialize a IU do Auth.

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

Configurar métodos de login

Antes de usar o Firebase para fazer o login de usuários, você precisa ativar e configurar os métodos de login que serão compatíveis.

Endereço de e-mail e senha

  1. No Console do Firebase, abra a seção Authentication e ative a autenticação por e-mail e senha.

  2. Adicione o ID do provedor de e-mail à lista de signInOptions do FirebaseUI.

    ui.start('#firebaseui-auth-container', {
      signInOptions: [
        firebase.auth.EmailAuthProvider.PROVIDER_ID
      ],
      // Other config options...
    });
    
  3. Opcional: é possível configurar EmailAuthProvider para exigir que o usuário insira um nome de exibição (o padrão é true).

    ui.start('#firebaseui-auth-container', {
      signInOptions: [
        {
          provider: firebase.auth.EmailAuthProvider.PROVIDER_ID,
          requireDisplayName: false
        }
      ]
    });
    
  1. No Console do Firebase, abra a seção Autenticação. Na guia Método de login, ative o provedor de E-mail/senha. Ative esse método para poder usar o login por link de e-mail.

  2. Na mesma seção, ative o método Link do e-mail (login sem senha) e clique em Salvar.

  3. Adicione o ID do provedor de e-mail à lista de signInOptions do FirebaseUI junto com o link de e-mail 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. Ao renderizar a UI de login condicionalmente (relevante para apps de uma só página), use ui.isPendingRedirect() para detectar se a URL corresponde a um link de login com e-mail e se a interface do usuário precisa ser renderizada para concluir o login.

    // 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: é possível configurar EmailAuthProvider para login por link de e-mail para permitir ou bloquear a ação do usuário de concluir o login entre dispositivos.

    Um callback emailLinkSignIn opcional pode ser definido para retornar a configuração firebase.auth.ActionCodeSettings a ser usada ao enviar o link. Isso fornece a capacidade de especificar como o link pode ser manipulado, o link dinâmico personalizado, o estado adicional no link direto etc. Quando não é fornecido, o URL atual é usado e um fluxo somente da Web é acionado.

    O login do link de e-mail no FirebaseUI-web é compatível com o FirebaseUI-Android e o FirebaseUI-iOS, em que um usuário que inicia o fluxo do FirebaseUI-Android pode abrir o link e fazer login com o FirebaseUI-web. O mesmo vale para o fluxo oposto.

    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'
              }
            };
          }
        }
      ]
    });
    

Provedores de OAuth (Google, Facebook, Twitter e GitHub)

  1. No Console do Firebase, abra a seção Authentication e ative o login do provedor de OAuth especificado. Verifique se o ID e a chave secreta correspondentes do cliente de OAuth também foram especificados.

  2. Também na seção Authentication, verifique se o domínio em que sua página de login será renderizada também está adicionado à lista de domínios autorizados.

  3. Adicione o ID do provedor OAuth à lista de signInOptions do 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 parâmetros OAuth ou escopos personalizados por provedor, transmita um objeto em vez de apenas o valor do provedor:

    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 telefone

  1. No Console do Firebase, abra a seção Authentication e ative o login por número de telefone.

  2. Verifique se o domínio em que sua página de login será renderizada também está adicionado à lista de domínios autorizados.

  3. Adicione o ID do provedor do número de telefone à lista de signInOptions do FirebaseUI.

    ui.start('#firebaseui-auth-container', {
      signInOptions: [
        firebase.auth.PhoneAuthProvider.PROVIDER_ID
      ],
      // Other config options...
    });
    
  4. Opcional: o PhoneAuthProvider pode ser configurado com parâmetros reCAPTCHA personalizados caso esse serviço esteja visível ou invisível (o padrão é normal). Consulte a documentação da API reCAPTCHA para mais detalhes.

    Também é possível configurar o país padrão a ser selecionado na entrada do número de telefone. Consulte a lista completa de códigos de país compatíveis. Se a entrada do número de telefone não for especificada, ela será definida como sendo dos Estados Unidos (+1) por padrão.

    As seguintes opções são aceitas no momento:

    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'
        }
      ]
    });
    

Login

Para iniciar o fluxo de login do FirebaseUI, inicialize a instância do recurso ao transmitir a instância de Auth que está por trás.

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

Defina o elemento HTML em que o widget de login do FirebaseUI será renderizado.

<!-- 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>

Especifique a configuração do FirebaseUI. Isso inclui provedores compatíveis, personalizações da IU, callbacks concluídos etc.

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 fim, processe a interface de autenticação do FirebaseUI:

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

Upgrade de usuários anônimos

Como ativar o upgrade de usuários anônimos

Quando um usuário anônimo faz login ou se inscreve com uma conta permanente, é recomendado que ele possa continuar o que estava fazendo. Para tanto, basta definir autoUpgradeAnonymousUsers como true ao configurar a IU de login (essa opção é desativada por padrão).

Como lidar com conflitos de integração em upgrades de usuários anônimos

Há casos em que um usuário, inicialmente conectado de forma anônima, tenta fazer upgrade para um usuário existente do Firebase. Como um usuário existente não pode ser vinculado a outro usuário existente, o FirebaseUI acionará o callback signInFailure com um código de erro firebaseui/anonymous-upgrade-merge-conflict quando isso ocorrer. O objeto de erro também conterá a credencial permanente. O login com a credencial permanente deve ser acionado no callback para concluir o login. Antes que o login possa ser concluído via auth.signInWithCredential(error.credential), é necessário salvar os dados do usuário anônimo e excluí-lo. Em seguida, após a conclusão do login, copie os dados de volta para o usuário não anônimo. Veja no exemplo a seguir como esse fluxo funcionaria.

// 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);
    }
  }
});

Próximas etapas

  • Para mais informações sobre como usar e personalizar o FirebaseUI, acesse o README.
  • Se você encontrar um problema no FirebaseUI e quiser reportá-lo, use o rastreador de problemas do GitHub.