Community Post

Firebase: Implementando login com Múltiplos Provedores

Fred Policarpo

Olá pessoas,

Vou começar a série de posts sobre o firebase com o serviço de login. Esse tutorial será bem simples. Exibirá uma tela para o usuário logar via Facebook, Google ou Anônimo. Quando logar exibirá uma mensagem dizendo que está logado, exibindo seu nome, email, sua foto e um botão para deslogar.

Experimente

Veja esse exemplo em ação! Acesse aqui!

Baixe o código fonte

Você tem acesso ao código fonte deste tutorial no GitHub!

Vamos começar configurando o seu backend. Loge com sua conta Google no console do firebase.

Crie um novo projeto, o botão fica bem no meio da tela ;)

Ao criar você coloca o nome e escolhe a região(o firebase irá hospedar seus dados e serviços no servidor mais perto de você!)

Agora o firebase vai exibir o painel de controle pra você, todo completão. Você vai clicar nas opções de autenticação.

Agora você vai configurar os métodos de login. É tudo muito intuitivo e simples de usar.

Na tela que lista os métodos de login vamos ativar os três que utilizaremos neste exemplo: Goolge, Facebook e Anônimo.

Premeiro o Google. Basta clicar para ativar e depois em salvar na modal que será exibida. Existem umas configurações opcionais e um texto explicativo sobre IOs que não nos interessa por agora. Basta salvar.

Agora clique para ativar o login vai Face.

Você perceberá que para esse método de autenticação será necessário fornecer um ID e Chave Secreta de um aplicativo Facebook. Portanto, para podermos prosseguir você terá que criar um aplicativo nesta plataforma. Acesse https://developers.facebook.com. No painel de controle clique para adicionar um novo aplicativo.

Acabei de descobrir que fb é um prefixo proíbido para nome de aplicativos do Facebook, por que também é o prefixo do Face. Veja a mensagem que ele me retornou quando tentei criar o aplicativo com o nome: hello-fb-login

Ok, tentei com hello-firebase-login e deu tudo certo, vamos seguir.

Acesse o painel e copie o ID do Aplicativo e Chave Secreta para fazer o link do seu Aplicativo Facebook com o seu Aplicativo Firebase. Você irá copiar esses dados e colar nos campos correspondentes do modal de configuração do Face no Firebase. Veja as duas imanges abaixo:

No Facebook

No Firebase

Note que eu coloquei uma seta no botão de copiar a URI de Redirecionamento do OAuth. Ela é necessária para que o Facebook também conheça sua aplicação Firebase para poder confiar nela. É um aperto de mãos. Então clique aí para copiar essa URI.

No seu painel de controle do Facebook Developers, abra a aba Login do Facebook e procure um campo com o rótulo URIs de redirecionamento do OAuth válidos. Agora copie a URL que o Firebase te indicou. Não se esqueça de salvar as alterações. Agora sim o acordo entre os dois serviços está fechado!

E por último a autenticação em modo anônimo, que é tão simples quanto a do Google. Basta ativar e salvar.


Ok, neste momento finalizamos as configurações do backend para autenticação. Agora vamos trabalhar no código do front-end. O Firebase facilita muito isso. No cabeçalho do painel de controle tem um botão que fornece o código para você adicionar ao seu aplicativo Web.

Como lá bem explica, basta adicionar isso ao seu html. Colocarei em um arquivo separado para javascript. Irei utilizar JQuery para essa aplicação. E a primeira coisa a fazer é a inicialização do firebase quando a página for carregada. Por enquanto nosso arquivo JS fica assim:

$(document).ready(function () {
    firebase.initializeApp(config);
});

var config = {
    apiKey: "AIzaSyAOlL5BIsqbuCT1C3KnJQUY14J1UcUmbgg",
    authDomain: "hello-fb-login.firebaseapp.com",
    databaseURL: "https://hello-fb-login.firebaseio.com",
    storageBucket: "hello-fb-login.appspot.com"
};

As telas são simples, feitas com HTML e CSS:

Pagina de Login

<div id="login" class="cartao hide">
    <div class="login cartao">
        <img src="google_firebase-2-128.png">
        <h1>Bem vindo ao Firebase Login</h1>
        <button onclick="facebookLogin()" class="face">
            <i class="fa fa-facebook-square" aria-hidden="true"></i>Entrar com <b>Facebook</b>
        </button>
        <button onclick="googleLogin()" class="google"><i class="fa fa-google" aria-hidden="true"></i>Entrar com Google
        </button>
        <button onclick="anonimoLogin()" class="anonimo"><i class="fa fa-user" aria-hidden="true"></i>
            Entrar como Anônimo
        </button>
    </div>
    <span class="overlay"></span>
</div>

Pagina do Usuário

<div class="firelogin hide cartao">
    <div>
        <img class="avatar" id="foto">
        <h1 id="username"></h1>
        <h3 id="email"></h3>
    </div>
    <div style="margin-top: 50px">
        <img src="google_firebase-2-128.png">
        <h4>Seja bem vindo ao</h4>
        <p>Firebase Login <i id="iconLogado" class="fa" aria-hidden="true"></i></p>
        <button class="logout" onclick="logout()"><i class="fa fa-sign-out" aria-hidden="true"></i> Sair</button>
    </div>
</div>

As bibliotecas JavaScript necesárias são: JQuery, Firebase, Fontawesome e o Sweetalert(que usei para tratamento de erro).

Confira a página completa no GitHub, e também o CSS.


Agora que já temos o desenho das telas, vamos às funcionalidades, que estão implementadas com funções JavaScript chamadas pelos cliques nos botões das duas telas.

Noção básica do Firebase SDK

Primeiro você deve entender o básico da SDK do Firebase. Ao importar o firebase.json você passa ter acesso ao namespace firebase. Esse namespace fornce os serviços auth(), storage() e database().

Nos códigos abaixo utilizaremos funções do serviço auth() para logar e deslogar. Além de usar objetos provedores que identificam o método de login. Let's code!

Função 1: Logar Via Facebook

Vou usar o login via Popup, existem ainda as opções redirect ou logar direto com as credenciais. Primeiro você deve definir o provedor de autenticação. Em seguida invocar o método signInWithPopup passando o provedor como argumento. Se logar com sucesso a função de retorno conterá o objeto user com os dados que precisamos para montar o tela do usuário. Guardamos tudo isso, além da classe com o ícone do método de login, no armazenamento de sessão do HTML5.

Também temos no código abaixo um tratamento especial de erro, no qual utilizei a lib SweetAlert para exibir as informações para o usuário. O erro em questão é causado quando você loga via Google uma vez, e depois tenta logar com uma conta do Facebook que utiliza o mesmo email. O Firebase te encoraja a manter essa proteção para que seu aplicativo não tenha dados duplicados de dois usuários que representam a mesma pessoa. Ou seja, ele ainda te ajuda a não fazer merdinhas de programação ;)

Esse trabalho feito com código abaixo, dividido em algumas funções.

function facebookLogin() {
    console.debug("Entrando com Facebook...");
    var provider = new firebase.auth.FacebookAuthProvider();

    firebase.auth().signInWithPopup(provider).then(function (result) {
        sessionStorage.iconeProvedor = "fa-facebook-square";
        window.salveUserNaSessao(result.user);
        window.preenchaUsuario();
    }).catch(function (error) {
        if (error.code === 'auth/account-exists-with-different-credential') {
            var email = error.email;
            firebase.auth().fetchProvidersForEmail(email).then(function (providers) {
                sweetAlert("Não deu ;(", 'Você já logou com o email ' + email + ' usando método de autenticação ' + providers, "error");
            });
        } else {
            console.error("ERRO: " + error.code);
            console.error("Falha ao logar: " + error);
        }
    });
}

function salveUserNaSessao(user) {
    sessionStorage.nome = user.displayName;
    sessionStorage.email = user.email;
    sessionStorage.foto = user.photoURL;
}

function preenchaUsuario() {
    $("#iconLogado").addClass(sessionStorage.iconeProvedor);
    $("#username").text(sessionStorage.nome);
    $("#email").text(sessionStorage.email);
    $("#foto").attr("src", sessionStorage.foto);
    $(".firelogin").removeClass("hide");
    $("#login").addClass("hide");
}

E também uma função para delsogar

Que volta para a tela inicial de login, desloga do firebase e limpa a sessão.

fufunction logout() {
    firebase.auth().signOut();
    $(".firelogin").addClass("hide");
    $("#login").removeClass("hide");
    $("#iconLogado").removeClass(sessionStorage.iconeProvedor);
    limparSessao();
}

function limparSessao() {
    sessionStorage.clear();
}

Função 2: Login via Google

Análogo ao anteior.

function googleLogin() {
    console.debug("Entrando com Google...");
    var provider = new firebase.auth.GoogleAuthProvider();
    firebase.auth().signInWithPopup(provider).then(function (result) {
        sessionStorage.iconeProvedor = "fa-google";
        window.salveUserNaSessao(result.user)
        window.preenchaUsuario();
    }).catch(function (error) {
        console.error("Falha ao logar: " + error);
    });
}

Função 3: Login Anônimo

Para esse provedor de login precisei mudar um pouco a logica de montagem da página do usuário. Isso foi necessário por que função de login anônimo não retorna um resultado com dados do usuário. Afinal de contas não existem dados do usuário. Mas existe registro da atividade do usuário; Tudo fica registrado no seu Firebase! Como não existe retorno de dados, para montar a página do usuário eu interceptei a função que detecta se o usuário logou ou deslogou, e nela verifiquei se o usuário é anônimo, para finalmente montar os dados fake e montar a tela do usuário anônimo.

function anonimoLogin() {
    console.debug("Entrando Anônimamente...");

    firebase.auth().signInAnonymously().catch(function (error) {
        console.error("Falha ao logar: " + error);
    });

    firebase.auth().onAuthStateChanged(function (user) {
        if (user && user.isAnonymous) {
            sessionStorage.iconeProvedor = "fa-user";
            window.salveUserNaSessao({
                displayName: 'Mistéérioo',
                email: '@nonimo',
                photoURL: 'https://scontent.fcpq1-1.fna.fbcdn.net/v/t1.0-1/c15.15.190.190/s160x160/482865_107766019411218_1824143669_n.jpg?oh=233c546aafa3f867c19151aebe803804&oe=582AB1AD'
            });
            window.preenchaUsuario();
        } else if (!user) {
            console.log("Deslogou");
        }
    });
}

E isso é tudo pessoal. Além desta forma mais simples que usei para guardar os dados da sessão do usuário, você pode armazená-los como quiser, conforme sua tecnologia de FrontEnd: JSP, Angular, React, ASP, PHP....

Comente aí o que você achou do post e o que você gostaria de estudar a seguir. E não fique aí parado, coloque as mãos na massa.

Let's Code!

Referências

Fred Policarpo

Desenvolvedor FullStack desde 2005. Estudando Angular 2, Ionic 2 e Firebase. Revise seu código, ele pode ser melhor!

https://fredpolicarpo.github.io/