Integración con React Native / Expo

Integración del SDK de EMMA en una app React Native / Expo con VSCode, usando EAS Build y ajustes en código nativo Android, en entorno Windows 10.

Requisitos previos

ComponenteRequerimiento
Sistema OperativoWindows 10 o superior
Editor de CódigoVisual Studio Code (última versión)
Node.jsVersión: 22.13.1
Expo SDKVersión: 53.0.9
ReactVersión: 19.0.0
React NativeVersión: 0.79.2
React DOMVersión: 19.0.0
React Native WebVersión: 0.20.0
Expo RouterVersión: 5.0.6
EAS CLIVersión: 16.7.1
TypeScriptVersión: 5.8.3
Babel CoreVersión: 7.25.2
ESLintVersión: 9.25.0
ReanimatedVersión: 3.17.4
Gesture HandlerVersión: 2.24.0
React NavigationVersión: 7.1.6

Esta app fue construida con la versión 22.13.1 de Node.js y funcionó correctamente. Sin embargo, debido a la compatibilidad con EAS y el Expo SDK 53 (la versión más reciente), se recomienda utilizar Node.js en la versión ^18.18.0 o ^20.9.0. Además, si alguna librería nativa que necesitas no es compatible aún con React Native 0.73, deberías considerar utilizar una versión anterior del SDK de Expo. Para más información de cambios y actualizaciones visita el ChangeLog de Expo.

Crear proyecto con Expo usanso flujo Bare y compilando en local y EAS

  • Crear proyecto

    Crear proyecto con plantilla Bare de Expo:

    bash
    npx create-expo-app Example --template expo-template-bare-minimum
    
  • Instalar la CLI de EAS

    Instala la herramienta de línea de comandos de EAS globalmente:

    bash
    npm install -g eas-cli
    
  • Iniciar sesión en tu cuenta de Expo

    Una vez instalada la CLI, inicia sesión en tu cuenta de Expo, o si aún no tienes una cuenta accede a este link.

    bash
    eas login
    
  • Prebuild del proyecto

    Usa el siguiente comando:

    bash
    npx expo prebuild
    
  • Con el comando anterior tendrás acceso a los archivos nativos. En este caso, la integración se realizó únicamente para sistemas Android, debido a la limitación del sistema operativo Windows, que no es compatible con iOS.

Pasos para la Integración del SDK de EMMA.

  • Incluir el repositorio en tu proyecto

    Abrir los ficheros nativos y añadir el repositorio de EMMA

    C:expo\example-proyect\android\build.gradle
        maven { url 'https://repo.emma.io/emma' }
    
    Paso 1
  • Incluir dependencia de EMMA

    Abrir los ficheros nativos y añadir la dependencia de EMMA

    C:expo\example-proyect\android\app\build.gradle
    implementation 'io.emma:eMMaSDK:4.15.5'
    
    Paso 1
  • Consulta versiones del SDK EMMA aquí

  • Obtener el Session Key de EMMA

    Para comenzar a utilizar EMMA, puedes guiarte con este enlace: y así crear una cuenta; Una vez registrada, configura tu cuenta siguiendo los pasos indicados aquí y luego solicita tus credenciales: la EMMA Key y la API Key, necesarias para habilitar la integración, aquí puedes ver la guía.

    Paso 3
  • Inicializar la librería

    En tu clase Application, añade lo siguiente:

    C:expo\example-proyect\android\app\src\main\java\com\emmaexample\MainApplication.kt
    
    import android.app.Application
    import io.emma.android.EMMA
    
    class MainApplication : Application(), ReactApplication {
    private fun initializeEMMA() {
    val configuration = EMMA.Configuration.Builder(this)
    .setSessionKey("TU_SESION_KEY")
    .setDebugActive(BuildConfig.DEBUG)
    .build()
    
        EMMA.getInstance().startSession(configuration)
    }
    
    }
    
    
  • Recuerda habilitar esta función en tu archivo build.gradle.kts(:app) .
    build.gradle.kts(:app)
    buildFeatures {
        buildConfig = true
    }
    
    Paso 8
    {" "}

    Omitir este paso podría generar un error de la clase BuildConfig.

    Paso 7
  • Compilar a nivel local para verificar inicialización de libreria

    Para compilar localmente, debes acceder al directorio de Android desde la terminal e ingresar el siguiente comando. Esto compilará el proyecto y generará un archivo APK o AAB para instalación local. Además, iniciará el servidor Metro, encargado de servir el código JavaScript.

    bush
    npx expo run:android
    
    
  • En esta etapa del desarrollo, se recomienda realizar pruebas de manera local para agilizar el proceso. Aunque también es posible compilar usando EAS, este método suele requerir mucho más tiempo.

  • Verificar en la plataforma de EMMA

    Al configurar el SDK en la app, es importante verificar en la plataforma de EMMA (dashboard) que los usuarios estén siendo registrados como activos. Esto confirma que la integración del SDK fue exitosa y que la app está enviando correctamente los eventos de inicio de sesión e instalación.

    Paso 10

Pasos para la Integración Notificaciones Push.

  • Generar clave privada JSON

    Genera un archivo JSON de clave privada entrando en la configuración de tu proyecto de Firebase , Cuentas de servicio, y generar nueva clave privada.

    Clave privada
  • Configurar la plataforma EMMA

    Además debes configurar la plataforma EMMA con ese archivo JSON de la siguiente manera; Entra al menu del borde superior y accede a preferencias app, has click en Selecciona un fichero JSON.

    Clave privada json
  • Integrar FCM en tu Service

    Hay que añadir el siguiente service al AndroidManifest.xml:

    android\app\src\main\AndroidManifest.xml
    <service
    android:name="io.emma.android.push.EMMAFcmMessagingService"
    android:enabled="true"
    android:exported="false">
    <intent-filter>
    <action android:name="com.google.firebase.MESSAGING_EVENT"/>
    </intent-filter>
    </service>
    
    Service push
  • Configurar dependencias de Google Services nivel proyect

    Agrega el classpath en el archivo de Gradle build.gradle.kts a nivel de proyecto: Aquí más información sobre integración de Firebase

    settings.gradle.kts(:project)
    
    classpath 'com.google.gms:google-services:4.4.2'
    
    
  • Configurar dependencias de Google Services nivel app

    Agrega el complemento de los servicios de Google en el archivo de Gradle build.gradle.kts a nivel de app.

    \android\app\build.gradle
    
    apply plugin: "com.google.gms.google-services"
    

    Agrega los SDK de Firebase a tu app en el archivo Gradle build.gradle.kts a nivel de app, agrega las dependencias de los productos de Firebase que quieras usar en tu app. Es recomendable que uses la Firebase Android BoM para controlar las versiones de las bibliotecas.

    settings.gradle.kts(:app)
    
    implementation platform('com.google.firebase:firebase-bom:33.15.0')
    
    
  • Iniciando el sistema de push

    Inicia el sistema de push debajo del inicio de sesión en Application, esta anotación usa un icono por defecto se puede personalizar. Debes anotar el siguiente código:

    android\app\src\main\java\com\emmaexpotest\MainApplication.kt
    
    val pushOptions = EMMAPushOptions.Builder(MainActivity::class.java, R.drawable.ic_notification)
        .setNotificationColor(ContextCompat.getColor(this, R.color.push_color))
        .setNotificationChannelName("Canal EMMA")
        .build()
    
        EMMA.getInstance().startPushSystem(pushOptions)
    

    Desde Android 13, para recibir notificaciones es necesario solicitar un permiso al usuario. Para ello, EMMA ha añadido un método al SDK disponible en la versión 4.12 o superiores. (En mi caso uso API 29), por lo tanto, no lo implementaré, este método tiene que ser llamado en un Activity.

  • Añadir el método onNewIntent()

    Añadir el método onNewIntent() llamando a EMMA.onNewNotification(), que verificará si el usuario ha recibido una notificación cuando la app está abierta.

    Kotlin
    override fun onNewIntent(intent: Intent?) {
      super.onNewIntent(intent)
      intent?.let {
        // Correct EMMA notification handling
        EMMA.getInstance().onNewNotification(it, true)
        handleIntent(it)
      }
    }
    
  • Crear notificación push en plataforma de Emma

    Puedes seguir este tutorial para crear notificaciones push desde EMMA.

    Service push

Pasos para la Integración de deeplink.

  • Configurar AndroidManifest.xml

    Agregar filtros de intent y servicios necesarios para que el sistema Android y EMMA puedan interceptar deeplinks y notificaciones push.

    \android\app\src\main\AndroidManifest.xml
    
    <intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="miApp" android:host="notification" />
    </intent-filter>
    
    

    Permite que Android abra MainActivity cuando un link como miApp://notification sea pulsado.

    \android\app\src\main\AndroidManifest.xml
    
    <meta-data
    android:name="io.emma.DEEPLINK_OPEN_ACTIVITY"
    android:value="com.emmaexpotest.MainActivity" />
    
    

    Configurar EMMADeepLinkActivity

  • Configurar MainActivity para capturar deeplinks

    android\app\src\main\java\com\emmaexpotest\MainActivity.kt
    
    EMMA.getInstance().checkForRichPushUrl()
    
    

    Para verificar si la app se abrió desde una notificación con deeplink mientras estaba cerrada.

    android\app\src\main\java\com\emmaexpotest\MainActivity.kt
    
    EMMA.getInstance().onNewNotification(intent, true)
    
    

    Para manejar notificaciones push mientras la app está abierta.

  • Configurar la app React Native (JS/TS) para recibir el deeplink

    example\App.js
    
    Linking.getInitialURL().then((url) => { handleURL(url); });
    
    
    

    Captura deeplink mientras estaba cerrada.

    example\App.js
    
    Linking.getInitialURL().then((url) => { handleURL(url); });
    
    

    En handleURL(url), verificar si el deeplink es miApp://notification y navegar automáticamente a la pantalla deseada (Notification).

  • Crear pantalla de destino en React Native

    example\NotificationScreen.js
    
    import React from 'react';
    import { View, Text } from 'react-native';
    
    export default function NotificationScreen() {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        <Text>¡Has llegado aquí desde una notificación push!</Text>
      </View>
    );
    }
    
    

Despliegue con EAS

  • Inicializar EAS

    Esto creará eas.json y te pedirá vincular tu proyecto Expo.

    bush
    
    eas init
    
    
  • Configurar eas.json para Generar APK

    Configurar eas.json para Generar APK

    eas.json
    
    {
    "cli": {
    "version": ">= 16.7.1"
    },
    "build": {
    "development": {
      "developmentClient": true,
      "distribution": "internal"
    },
    "preview": {
      "distribution": "internal",
      "android": {
        "buildType": "apk"  
      }
    },
    "production": {
      "android": {
        "buildType": "apk",  
        "gradleCommand": ":app:assembleRelease"  
      }
    }
    }
    }
    
    
  • Configurar app.json para el Bundle

    Expo EAS no incluye por defecto el archivo Bundle que contiene el js/ts compilado por lo tanto si no se configura este json no se empaquetara en el APK.

    app.json
    {
    "expo": {
    "name": "TuApp",
    "slug": "tuapp",
    "android": {
      "package": "com.tuapp",
      "versionCode": 1,
      "bundleInProduction": true  
    }
    }
    
    
  • Generar el Bundle Manualmente (recomendado)

    Ejecuta este comando antes del build para asegurar que el bundle se incluya:

    bush
    npx react-native bundle \
    --platform android \
    --dev false \
    --entry-file index.js \
    --bundle-output android/app/src/main/assets/index.android.bundle \
    --assets-dest android/app/src/main/res
    
    
  • Construir el APK con EAS

    Ejecuta el build para producción:

    bush
    eas build --platform android --profile production
    
    
  • Descargar y Verificar el APK

    El APK estará disponible en el dashboard de EAS.