Artigo original: https://www.freecodecamp.org/news/google-login-with-react-native-and-firebase/

O login do Google é um ótimo recurso de login a ser oferecido aos usuários de sua aplicação. Ele facilita para os usuários a criação de uma conta e o login.

Melhor do que isso, o Firebase torna extremamente fácil para os desenvolvedores adicionar suporte ao login do Google. Configurar o ambiente do React Native, no entanto, pode criar alguns desafios, os quais são totalmente tratados neste tutorial.

O React Native e o SDK do Firebase tornam a implementação do login do Google bastante simples. Vamos construir uma aplicação simples que tem apenas um único botão de login do Google. Uma vez que o usuário faça login no Google com sucesso, exibiremos as informações do usuário recuperadas de sua conta do Google, bem como um botão de logout.

Você também pode adicionar o login do Facebook à aplicação se estiver interessado em fornecer ainda mais opções de login para seus usuários. Você pode conferir este guia para login do Facebook no React Native com Firebase (texto em inglês) se quiser aprender mais sobre como configurar o login no Facebook.

Por que usar um botão de login do Google em aplicações para dispositivos móveis?

  1. Usar o Google ou outras aplicações de terceiros pode fazer o seu processo de autenticação descomplicado e amigável. Os usuários não precisam perder tempo no processo de registro, o que melhorará tremendamente suas taxas de registro e retenção.
  2. É seguro e protegido.
  3. Os usuários confiam mais no Google ou no Facebook do que em um portal ou aplicação desconhecida da internet.
  4. Ele fornece uma boa experiência ao usuário. Como usuário, temos pouca paciência para qualquer ação ou trabalho que precisemos fazer, especialmente em uma aplicação bastante desconhecida que estamos testando pela primeira vez.

Sem mais delongas, vamos pular diretamente para a parte de desenvolvimento de aplicações deste tutorial.

Configurando o projeto do Firebase

Vá até o console do Firebase e crie um projeto do Firebase:

create-new-firebase-project
Cria um projeto do Firebase

Aqui, precisaremos configurar o nome do projeto do Firebase e o identificador da aplicação. Então, vamos primeiro criar a aplicação do React Native.

Criando o projeto do React Native

Primeiro, precisamos criar um projeto do React Native usando o seguinte comando:

react-native init instamobile-google-login-demo

Aqui, demos ao projeto o nome instamobile-google-login-demo. Agora, precisamos instalar o pacote react-native-google-signin usando o seguinte comando:

yarn add react-native-google-singin

O pacote react-native-google-signin é usado para implementar as funções de autenticação do Google na aplicação do React Native. Agora, precisamos importar os módulos e componentes necessários do respectivo pacote, conforme mostrado no trecho de código abaixo:

import {
GoogleSignin,
GoogleSigninButton,
statusCodes,
} from 'react-native-google-signin';
Importa o componente de login do google

Em seguida, precisamos criar os estados para lidar com o estado de autenticação e as informações do usuário. Para isso, utilizamos o módulo useState, conforme mostrado no trecho de código abaixo:

const [loggedIn, setloggedIn] = useState(false);
const [userInfo, setuserInfo] = useState([]);
Adiciona os estados

Agora, precisamos criar uma função de login para lidar com a autenticação, conforme mostrado no trecho de código abaixo:

_signIn = async () => {
  try {
    await GoogleSignin.hasPlayServices();
    const {accessToken, idToken} = await GoogleSignin.signIn();
    setloggedIn(true);
  } catch (error) {
    if (error.code === statusCodes.SIGN_IN_CANCELLED) {
      // usuário cancelou o fluxo de login
      alert('Cancel');
    } else if (error.code === statusCodes.IN_PROGRESS) {
      alert('Signin in progress');
      // operação (por exemplo, o login) já está em andamento
    } else if (error.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE) {
      alert('PLAY_SERVICES_NOT_AVAILABLE');
      // serviços de execução não disponível ou desatualizado
    } else {
      // algum outro erro ocorreu
    }
  }
};
Adiciona a função do google sign-in

A seguir, precisamos inicializar a configuração do objeto de login do Google, fazendo uso da função useEffect:

useEffect(() => {
   GoogleSignin.configure({
     scopes: ['email'], // qual API você quer acessar em nome do usuário; o padrão é o email e o perfil
     webClientId:
       '418977770929-g9ou7r9eva1u78a3anassxxxxxxx.apps.googleusercontent.com', // o ID do client do tipo WEB para seu servidor (necessário para verificar o ID do usuário e o acesso off-line)
     offlineAccess: true, // se você deseja acessar a API do Google API em nome do usuário DE SEU SERVIDOR
   });
 }, []);

Por fim, precisamos de uma função que lide com a ação de logout. Para isso, vamos implementar o método signOut, conforme mostrado no trecho de código abaixo:

signOut = async () => {
    try {
      await GoogleSignin.revokeAccess();
      await GoogleSignin.signOut();
      setloggedIn(false);
      setuserInfo([]);
    } catch (error) {
      console.error(error);
    }
  };
Adiciona a função de sign-out do Google 

Agora, precisamos apresentar os componentes na tela também. Para isso, vamos fazer uso de vários componentes como View e Button:

return (
    <>
      <StatusBar barStyle="dark-content" />
      <SafeAreaView>
        <ScrollView
          contentInsetAdjustmentBehavior="automatic"
          style={styles.scrollView}>
          <Header />

          <View style={styles.body}>
            <View style={styles.sectionContainer}>
              <GoogleSigninButton
                style={{width: 192, height: 48}}
                size={GoogleSigninButton.Size.Wide}
                color={GoogleSigninButton.Color.Dark}
                onPress={this._signIn}
              />
            </View>
            <View style={styles.buttonContainer}>
              {!loggedIn && <Text>You are currently logged out</Text>}
              {loggedIn && (
                <Button
                  onPress={this.signOut}
                  title="LogOut"
                  color="red"></Button>
              )}
            </View>
          </View>
        </ScrollView>
      </SafeAreaView>
    </>
  );
Código da IU

Agora, se nós executarmos nosso projeto no emulador, teremos os seguintes resultados:

google-login-first-screen
Login com Google React Native

Bem legal, certo? Concluímos a implementação (tanto da interface do usuário quanto da lógica de negócios) a nível do React Native em nosso projeto.

Como você pode ver, temos um botão "Sign in with Google" (Fazer login com o Google, em português) que se converte em um botão de logout assim que a operação de login é concluída com sucesso.

Agora, vamos configurar o pacote do Google SignIn e a aplicação do Firebase.

Configurando os projetos nativos do iOS e do Android

Existem algumas etapas de configuração que precisamos seguir antes que o projeto esteja totalmente funcionando. Elas estão relacionadas principalmente ao verdadeiro lado nativo da aplicação.

Para iOS

No VSCode (ou em qualquer Terminal), basta executar cd ios && pod install. Em seguida, abra o arquivo .xcworkspace no Xcode (da pasta ios) e verifique se os Pods estão incluídos:

install-google-login-lib-in-xcode
Instala a biblioteca google login no xcode

Para Android

1. Primeiro, precisamos vincular o módulo nativo.

  • Se RN >= 0.60, você não precisa fazer nada, graças à vinculação automática.
  • Se RN < 0.60, execute react-native link react-native-google-signin.

2. Atualize o android/build.gradle com a seguinte configuração:

buildscript {
    ext {
        buildToolsVersion = "27.0.3"
        minSdkVersion = 16
        compileSdkVersion = 27
        targetSdkVersion = 26
        supportLibVersion = "27.1.1"
        googlePlayServicesAuthVersion = "16.0.1" // <--- use esta versão ou uma mais recente
    }
...
    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.2' // <--- use esta versão ou uma mais recente
        classpath 'com.google.gms:google-services:4.1.0' // <--- use esta versão ou uma mais recente
    }
...
allprojects {
    repositories {
        mavenLocal()
        google() // <--- certifique-se de que isto está incluído
        jcenter()
        maven {
            // Todo o React Native (JS, fontes do Obj-C, binários do Android) é instalado a partir do npm
            url "$rootDir/../node_modules/react-native/android"
        }
    }
}

3. Atualize o android/app/build.gradle com a seguinte configuração:

...
dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation "com.android.support:appcompat-v7:23.0.1"
    implementation "com.facebook.react:react-native:+"
    implementation(project(":react-native-community_google-signin")) // <--- adicione esta dependência
}

Confira se o react-native link vinculou o módulo nativo – porém, apenas se você usou o react-native link!

Em android/settings.gradle, devemos ter as seguintes configurações:

...
include ':react-native-google-signin', ':app'
project(':react-native-google-signin').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/google-signin/android')
Configura o google login para android em setting.gradle

Em seguida, em MainApplication.java , devemos ter o pacote do Google adicionado, conforme o trecho de código a seguir:

import co.apptailor.googlesignin.RNGoogleSigninPackage;  // <--- importar

public class MainApplication extends Application implements ReactApplication {

  ......

  @Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
          new MainReactPackage(),
          new RNGoogleSigninPackage() // <-- isto precisa estar na lista
      );
    }
  ......

}
Configura o google login para android em MainApplication.java

Configurando o Firebase

Para iOS

Agora, precisamos começar a configuração do Firebase. No Firebase, precisamos configurar uma aplicação em nuvem do Google. Quando configuramos o método de autenticação no Firebase, no entanto, isso também cria uma aplicação em nuvem do Google.

Primeiro, precisamos criar a aplicação do iOS do Firebase para obter o GoogleServiceinfo.plist, como mostrado na captura de tela abaixo:

add-new-firebase-app-name
Adiciona novo nome de aplicação do Firebase

Em seguida, copiamos o arquivo GoogleService-info.plist para o projeto do Xcode, como mostrado na captura de tela abaixo:

add-google-service-plist-to-xcode
Adiciona o serviço do google plist ao xcode

Agora, precisamos adicionar o ID do client invertido que está presente no arquivo GoogleService-info.plist aos tipos de URL, tal como mostrado na captura de tela abaixo:

get-reverse-client-id-from-xcode
Obtém o id do client invertido do xcode

O próximo passo é ir até InfoURL Types e preencher o URL Schemes como mostrado na captura de tela abaixo:

add-url-scheme-to-xcode
Adiciona o url scheme ao xcode

Para Android

Primeiro, precisamos criar uma aplicação do Android no Firebase. Para isso, precisamos de um nome de pacote e certificado SHA-1 da nossa aplicação. Em seguida, podemos registrar a aplicação do Firebase, conforme mostrado abaixo:

create-new-android-firebase-app-300x252
Cria uma nova aplicação do Android do Firebase

Podemos obter o nome do pacote em MainApplication.java do nosso projeto, conforme destacado no trecho de código abaixo:

find-out-bundle-name-in-android-app-1024x408
Descobre o nome do pacote na aplicação do Android

Em seguida, podemos obter a chave SHA-1 no arquivo Keystore. No diretório android/app, podemos executar o comando:

cd android/app ; 
keytool -exportcert -keystore debug.keystore -list -v
Gera sha-1

Então, a chave SHA-1 aparecerá, conforme mostrado na captura de tela abaixo:

generate-sha1-for-register-android-app-in-firebase
Gera sha1 para registrar a aplicação do Android no Firebase

Após criar a aplicação de configuração do Firebase com sucesso, precisamos baixar o arquivo google-services.json e copiá-lo para o diretório, conforme mostrado na captura de tela abaixo:

add-google-service-json-to-android-app-folder-250x300
Adiciona google service json à pasta da aplicação do android

Agora, a etapa final é configurar um componente de login do Google no Android.

Instalando o pacote do Firebase do React Native

Para instalar o pacote react-native-firebase, versão 6, precisamos executar o seguinte comando no prompt de comando do nosso projeto:

# Using npm 
npm install --save @react-native-firebase/app 
# Using Yarn 
yarn add @react-native-firebase/app
Instala o componente principal react-native-firebase

O módulo @react-native-firebase/app deve ser instalado antes de usar qualquer outro serviço do Firebase.

Para iOS

Já adicionamos GoogleService-Info.plist ao Xcode. O que resta é permitir que o Firebase no iOS use as credenciais. O SDK do Firebase para iOS deve ser configurado durante a fase de inicialização da aplicação.

Para fazer isso, precisamos abrir nosso arquivo /ios/{projectName}/AppDelegate.m, e adicionar o seguinte:

Na parte superior do arquivo, precisamos importar o SDK do Firebase:

#import <Firebase.h>
Inclui o Firebase

Dentro do método didFinishLaunchingWithOptions existente, precisamos adicionar o seguinte ao topo do método:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  // Adicione-me --- \/
  if ([FIRApp defaultApp] == nil) {
    [FIRApp configure];
  }
  // Adicione-me --- /\
  // ...
}
Firebase React Native

Por fim, precisamos executar o seguinte comando para finalizar a instalação do pacote CocoaPods:

cd ios ; pod install
instala CocoaPods

É isso. Concluímos a instalação do pacote principal do Firebase no iOS.

Para Android

Precisamos configurar o Firebase com as credenciais do Android. Para permitir que o Firebase no Android use as credenciais, o plugin google-services deve estar ativado no projeto. Isso requer a modificação em dois arquivos no diretório Android.

Primeiro, adicione o plug-in google-services como uma dependência dentro do arquivo android/build.gradle:

buildscript {
  dependencies {
    // ... outras dependências
    classpath 'com.google.gms:google-services:4.2.0'
    // Adicione-me --- /\
  }
}
// Por fim, execute o plug-in adicionando o seguinte ao final do arquivo /android/app/build.gradle:

apply plugin: 'com.google.gms.google-services'
Adiciona o serviço google

Módulo de autenticação do React Native Firebase

Após a conclusão da instalação, precisamos configurar o pacote pai do Firebase. Em seguida, precisamos instalar o módulo filho para autenticação. Para isso, precisamos abrir um terminal e executar o seguinte comando:

yarn add @react-native-firebase/auth
install react native firebase auth 

Para iOS

Precisamos instalar os pods novamente na linha de comando:

cd ios/ && pod install
Instala o cacao pod

Para Android

Você pode seguir as instruções na documentação oficial, a qual é necessária somente se você estiver usando o React Native <= 0.59 ou se precisar integrar manualmente a biblioteca.

Ativando o login do Google no Firebase

Precisamos ir ao console do Firebase. Em seguida, na seção Authentication (Autenticação, em português), precisamos clicar em Google, conforme mostrado na captura de tela abaixo:

authentication-method-in-firebase-1024x396
Método de autenticação no Firebase

Em seguida, precisamos habilitar a configuração e salvá-la conforme mostrado na captura de tela abaixo:

select-support-email-in-firebase-app
Ativa o e-mail de suporte do projeto

No App.js, precisamos importar o auth do pacote Firebase, como mostrado no trecho de código abaixo:

import auth from '@react-native-firebase/auth';
Importa o auth do pacote firebase

Em seguida, precisamos integrar a configuração de autenticação à função de login. Após um login bem-sucedido, armazenamos o accessToken e o idToken no Firebase. Agora, podemos tentar fazer login com o Google em nossa aplicação do React Native de demonstração.

_signIn = async () => {
    try {
      await GoogleSignin.hasPlayServices();
      const {accessToken, idToken} = await GoogleSignin.signIn();
      setloggedIn(true);
      const credential = auth.GoogleAuthProvider.credential(
        idToken,
        accessToken,
      );
      await auth().signInWithCredential(credential);
    } catch (error) {
Função de Login do Firebase

Agora, concluímos com sucesso a integração do Login do Google em nossa aplicação do React Native:

2020-06-29-17.52.16
Resultado do login do Google com o React Native

Podemos ver novos dados que são adicionados ao console do Firebase:

firebase-authentication-console
Console de autenticação do firebase

Rastreando o status do usuário

Para verificar o status do login do usuário, usamos o Firebase Auth. Para isso, precisamos adicionar o método onAuthStateChanged ao useEffect para que ele seja executado em cada chamada do evento componentDidMount.

Além disso, precisamos passar um retorno de chamada para a função denominada onAuthStateChanged como um argumento, conforme mostrado no trecho de código abaixo:

useEffect(() => {
    .............
    const subscriber = auth().onAuthStateChanged(onAuthStateChanged);
    return subscriber; // remover a inscrição ao desmontar
  }, []);
Subscreve ao estado da autenticação

Na função onAuthStateChanged, tratamos os dados do estado local conforme mostrado no trecho de código abaixo:

function onAuthStateChanged(user) {
    setUser(user);
    console.log(user);
    if (user) setloggedIn(true);
  }
Define dados do usuário

Agora, precisamos armazenar os dados do usuário no estado. Em seguida, tentar exibir os dados do usuário após um login bem-sucedido. Para isso, precisamos usar o seguinte pedaço de código:

{!user && <Text>You are currently logged out</Text>}
{user && (
  <View>
    <Text>Welcome {user.displayName}</Text>
    <Button
      onPress={this.signOut}
      title="LogOut"
      color="red"></Button>
  </View>
)}
Código para exibir as informações do usuário

Teremos o seguinte resultado em nosso simulador:

show-auth-user-name
Logout do auth do Firebase

Logout do Firebase

Para sair, precisamos remover todas as credenciais do usuário e revogar o token de login do Google.

Primeiro, precisamos aguardar o módulo GoogleSignin revogar o acesso e sair. Em seguida, chamamos o método signOut da autenticação do Firebase para fazer logout com êxito.

A implementação completa do código é fornecida no trecho de código abaixo:

signOut = async () => {
    try {
      await GoogleSignin.revokeAccess();
      await GoogleSignin.signOut();
      auth()
        .signOut()
        .then(() => alert('Your are signed out!'));
      setloggedIn(false);
      // setuserInfo([]);
    } catch (error) {
      console.error(error);
    }
  };
Função de logout do Firebase

Como resultado, agora podemos realizar operações de logout, conforme mostrado no trecho de código abaixo:

firebase-signout-result
Logout do Firebase com React Native

Conclusão

Neste tutorial, aprendemos como configurar o Login do Google, além de armazenar um token de acesso, aproveitando o Firebase em nosso projeto React Native.

Primeiro, criamos o projeto do React Native com todos os componentes e configurações de funções necessários. Em seguida, aprendemos como configurar o Google Sign In e o Firebase para as plataformas do Android e do iOS. Por fim, configuramos o Firebase na aplicação do React Native usando um pacote do Firebase e exibimos os dados do usuário junto com o botão de logout.

Você pode baixar o código-fonte completo deste tutorial no Github.

A melhor parte é que o Firebase e o Google Auth são compatíveis com todas as linguagens de desenvolvimento para dispositivos móveis, tais como Flutter, Swift ou Kotlin. As etapas de configuração e a abordagem arquitetural são exatamente as mesmas.

Próximos passos

Agora que você aprendeu sobre como configurar o Login do Google com Firebase em aplicações do React Native, aqui estão alguns outros tópicos nos quais você pode dar uma olhada:

Se você gostou deste tutorial do React Native, dê uma estrela no repositório do Github e compartilhe-o com sua comunidade. Você pode conferir ainda mais projetos do React Native gratuitos na Instamobile. Obrigado!