Send User ID from Google Tag Manager to Google Analytics 4
Asked Answered
B

4

8

I have set up google tag manager with my GA4 property
(NOT legacy Universal Analytics)
according to the official guide:
https://support.google.com/tagmanager/answer/6103696?hl=en&ref_topic=3441530#zippy=%2Cweb-pages

and I have figured out how to send custom/recommended events to GA4 using
dataLayer.push({}) objects, using their "event" field in triggers and tags,
based on a Universal Analytics guide
(https://www.analyticsmania.com/post/track-logins-with-google-tag-manager/),
because this appears to be a black hole in the official guide:
https://support.google.com/tagmanager/answer/9442095
only describes, briefly, the GTM-side of the story.

Same goes for sending User ID: the docs only tell
when creating a Google Analytics 4 Configuration tag:

To set a user ID, add a row to Fields to Set. 
Set the Field Name to user_id, and the Value to 
a Tag Manager Variable that returns the user ID.

and I only take the knowledge from the external UA guides
to use a Data Layer Variable that reads the user_id field from the dataLayer,
and also create a corresponding user_id User Property on Google Analytics, which in Universal Analytics used to
have related settings that don't exist anymore (https://www.analyticsmania.com/post/google-analytics-user-id-with-google-tag-manager/).

So I have deployed my GA4 Events with the user_id data layer variable
referenced in their Configuration (and it is visible on the datalayer in Debug View), created the corresponding User Property in GA, and enabled User-ID reporting.
Yet, in my real-time view, the user_id fields always get some weird "gtm.js" value
(as if my data layer variable value was replaced by the event name
from the default dataLayer.push({event:"gtm.js",user_id:"ignored value")).
What in the world is missing for my user_id field to be recognised? user_id in debug view

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

Thanks!

Borkowski answered 2/2, 2021 at 14:48 Comment(0)
B
3

So at long last it turned out, that since the configuration tag was fired by the Page View event, that happened before I pushed the user_id to the dataLayer, so it filled the non-existing value with the event name instead.

I gave the user_id event a name to create a custom event trigger, that re-triggers the configuration tag. This way the user_id-s are finally visible.

Borkowski answered 7/2, 2021 at 12:39 Comment(3)
Is that why the count was more than 1 for the user property? I also have a similar situation. The userId gets set after the pageview event. I am seeing "2" in the users column for every userId/user property. Can I ignore it?Sarnen
@Rahul well if you get distinct user id-s, than your configuration should mostly be okay. duplication could happen due to duplicate events fired, either by the application reloading, or the configuration forking somewhere. but i'm just guessing, havent rly used GA since thisBorkowski
For Single Page Apps where you refire a configuration tag to set the user_id you have to set "Ignore duplicate instances of on-page configuration (recommended)" to off to make it work, at your own risk. See belowChristianly
P
8

Thanks @bpstrngr! Was going around in circles for a while before finding your answer.

To clarify the step by step in case anyone else bumps into this;

  1. When sending userId in dataLayer add an event name:
window.dataLayer.push({
   'userId' : '{{ myUserId }}',
   'event': 'userIdSet',
})
  1. In GTM, create a Custom Event trigger that listens to that event (set event name equal to whatever event you wrote in step 1): GTM Trigger configuration print screen

  2. Add this event as a firing trigger into your tag: GTM Tag configuration print screen

Payday answered 24/5, 2021 at 14:44 Comment(0)
B
3

So at long last it turned out, that since the configuration tag was fired by the Page View event, that happened before I pushed the user_id to the dataLayer, so it filled the non-existing value with the event name instead.

I gave the user_id event a name to create a custom event trigger, that re-triggers the configuration tag. This way the user_id-s are finally visible.

Borkowski answered 7/2, 2021 at 12:39 Comment(3)
Is that why the count was more than 1 for the user property? I also have a similar situation. The userId gets set after the pageview event. I am seeing "2" in the users column for every userId/user property. Can I ignore it?Sarnen
@Rahul well if you get distinct user id-s, than your configuration should mostly be okay. duplication could happen due to duplicate events fired, either by the application reloading, or the configuration forking somewhere. but i'm just guessing, havent rly used GA since thisBorkowski
For Single Page Apps where you refire a configuration tag to set the user_id you have to set "Ignore duplicate instances of on-page configuration (recommended)" to off to make it work, at your own risk. See belowChristianly
F
0

Option 1

Addition to above mentioned Configuration Tag. For Single Page Apps I used to fire an additional GA4 Config Tag with automated Page View tracking disabled whenever the user properties change.

Very important!!!! This approach is only working if you switch of a setting in you GA4 Stream configuration labeled:

Ignore duplicate instances of on-page configuration (recommended)

That is hard to find under:

Admin

  1. Web Streams
  2. Click Your Webstream
  3. Under Google Tag: Configure Tab Setting
  4. under Tab Admin: Manage Google Tag

Because you fire the configuration tab multiple times that has to be disabled.

Read the warning of the toggle though, it has some Caveats, but so far have not encountered real problems yet.

Option 2

It seems to work to set also the user_id under User Properties although it is marked as reserved property name in the GA4 Docs.

In my case the website happly send a set_user_properties event, so I could utilize this.

That approach will of course create a new event that doesn't have much business value than setting the props.

Other event based approaches: Set user properties on every event you fire (hard to maintain) or just set them on the frequent page_view event (in which case you need to disable automatic page view tracking).

Fig answered 22/6, 2023 at 15:13 Comment(0)
S
0

That is not maybe the best option as it's not entirely following google guidelines, but it works perfectly.

So, in your initializing script we can setting our user id first, and only then calling the gtm.start / gtm.js events :

    setGTMDataLayer() {
        const { dataLayer } = window;
        if (!dataLayer) window.dataLayer = [];
        if (this.props.user) {
            window.dataLayer.push({
                userId: this.props.user.userid,
                event: 'setUserId',
            });
        }

        const gtmScript = (w, d, s, l, i) => {
            w[l] = w[l] || []; w[l].push({
                'gtm.start':
        new Date().getTime(),
                event: 'gtm.js',
            }); const f = d.getElementsByTagName(s)[0],
                j = d.createElement(s),
                dl = l !== 'dataLayer' ? `&l=${l}` : ''; j.async = true; j.src = `https://www.googletagmanager.com/gtm.js?id=${i}${dl}`; f.parentNode.insertBefore(j, f);
        };

        gtmScript(window, document, 'script', 'dataLayer', 'GTM-XXXXXX');


    }

At the end of that script, in case we are using react we can call

this.setState({ renderGTM: true });

Then, and only after the setGTMDataLayer function was exectued, we need to render the iframe. so using the created state, all needed to do is :

    renderGTM = () => this.state.renderGTM && <noscript>
        <iframe title="gtm" src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXX"
            height="0" width="0" style={{ display: 'none', visibility: 'hidden' }} />
    </noscript>
Sweven answered 13/8, 2023 at 17:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.