Send Firebase WEB events from the SERVER using GA4 Measurement Protocol
On
The problem
The Analytics JS SDK (v9) is a wrapper and separate SDK from what Google is referring to as "The Google Tag" (gtag). The problem with the Firebase SDK is that it offers little to zero benefits, yet still requires cross site pixel drop, with no current support of GTM Server, ignoring transport_url
or being able to load tags with your own endpoint, causing googletagmanager.com
Example server side Google Tag
<script async src="https://metrics.romanch.uk/gtag/js?id=G-24Q5EDRSF7" data-turbo-track="reload"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-24Q5EDRSF7', {
'transport_url': 'https://metrics.romanch.uk'
});
</script>
To use Measurement Protocol (Google Analytics 4) for Firebase, it requires both firebase_app_id
and app_instance_id
. The app_instance_id
is generated on device and it's up to you to manage handing the token back to your S2S environment. In iOS this was trivial with Analytics.appInstanceID()
in a standard REST environment. It has not been so obvious in the browser, but it is possible.
<script type="module">
import { firebase } from "application";
import { getInstallations, getId } from "firebase/installations";
const installations = getInstallations(firebase)
const installationId = await getId(installations);
console.log(installationId);
// You still have to get this back to the server, pass cookie, hidden input + stimulus post
document.cookie = "iid=" + installationId + "; SameSite=Lax; Secure";
</script>
Full context
# config/importmap.rb
pin "application", preload: true
pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true
pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
pin_all_from "app/javascript/controllers", under: "controllers"
pin "firebase/app", to: "https://www.gstatic.com/firebasejs/9.9.3/firebase-app.js"
pin "firebase/installations", to: "https://www.gstatic.com/firebasejs/9.9.3/firebase-installations.js"
// app/javascript/application.js
import "@hotwired/turbo-rails"
import "controllers"
import * as bootstrap from 'bootstrap';
fontAwesomeInit()
const firebase = firebaseInit()
export { bootstrap, firebase };
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
private
def iid() = cookies[:iid].presence
end