Original article: How to Set Up Google Login in React Native & Firebase

El inicio de sesión de Google es una excelente función de inicio de sesión para ofrecer a los usuarios de su aplicación. Les facilita crear una cuenta e iniciar sesión.

Y lo que es aún mejor, Firebase hace que sea extremadamente fácil para los desarrolladores agregar soporte para el inicio de sesión de Google. Pero configurar el entorno de React Native puede crear algunos desafíos, que se cubren completamente en este tutorial.

React Native y Firebase SDK hacen que la implementación del inicio de sesión de Google sea bastante sencilla. Construyamos una aplicación simple que solo tenga un botón de inicio de sesión de Google. Una vez que el usuario inicie sesión con éxito en Google, mostraremos la información del usuario recuperada de su cuenta de Google, así como un botón de cierre de sesión.

También puede agregar Facebook Login a su aplicación si está interesado en brindar aún más opciones de inicio de sesión a sus usuarios. Puede consultar esta guía para iniciar sesión con Facebook en React Native con Firebase si desea obtener más información sobre cómo configurar el inicio de sesión con Facebook.

¿Por qué usar un botón de inicio de sesión de Google en aplicaciones móviles?

  1. El uso de Google u otros terceros puede hacer que su proceso de autenticación sea sencillo y amigable. Los usuarios no tienen que perder tiempo en el proceso de registro, lo que mejorará enormemente sus tasas de registro y retención.
  2. Es segura y protegida.
  3. Los usuarios confían más en Google o Facebook que en un sitio o aplicación desconocidos en Internet.
  4. Proporciona una buena experiencia de usuario. Como usuario, tenemos poca paciencia para cualquier acción o trabajo que necesitemos hacer, especialmente en una aplicación bastante desconocida que estamos probando por primera vez.

Sin más preámbulos, pasemos directamente a la parte de desarrollo de aplicaciones de este tutorial.

Configuración del proyecto Firebase

Vaya a Firebase Console y cree un proyecto de Firebase:

create new firebase project
create new firebase project

Aquí, necesitaremos configurar el nombre del proyecto Firebase y el identificador de la aplicación, así que primero creemos la aplicación React Native.

Creando el proyecto React Native

Primero, necesitamos crear un proyecto React Native usando el siguiente comando:

react-native init instamobile-google-login-demo

Aquí, hemos dado el nombre del proyecto como instamobile-google-login-demo. Ahora, necesitamos instalar el paquete react-native-google-signin usando el siguiente comando:

yarn add react-native-google-singin

El paquete react-native-google-signin se utiliza para implementar las funciones de autenticación de Google en la aplicación React Native. Ahora, necesitamos importar los módulos y componentes necesarios del paquete respectivo como se muestra en el fragmento de código a continuación:

import {
GoogleSignin,
GoogleSigninButton,
statusCodes,
} from 'react-native-google-signin';
import google sign-in component

A continuación, necesitamos crear los estados para manejar el estado de autenticación y la información del usuario. Para eso usamos el módulo useState como se muestra en el fragmento de código a continuación:

const [loggedIn, setloggedIn] = useState(false);
const [userInfo, setuserInfo] = useState([]);
add state

Ahora, necesitamos crear una función de inicio de sesión para manejar la autenticación como se muestra en el fragmento de código a continuación:

_signIn = async () => {
  try {
    await GoogleSignin.hasPlayServices();
    const {accessToken, idToken} = await GoogleSignin.signIn();
    setloggedIn(true);
  } catch (error) {
    if (error.code === statusCodes.SIGN_IN_CANCELLED) {
      // user cancelled the login flow
      alert('Cancel');
    } else if (error.code === statusCodes.IN_PROGRESS) {
      alert('Signin in progress');
      // operation (f.e. sign in) is in progress already
    } else if (error.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE) {
      alert('PLAY_SERVICES_NOT_AVAILABLE');
      // play services not available or outdated
    } else {
      // some other error happened
    }
  }
};
add google sign-in function

A continuación, debemos inicializar la configuración del objeto de inicio de sesión de Google aprovechando la función useEffect :

useEffect(() => {
   GoogleSignin.configure({
     scopes: ['email'], // what API you want to access on behalf of the user, default is email and profile
     webClientId:
       '418977770929-g9ou7r9eva1u78a3anassxxxxxxx.apps.googleusercontent.com', // client ID of type WEB for your server (needed to verify user ID and offline access)
     offlineAccess: true, // if you want to access Google API on behalf of the user FROM YOUR SERVER
   });
 }, []);

Por último, necesitamos una función que maneje la acción de cierre de sesión. Para eso, vamos a implementar el método signOut como se muestra en el fragmento de código a continuación:

signOut = async () => {
    try {
      await GoogleSignin.revokeAccess();
      await GoogleSignin.signOut();
      setloggedIn(false);
      setuserInfo([]);
    } catch (error) {
      console.error(error);
    }
  };
add Google Sign-out function

Ahora, también necesitamos renderizar los componentes en la pantalla. Para eso, vamos a hacer uso de varios componentes como View y 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>
    </>
  );
UI code

Ahora bien, si ejecutamos nuestro proyecto en el emulador obtendremos los siguientes resultados:

google login first screen
Login with Google React Native

Bastante dulce, ¿verdad? Hemos completado la implementación (tanto de la interfaz de usuario como de la lógica empresarial) en el nivel de React Native en nuestro proyecto.

Como puede ver, tenemos un botón "Iniciar sesión con Google" que se convierte en un botón de cierre de sesión una vez que la operación de inicio de sesión se completa con éxito.

Ahora vamos a configurar el paquete de inicio de sesión de Google y la aplicación Firebase.

Configuración de los proyectos nativos de iOS y Android

Hay algunos pasos de configuración que debemos seguir antes de que el proyecto funcione por completo. En su mayoría están relacionados con el lado nativo real de la aplicación.

Para iOS

Aquí, en VSCode (o cualquier Terminal) simplemente ejecute cd ios && pod install. Luego abra el archivo .xcworkspace en Xcode (desde la carpeta ios) y asegúrese de que los Pods estén incluidos:

install google login lib in xcode
install google login lib in xcode

Para Android

1. Primero, necesitamos vincular el módulo nativo.

  • En RN >= 0.60 no debería necesitar hacer nada gracias a la vinculación automática.
  • En RN < 0.60 ejecute el enlace react-native link react-native-google-signin.

2. Actualice android/build.gradle con la siguiente configuración:

buildscript {
    ext {
        buildToolsVersion = "27.0.3"
        minSdkVersion = 16
        compileSdkVersion = 27
        targetSdkVersion = 26
        supportLibVersion = "27.1.1"
        googlePlayServicesAuthVersion = "16.0.1" // <--- use this version or newer
    }
...
    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.2' // <--- use this version or newer
        classpath 'com.google.gms:google-services:4.1.0' // <--- use this version or newer
    }
...
allprojects {
    repositories {
        mavenLocal()
        google() // <--- make sure this is included
        jcenter()
        maven {
            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
            url "$rootDir/../node_modules/react-native/android"
        }
    }
}

3. Actualiceandroid/app/build.gradle con la siguiente configuración:

...
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")) // <--- add this dependency
}

Verifique que vinculó el módulo nativo react-native link  – pero solo si usaste react-native link!

En android/settings.gradle  deberíamos tener las siguientes configuraciones:

...
include ':react-native-google-signin', ':app'
project(':react-native-google-signin').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/google-signin/android')
setup google login for android in setting.gradle

A continuación, en MainApplication.java ,deberíamos agregar el paquete de Google como en el siguiente fragmento de código:

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

public class MainApplication extends Application implements ReactApplication {

  ......

  @Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
          new MainReactPackage(),
          new RNGoogleSigninPackage() // <-- this needs to be in the list
      );
    }
  ......

}
setup google login for android in MainApplication.java

Configuración para Firebase

Para iOS

Ahora, debemos comenzar con la configuración de Firebase. En Firebase, necesitamos configurar una aplicación en la nube de Google. Pero cuando configuramos el método de autenticación en Firebase, esto también crea una aplicación en la nube de Google.

Primero, necesitamos crear la aplicación Firebase iOS para obtener GoogleServiceinfo.plist como se muestra en la siguiente captura de pantalla:

add new firebase app name
add new firebase app name

A continuación, copiamos el archivo GoogleService-info.plist al proyecto Xcode como se muestra en la siguiente captura de pantalla:

add google service plist to xcode
add google service plist to xcode

Ahora, debemos agregar la ID de cliente invertida presente en el archivo GoogleService-info.plist a los tipos de URL, como se muestra en la siguiente captura de pantalla:

get reverse client id from xcode
get reverse client id from xcode

El siguiente paso es ir a InfoURL Types y luego completar los URL Schemes como se muestra en la siguiente captura de pantalla:

add url scheme to xcode
add url scheme to xcode

Para Android

Primero, necesitamos crear una aplicación de Android en Firebase. Para eso, necesitamos un nombre de paquete y un certificado SHA-1 de nuestra aplicación. Luego, podemos registrar la aplicación Firebase como se muestra a continuación:

create new android firebase app
create new android firebase app

Podemos obtener el nombre del paquete en MainApplication.java de nuestro proyecto como se destaca en el fragmento de código a continuación:

find out bundle name in android app
find out bundle name in android app

A continuación, podemos obtener la clave SHA-1 en el archivo Keystore. En el directorio android/app, podemos ejecutar el comando:

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

Luego, aparecerá la clave SHA-1, como se muestra en la siguiente captura de pantalla:

generate sha1 for register android app in firebase
generate sha1 for register android app in firebase

Después de crear con éxito la aplicación de configuración de Firebase, debemos descargar el archivo google-services.json y copiarlo en el directorio, como se muestra en la siguiente captura de pantalla:

add google service json to android app folder
add google service json to android app folder

Ahora, el paso final es configurar un componente de inicio de sesión de Google en Android.

Instalación del paquete React Native Firebase

Para instalar el paquete react-native-firebase versión 6, debemos ejecutar el siguiente comando en el símbolo del sistema de nuestro proyecto:

# Using npm 
npm install --save @react-native-firebase/app 
# Using Yarn 
yarn add @react-native-firebase/app
install react native firebase core component

El módulo @react-native-firebase/app debe instalarse antes de usar cualquier otro servicio de Firebase.

Para iOS

Ya tenemos GoogleService-Info.plist agregado a Xcode. Lo que queda es permitir que Firebase en iOS use las credenciales. El SDK de Firebase iOS debe configurarse durante la fase de arranque de su aplicación.

Para hacer esto, debemos abrir nuestro archivo /ios/{projectName}/AppDelegate.m , y agregar lo siguiente:

En la parte superior del archivo, necesitamos importar el SDK de Firebase:

#import <Firebase.h>
include Firebase

Dentro de su método didFinishLaunchingWithOptions existente, debemos agregar lo siguiente en la parte superior del método:

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

Finalmente, debemos ejecutar el siguiente comando para finalizar la instalación del paquete CocoaPods:

cd ios ; pod install
CocoaPods install

Eso es todo. Ahora hemos completado la instalación del paquete principal de Firebase en iOS

Para Android

Necesitamos configurar Firebase con credenciales de Android. Para permitir que Firebase en Android use las credenciales, el complemento de servicios de Google debe estar habilitado en el proyecto. Esto requiere la modificación de dos archivos en el directorio de Android.

Primero, agregue el complemento de servicios de Google como una dependencia dentro de su archivo android/build.gradle:

buildscript {
  dependencies {
    // ... other dependencies
    classpath 'com.google.gms:google-services:4.2.0'
    // Add me --- /\
  }
}
Lastly, execute the plugin by adding the following to the very bottom of your /android/app/build.gradle file:

apply plugin: 'com.google.gms.google-services'
add google service

Módulo de autenticación React Native Firebase

Una vez completada la instalación, debemos configurar el paquete principal de Firebase. A continuación, necesitamos instalar el módulo secundario para la autenticación. Para eso, necesitamos abrir una terminal y ejecutar el siguiente comando:

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

Para iOS

Solo necesitamos instalar los pods nuevamente en el símbolo del sistema:

cd ios/ && pod install
install cacao pod

Para Android

Puede seguir las instrucciones en la documentación oficial que solo se requiere si está utilizando React Native <= 0.59 o necesita integrar manualmente la biblioteca.

Activar el inicio de sesión de Google en Firebase

Tenemos que ir a la consola de Firebase. Luego, en la sección Autenticación, debemos hacer clic en Google como se muestra en la siguiente captura de pantalla:

authentication method in firebase
authentication method in firebase

A continuación, debemos habilitar la configuración con la siguiente configuración y guardar la configuración como se muestra en la captura de pantalla a continuación:

activate project support email
activate project support email

En App.js, necesitamos importar la autenticación del paquete Firebase como se muestra en el fragmento de código a continuación:

import auth from '@react-native-firebase/auth';
import firebase auth package

A continuación, debemos integrar la configuración de autenticación a la función de sign-in. Después de un inicio de sesión exitoso, almacenamos accessToken y idToken en Firebase. Ahora, podemos intentar iniciar sesión con Google en nuestra aplicación de demostración React Native.

_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) {
Firebase Login function

Ahora hemos completado con éxito la integración de Google Sign-in en nuestra aplicación React Native:

result of google login with react native
result of google login with react native

Podemos ver nuevos datos que se agregan a Firebase Console:

firebase authentication console
firebase authentication console

Seguimiento del estado del usuario

Para verificar el estado de inicio de sesión del usuario, usamos Firebase Auth. Para eso, necesitamos agregar el método onAuthStateChanged a useEffect para que se ejecute en cada llamada de evento componentDidMount.

Además, debemos pasar una devolución de llamada a la función denominada onAuthStateChanged como argumento, como se muestra en el fragmento de código a continuación:

useEffect(() => {
    .............
    const subscriber = auth().onAuthStateChanged(onAuthStateChanged);
    return subscriber; // unsubscribe on unmount
  }, []);
subscribe to auth state

En la función onAuthStateChanged, manejamos los datos del estado local como se muestra en el fragmento de código a continuación:

function onAuthStateChanged(user) {
    setUser(user);
    console.log(user);
    if (user) setloggedIn(true);
  }
set user data

Ahora, necesitamos almacenar los datos de usuario para el estado. Luego, intente mostrar los datos del usuario después de un inicio de sesión exitoso. Para eso, necesitamos usar la siguiente pieza 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>
)}
code for display user info

Obtendremos el siguiente resultado en nuestro simulador:

result on show auth username
logout firebase auth

Cerrar sesión de Firebase

Para cerrar sesión, debemos eliminar todas las credenciales del usuario y revocar el token de inicio de sesión de Google.

Primero, debemos esperar a que el módulo GoogleSignin revoque el acceso y cierre la sesión. Luego, llamamos al método de signOut de Firebase auth para cerrar sesión con éxito.

La implementación general del código se proporciona en el siguiente fragmento de código:

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);
    }
  };
Firebase sign-out function

Como resultado, ahora podemos realizar operaciones de cierre de sesión como se muestra en el fragmento de código a continuación:

firebase react native sign out result
firebase react native logout

Conclusion

En este tutorial, aprendimos a configurar Google Login, además de almacenar un token de acceso, aprovechando Firebase en nuestro proyecto React Native.

Primero, creamos el proyecto React Native con todos los componentes necesarios y configuraciones de funciones. Luego, aprendimos cómo configurar Google Sign In y Firebase para las plataformas Android e iOS. Finalmente, configuramos Firebase en la aplicación React Native usando un paquete de Firebase y mostramos los datos del usuario junto con el botón de cierre de sesión.

Puede descargar el código fuente completo de este tutorial desde Github.

La mejor parte es que Firebase y Google Auth son compatibles con todos los lenguajes de desarrollo móvil, como Flutter, Swift o Kotlin. Los pasos de configuración y el enfoque arquitectónico son exactamente los mismos.

Si te gustó este tutorial de React Native, dame una estrella en el repositorio de Github y compártelo con tu comunidad. Puede consultar aún más proyectos React Native gratuitos en Instamobile. ¡Salud!