Implementar o Google Analytics para Firebase no Android WebView

Implementar o Google Analytics para Firebase no Android WebView

Sobre este codelab

subjectÚltimo fev. 8, 2022 atualizado
account_circleEscrito por Erhu Akpobaro

1. Introdução

Última atualização:03/02/2022

8cef5cc6581b73d0.png

O que você aprenderá

  • Como criar uma Webview muito simples no Android
  • Como enviar eventos da Webview para o Firebase

O que é necessário

  • Projeto do Firebase com o SDK do Google Analytics implementado
  • Android Studio versão 4.2 ou mais recente.
  • Um Android Emulator com Android 5.0 ou mais recente.
  • Noções básicas da linguagem de programação Java.
  • Noções básicas da linguagem de programação JavaScript.

2. Criar uma Webview da Web simples no Android

Como adicionar uma WebView no layout da atividade

Para adicionar uma WebView ao app no layout, adicione o seguinte código ao arquivo XML do layout da atividade:

<?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>;

Como adicionar uma WebView em onCreate()

Para carregar uma página da Web na WebView, use loadUrl(). A WebView precisa ser criada na atividade em tela preta. Por exemplo, vou implementar isso no 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");
 }
}

No entanto, antes que isso funcione, seu app precisa ter acesso à Internet. Para ter acesso à Internet, solicite a permissão INTERNET no arquivo de manifesto. Exemplo:

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

Isso é tudo que você precisa para uma WebView básica que mostra uma página da Web.

Como usar o JavaScript em Webviews

Se a página da Web que você pretende carregar na WebView usa JavaScript, você precisa ativar o JavaScript para sua WebView. Depois que o JavaScript for ativado, você também poderá criar interfaces entre o código do app e o código JavaScript.

Por padrão, o JavaScript fica desativado em uma WebView. É possível ativar essa opção nas WebSettings anexadas à WebView. É possível recuperar as WebSettings com getSettings() e ativar o JavaScript com setJavaScriptEnabled().

Exemplo:

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

Atividade atualizada :

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. Como implementar a interface de ponte do JavaScript

Gerenciador de Javacript

A primeira etapa para usar o Google Analytics em um WebView é criar funções JavaScript para transformar eventos e propriedades do usuário em código nativo. O exemplo a seguir mostra como fazer isso de modo compatível com o código nativo da Apple e do Android:

Neste exemplo, criei um arquivo JavaScript chamado script.js que inclui o seguinte :

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.");
  }
}

Interface nativa

Para chamar o código nativo do Android do JavaScript, implemente uma classe com os métodos marcados com @JavaScriptInterface: no exemplo abaixo, criei uma nova classe Java chamada 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]
    }

Agora que você configurou a interface do JavaScript , está tudo pronto para começar a enviar eventos de análise.

4. Como enviar eventos pela interface

Como você pode ver, minha Webview é muito simples, tem três botões, dois que registram um evento e outro que registra uma propriedade do usuário :

7a00ed1192151b19.png

Quando clico nos botões, ele chama meu arquivo "script.js" e executa o seguinte 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");
});

Arquivo 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");
});

Essa é a maneira básica de enviar eventos para o Google Analytics.

5. Depurar eventos da WebView no Firebase

A depuração de eventos da Webview no app funciona da mesma forma que a depuração de qualquer parte nativa do SDK :

Para ativar o modo de depuração, use os seguintes comandos no console do Android Studio:

adb shell setprop debug.firebase.analytics.app package_name

Depois disso, você pode testar e conferir seus eventos da Webview :

d230debf4ccfddad.png

6. Parabéns

Parabéns! Você criou uma WebView no seu app Android. É possível enviar e medir os principais eventos do funil no app que ocorrem por WebViews. Para aproveitar ao máximo essa oportunidade, sugerimos que você se conecte ao Google Ads e importe esses eventos como conversões.

Você aprendeu

  • Como enviar eventos da Webview para o Firebase
  • Como configurar e criar uma Webview simples no Android

Documentos de referência