Implementación de Google Analytics para Firebase en Android Webview

1. Introducción

Última actualización: 2022-02-03

8cef5cc6581b73d0.png

lo que aprenderás

  • Cómo crear una vista web muy sencilla en Android
  • Cómo enviar eventos de Webview a Firebase

Lo que necesitarás

  • Proyecto Firebase con SDK de Analytics implementado
  • Android Studio versión 4.2+.
  • Un emulador de Android con Android 5.0+.
  • Familiaridad con el lenguaje de programación Java.
  • Familiaridad con el lenguaje de programación Javascript.

2. Cree una vista web sencilla en Android

Agregar Webview en el diseño de la actividad

Para agregar un WebView a su aplicación en el diseño, agregue el siguiente código al archivo XML de diseño de su actividad:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context=".WebActivity"
>
  <WebView
    android:id="@+id/webview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
  />
</androidx.constraintlayout.widget.ConstraintLayout>;

Agregar una vista web en onCreate()

Para cargar una página web en WebView, utilice loadUrl(). La vista web debe crearse en la actividad negra. Por ejemplo, implementaré esto en el método onCreate:

public class WebActivity extends AppCompatActivity {
 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web);
        // Navigate to site
        myWebView.loadUrl("https://bittererhu.glitch.me");
 }
}

Sin embargo, antes de que esto funcione, su aplicación debe tener acceso a Internet. Para obtener acceso a Internet, solicite el permiso de INTERNET en su archivo de manifiesto. Por ejemplo:

<uses-permission android:name="android.permission.INTERNET" />

Eso es todo lo que necesita para un WebView básico que muestra una página web.

Usando Javascript en vistas web

Si la página web que planea cargar en su WebView usa JavaScript, debe habilitar JavaScript para su WebView. Una vez que JavaScript esté habilitado, también puede crear interfaces entre el código de su aplicación y su código JavaScript.

JavaScript está deshabilitado en WebView de forma predeterminada. Puede habilitarlo a través de WebSettings adjunto a su WebView. Puede recuperar WebSettings con getSettings() y luego habilitar JavaScript con setJavaScriptEnabled().

Por ejemplo:

WebView myWebView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);

Actividad actualizada:

public class WebActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web);
        WebView myWebView = (WebView) findViewById(R.id.webview);
        if(myWebView != null) {
            WebSettings webSettings = myWebView.getSettings();
            webSettings.setJavaScriptEnabled(true);
        }
        // Navigate to site
        myWebView.loadUrl("https://bittererhu.glitch.me");
  }
}

be627fcc51a6179f.png

3. Implementación de la interfaz puente de Javascript

Controlador de Javacript

El primer paso para utilizar Google Analytics en un WebView es crear funciones de JavaScript para reenviar eventos y propiedades del usuario al código nativo. El siguiente ejemplo muestra cómo hacer esto de una manera que sea compatible con el código nativo de Android y Apple:

En este ejemplo, creé un archivo Javascript llamado script.js que incluye lo siguiente:

function logEvent(name, params) {
  if (!name) {
    return;
  }
  if (window.AnalyticsWebInterface) {
    // Call Android interface
    window.AnalyticsWebInterface.logEvent(name, JSON.stringify(params));
  } else if (window.webkit
      && window.webkit.messageHandlers
      && window.webkit.messageHandlers.firebase) {
    // Call iOS interface
    var message = {
      command: 'logEvent',
      name: name,
      parameters: params
    };
    window.webkit.messageHandlers.firebase.postMessage(message);
  } else {
    // No Android or iOS interface found
    console.log("No native APIs found.");
  }
}


function setUserProperty(name, value) {
  if (!name || !value) {
    return;
  }

  if (window.AnalyticsWebInterface) {
    // Call Android interface
    window.AnalyticsWebInterface.setUserProperty(name, value);
  } else if (window.webkit
      && window.webkit.messageHandlers
      && window.webkit.messageHandlers.firebase) {
    // Call iOS interface
    var message = {
      command: 'setUserProperty',
      name: name,
      value: value
   };
    window.webkit.messageHandlers.firebase.postMessage(message);
  } else {
    // No Android or iOS interface found
    console.log("No native APIs found.");
  }
}

Interfaz nativa

Para invocar código nativo de Android desde JavaScript, implemente una clase con métodos marcados como @JavaScriptInterface : en el siguiente ejemplo, creé una nueva clase Java llamada: AnalyticsWebInterfcae.java:

public class AnalyticsWebInterface {

    public static final String TAG = "AnalyticsWebInterface";
    private FirebaseAnalytics mAnalytics;

    public AnalyticsWebInterface(Context context) {
        mAnalytics = FirebaseAnalytics.getInstance(context);
    }

    @JavascriptInterface
    public void logEvent(String name, String jsonParams) {
        LOGD("logEvent:" + name);
        mAnalytics.logEvent(name, bundleFromJson(jsonParams));
    }

    @JavascriptInterface
    public void setUserProperty(String name, String value) {
        LOGD("setUserProperty:" + name);
        mAnalytics.setUserProperty(name, value);
    }

    private void LOGD(String message) {
        // Only log on debug builds, for privacy
        if (BuildConfig.DEBUG) {
            Log.d(TAG, message);
        }
    }

    private Bundle bundleFromJson(String json) {
        // ...
    }
}

Once you have created the native interface, register it with your WebView so that it is visible to JavaScript code running in the WebView:

// Only add the JavaScriptInterface on API version JELLY_BEAN_MR1 and above, due to
// security concerns, see link below for more information:
// https://developer.android.com/reference/android/webkit/WebView.html#addJavascriptInterface(java.lang.Object,%20java.lang.String)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
    mWebView.addJavascriptInterface(
            new AnalyticsWebInterface(this), AnalyticsWebInterface.TAG);
} else {
    Log.w(TAG, "Not adding JavaScriptInterface, API Version: " + Build.VERSION.SDK_INT);
}

Código final:

// [START analytics_web_interface]
public class AnalyticsWebInterface {

    public static final String TAG = "AnalyticsWebInterface";
    private FirebaseAnalytics mAnalytics;

    public AnalyticsWebInterface(Context context) {
        mAnalytics = FirebaseAnalytics.getInstance(context);
    }
    @JavascriptInterface
    public void logEvent(String name, String jsonParams) {
        LOGD("logEvent:" + name);
        mAnalytics.logEvent(name, bundleFromJson(jsonParams));
    }
    @JavascriptInterface
    public void setUserProperty(String name, String value) {
        LOGD("setUserProperty:" + name);
        mAnalytics.setUserProperty(name, value);
    }
    private void LOGD(String message) {
        // Only log on debug builds, for privacy
        if (BuildConfig.DEBUG) {
            Log.d(TAG, message);
        }
    }
    private Bundle bundleFromJson(String json) {
        // [START_EXCLUDE]
        if (TextUtils.isEmpty(json)) {
            return new Bundle();
        }

        Bundle result = new Bundle();
        try {
            JSONObject jsonObject = new JSONObject(json);
            Iterator<String> keys = jsonObject.keys();

            while (keys.hasNext()) {
                String key = keys.next();
                Object value = jsonObject.get(key);
                if (value instanceof String) {
                    result.putString(key, (String) value);
                } else if (value instanceof Integer) {
                    result.putInt(key, (Integer) value);
                } else if (value instanceof Double) {
                    result.putDouble(key, (Double) value);
                } else {
                    Log.w(TAG, "Value for key " + key + " not one of [String, Integer, Double]");
                }
            }
        } catch (JSONException e) {
            Log.w(TAG, "Failed to parse JSON, returning empty Bundle.", e);
            return new Bundle();
        }
        return result;
        // [END_EXCLUDE]
    }

Ahora ha configurado la interfaz Javascript y está listo para comenzar a enviar eventos analíticos.

4. Envío de Eventos a través de la interfaz

Como puede ver aquí, mi vista web es muy simple, tiene tres botones, dos que registrarán un evento y el otro que registrará una propiedad del usuario:

7a00ed1192151b19.png

Una vez que haga clic en los botones, llamará a mi archivo "script.js" y ejecutará el siguiente código:

document.getElementById("event1").addEventListener("click", function() {
    console.log("event1");
    logEvent("event1", { foo: "bar", baz: 123 });
});

document.getElementById("event2").addEventListener("click", function() {
  console.log("event2");
    logEvent("event2", { size: 123.456 });
});

document.getElementById("userprop").addEventListener("click", function() {
    console.log("userprop");
    setUserProperty("userprop", "custom_value");
});

Archivo script.js final:

/* If you're feeling fancy you can add interactivity 
    to your site with Javascript */

// prints "hi" in the browser's dev tools console
console.log("hi");

// [START log_event]
function logEvent(name, params) {
  if (!name) {
    return;
  }

  if (window.AnalyticsWebInterface) {
    // Call Android interface
    window.AnalyticsWebInterface.logEvent(name, JSON.stringify(params));
  } else if (window.webkit
      && window.webkit.messageHandlers
      && window.webkit.messageHandlers.firebase) {
    // Call iOS interface
    var message = {
      command: 'logEvent',
      name: name,
      parameters: params
    };
    window.webkit.messageHandlers.firebase.postMessage(message);
  } else {
    // No Android or iOS interface found
    console.log("No native APIs found.");
  }
}
// [END log_event]

// [START set_user_property]
function setUserProperty(name, value) {
  if (!name || !value) {
    return;
  }

  if (window.AnalyticsWebInterface) {
    // Call Android interface
    window.AnalyticsWebInterface.setUserProperty(name, value);
  } else if (window.webkit
      && window.webkit.messageHandlers
      && window.webkit.messageHandlers.firebase) {
    // Call iOS interface
    var message = {
      command: 'setUserProperty',
      name: name,
      value: value
   };
    window.webkit.messageHandlers.firebase.postMessage(message);
  } else {
    // No Android or iOS interface found
    console.log("No native APIs found.");
  }
}
// [END set_user_property]

document.getElementById("event1").addEventListener("click", function() {
    console.log("event1");
    logEvent("event1", { foo: "bar", baz: 123 });
});

document.getElementById("event2").addEventListener("click", function() {
  console.log("event2");
    logEvent("event2", { size: 123.456 });
});

document.getElementById("userprop").addEventListener("click", function() {
    console.log("userprop");
    setUserProperty("userprop", "custom_value");
});

Esta es la forma básica de enviar eventos a Analytics.

5. Depurar eventos de Webview en Firebase

La depuración de eventos de Webview en tu aplicación funciona de la misma manera que la depuración de cualquier parte nativa de tu SDK:

Para habilitar el modo de depuración, utilice los siguientes comandos en su consola de Android Studio:

adb shell setprop debug.firebase.analytics.app package_name

Una vez hecho esto, puedes probar y ver cómo tus eventos de Webview cobran vida:

d230debf4ccfddad.png

6. Felicitaciones

Felicitaciones, ha creado con éxito una vista web en su aplicación de Android. Puede enviar y medir eventos clave del embudo en su aplicación que tienen lugar a través de vistas web. Para aprovechar esto al máximo, también sugerimos conectarse a Google Ads e importar estos eventos como conversiones.

has aprendido

  • Cómo enviar eventos de Webview a Firebase
  • Cómo configurar y crear una vista web sencilla en Android

Documentos de referencia