-
Notifications
You must be signed in to change notification settings - Fork 894
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Analytics GTAG script installed twice #2628
Comments
I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight. |
One question, are you simultaneously using Firebase Analytics ( |
I can't seem to reproduce this with that code snippet. I filled in my own project config, I substituted Is there any way you can provide a full minimal repro that includes how you call the |
here it is @hsubox76, you just need to pass correct config to AnalyticsProvider in App.js and if you enable Google Analytics Debugger Chrome extension you should see the warning: "GTAG script is installed twice." |
Thank you, I am able to reproduce it. I believe that this warning comes from the unusual way that Firebase Analytics has to wrap gtag.js, which must be downloaded by script tag injection and cannot be bundled at runtime, and additionally requires 2 download phases to avoid triggering a premature page_view event sent before the client has set up its Firebase instance data. Unfortunately it will result in that warning for now, but hopefully it does not affect actual functionality. Have you observed any bugs in functionality? |
ok, thanks for the explanation, I'm still setting up the project, but I have not observed any strange behaviour so far, apart from the console warning, I will let you know otherwise. |
I'm having this issue as well, it's resulting in mixed content warnings on my site as one of the added gtag scripts is served over http |
I have the same issue with my project. And it seems that it sends all events twice and reported as doubled on the stream view. Is there any way to avoid this? Even a temporary solution would be appreciated. (Edited 2020/04/01 12:47:00 PT) This is caused by my code. It was calling |
Anything new about that? I am having the issue as well. I am calling only |
The bug, as I reproduced it locally, did not cause any functionality problems. Earlier this week I did have some trouble seeing Analytics events reported in one of my personal projects over the last 24-48 hours, there may have been a backend service issue, and there periodically can be. For what it's worth, when I checked two days later, the missing data had been populated. If you are still seeing problems with events, can you
As for the issue described in #1, can you especially look at this comment: #2600 (comment) particularly checking for that POST call to the |
As mentioned above, this warning message is ugly but does not seem to be causing any functionality issues. If it is causing any functionality issues that you've noticed (not reporting data, reporting data incorrectly, or reporting each event twice), please see my comment 2 posts up for what action to take next. |
@hsubox76 please have a look at GoogleChromeLabs/bubblewrap#173, this is unfortunately preventing PWAs from getting the appropriate lighthouse scoring causing further issues (e.g. the PWA failing the lighthouse PWA check which causes confusion whether the PWA is ready for use with bubblewrap). |
I further tried to investigate this issue as the additional http call to I could unfortunately not trace it further down. I tried changing the import order of the imports
but it did also not help (side note: it is bundled with webpack afterwards).
This instructs user agents to upgrade insecure requests - which the one we are talking about here is - automatically to secure ones. |
I am having the same problem but it includes functionality issues. In my case, the request is sent but I cannot see anything in the DebugView. If it helps tracking this down:
Edit: I just found out that it's working if I use the OLD @hsubox76 any idea on why could be this happening? |
@JFGHT which old @hsubox76 unfortunately this issue is still a rather big problem as it seems - confirmed via DebugView - to skip some pageviews as well as remove/reset the source for users when navigating on the website to another page (same domain). Is there anything we can do to prevent fix this issue as it makes using FB analytics really untrustworthy? |
I'm seeing this also, in a very clean setup. I'm seeing pending (unresolved) requests. Any timeline on getting to the bottom of this? @hsubox76 |
I think there may be a number of separate issues here and I am trying to sort out which are related. As far as the apiKey/measurementId issue, there may have been some project config bug. We just released a big change to analytics where measurementId is no longer required in the config and is dynamically fetched based on your config's apiKey and appId so that situation may have changed (hopefully for the better, possibly for worse). If you're still having trouble, can you contact Firebase Support, where you can privately give them your specific project config details and see if they can track it down. As for the Lighthouse http/https issue, I think the http call is made inside the gtag code which we unfortunately do not have any control over. I'll look into this further. As for the pending request, I think it's not related to Firebase and may possibly be intended functionality. I made an html page with no Firebase, just using gtag directly (https://developers.google.com/analytics/devguides/collection/gtagjs) and inserting my Firebase app's measurementId, and got the same requests. The page view event showed up fine in the dashboard either way. If you see a problem using Firebase Analytics that does not happen when using plain gtag.js in an html page with the same measurementId, please let me know. In general this is a good way to narrow down which problems are Firebase specific. |
I'm not sure if it's a workaround or the actual cause, but in my case I realised that the duplicate Edit: never mind, I still see the |
@hsubox76, thank you for your detailed reply. To be clear, my concern is the bahavior of Firebase Analytics when initialized. @tzar, this has nothing to do with frameworks. I can re-create the problem with a plain HTML page. I have not found anything that will stop this. After importing Firebase from the CDN (version 7.19.1), and initializing Firebase, I initialize Analytics. At that point, the Google library injects two scripts into the head of my page, one of which appears to be superflous. In addition, it makes two POST calls, one of which never resolves, leading the browser and performance monitoring tools like Lighthouse to think the page is still loading. Here are the two scripts injected into the head:
This call stays pending forever:
This call returns quickly with a 204:
You can peek at my page if you want (see the URL in the link above?), but I'm working on this daily, and I can't promise it'll be in the same state tomorrow. I may just rip Analytics out of the project until we can get a better handle on this. This seems like a mistake to me. I don't think the script should be injected twice. That's sloppy, and looks broken, which is not typical of Google. Worse, it's giving my page a bad performance rating--one that Google's own web crawler can certainly see, and may penalize me for. |
As mentioned in my previous comment, can you create a plain HTML page using gtag.js directly (https://developers.google.com/analytics/devguides/collection/gtagjs) and NOT importing or using Firebase, and let me know what problems you see in the Firebase page that you do not see in that page? We need to isolate which problems are unique to Firebase and not gtag.js. You can use the same measurementId as your Firebase app. |
I had this problem and managed to find a workaround for my use case. My initial problem was the following: I am using Nextjs and was initialising both firebase app and firebase analytics in code that was running at build time (nodejs), which was working in my development setting (I got all the events in the DebugView) but was failing in the call to My first idea was to move the analytics init to a part of the code that only runs in the client and not at build time (using the useEffect hook in React). This way I got rid of the build error but my events wouldn't be sent reliably anymore. I noticed the first couple events would sometime work and then nothing (maybe a race between the two inits of gtag, one not being configured properly?). After playing around, I realised that if I keep the Note that this fixed my issues with events not being sent (which was my only concern at this point) but that I still see the two gtag init messages in the console and keep seeing logs like So my guess would be that there might be some kind of race condition in the initialisation of gtag that could prevent it from being configured correctly. Moving the analytics init to as early as possible fixed it for me and I had to protect it in a try statement, which probably make the script run far enough to configure gtag properly and then fails only at the end because it is running in nodeJS. In my code I have a FirebaseProvider component that I include first in all my pages:
It's ugly but it works for me. Hope this helps. |
I believe the reason Firebase errors in your server-side build in Node is because Firebase Analytics is not supported in Node. I don't think this is related to this issue. Let me try to sum up this issue so far:
|
Yes, it's not supported and most likely unrelated to the issue. The fact that we see gtag logs twice doesn't seem directly related to the issue either as I see this whether events are working or not. My point is that the only difference between a working configuration and a failing one (events are not sent) on my project is the place/time where I initialise firebase analytics (potentially with regard to the place/time where I initialise the firebase app). Sorry if that wasn't clear. |
I have a similar issue. I have a minimalistic setup:
This causes gtag to be loaded twice: I see that the first load is initiated by helpers.ts, where I find the following comment:
Can you explain why this is necessary? I tried loading gtag myself (with measurementId included) like that:
This way gtag is only loaded once. Is this a save approach, or can this lead to corrupted analytics data? |
The thing that Firebase analytics adds on top of using plain gtag is that it attaches a Firebase instance ID to every event sent to analytics, which allows the backend to associate that event with your Firebase project. If that ID is not sent, the event will be stored with Google Analytics (I believe) but will not be associated with your Firebase project and won't show up in your Firebase analytics dashboard. If you include the measurementId in the gtag script download url as in your example above, it will immediately trigger a page_view event for that measurementID. This event data won't include your Firebase instance ID and won't be associated with your Firebase project. By leaving the measurementID out of the script download url, we prevent the initial page_view event (with no Firebase ID) from being sent, and we immediately make a gtag config call to send the measurementId plus firebase ID as the first call, so that your page_view will be logged correctly to your Firebase project. Unfortunately gtag needs to make another download once it gets the measurementId for the first time, so that's why it loads again. There doesn't seem to be a way to avoid it unless the gtag API changes to allow us to attach arbitrary config data to the initial script download, or some other option around this. |
Thanks for the explanation. Unfortunately I can not reproduce this behaviour in my project. If I simply add the gtag script with measurementId, I do not see a After initializing firebase analytics I see the following POST request:
|
Thanks very much for drawing my attention to measurementId in the script tag not causing a page_view event. I tested it and talked to the gtag team and confirmed this. I think we may have been operating on incorrect info originally. I've just merged #4434 which I believe will stop gtag from being downloaded twice. I'm not sure if this will fix any errors people are experiencing or reporting in this thread, but perhaps it could. It should at least avoid adding unnecessary and confusing clutter while you are debugging those errors. The fix probably won't go into this week's release (which is happening today) but should most likely make it into next Thursday's (Feb 18). |
i don't understand how this works with my own first party domain via GTM server side, can i pass a Can i just use my firebase web measurement id without firebase.analytics()? Right now i have firebase web data stream, and then i have a "web web" data stream because i dont trust the firebase web property since it's not managed by G4 (where is measurement protocol secrets api key?) so now i have two separate data streams to make sure i'm losing web to app conversions. Aren't we really just talking about |
Is there any way i can append or expose const configProperties = {
// guard against developers accidentally setting properties with prefix `firebase_`
[ORIGIN_KEY]: 'firebase',
update: true
}; async function initializeAnalytics(app, dynamicConfigPromisesList, measurementIdToAppId, installations, gtagCore, dataLayerName) {
const dynamicConfigPromise = fetchDynamicConfigWithRetry(app);
// Once fetched, map measurementIds to appId, for ease of lookup in wrapped gtag function.
dynamicConfigPromise
.then(config => {
measurementIdToAppId[config.measurementId] = config.appId;
if (app.options.measurementId &&
config.measurementId !== app.options.measurementId) {
logger.warn(`The measurement ID in the local Firebase config (${app.options.measurementId})` +
` does not match the measurement ID fetched from the server (${config.measurementId}).` +
` To ensure analytics events are always sent to the correct Analytics property,` +
` update the` +
` measurement ID field in the local config or remove it from the local config.`);
}
})
.catch(e => logger.error(e));
// Add to list to track state of all dynamic config promises.
dynamicConfigPromisesList.push(dynamicConfigPromise);
const fidPromise = validateIndexedDB().then(envIsValid => {
if (envIsValid) {
return installations.getId();
}
else {
return undefined;
}
});
const [dynamicConfig, fid] = await Promise.all([
dynamicConfigPromise,
fidPromise
]);
// Detect if user has already put the gtag <script> tag on this page.
if (!findGtagScriptOnPage()) {
insertScriptTag(dataLayerName, dynamicConfig.measurementId);
}
// This command initializes gtag.js and only needs to be called once for the entire web app,
// but since it is idempotent, we can call it multiple times.
// We keep it together with other initialization logic for better code structure.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
gtagCore('js', new Date());
const configProperties = {
// guard against developers accidentally setting properties with prefix `firebase_`
[ORIGIN_KEY]: 'firebase',
update: true
};
if (fid != null) {
configProperties[GA_FID_KEY] = fid;
}
// It should be the first config command called on this GA-ID
// Initialize this GA-ID and set FID on it using the gtag config API.
// Note: This will trigger a page_view event unless 'send_page_view' is set to false in
// `configProperties`.
gtagCore("config" /* CONFIG */, dynamicConfig.measurementId, configProperties);
return dynamicConfig.measurementId;
} |
There is a PR in progress to add this functionality (provide custom config params at initialization) in the new modular Firebase API (which is currently in Beta): #4575 You can use gtag without Firebase Analytics using your Firebase project's measurement ID. The drawback is you'll lose out on some functionality that lets you use things like Analytics audiences with other Firebase products like Remote Config. |
Heya, have you ever figured out, why some requests are stuck in |
I'm using S2S via G4 Measurement protocol for mobile events. Is it theoretically possible to use https://firebase.google.com/docs/reference/js/installations.md#getid Or, if i'm using a GTM web container<=>server with G4 tags can i push the firebase installation id to the dataLayer to be passed to g4 collection to be consumed as if it were coming from the the firebase analytics client? Basically if you look at the architecture here https://developers.google.com/analytics/devguides/collection/protocol/ga4 In this context, web client is referring to a non-firebase concept of client id, a gtag concept. Couldn't i retrieve the firebase installation from the web the same way as native client, and consolidate both data streams in an S2S only approach? I'd be happy to manage web installation id myself. My objective is just being able to send events to a firebase web property/data stream without the use of cross domain browser javascript/sdk |
I'm going to close this issue, as the initial issue of gtag being installed twice has been addressed. I realize the last 2 comments are old and had not been addressed so sorry about that, but if anyone is having separate issues or questions with Analytics not related to gtag being installed twice, feel free to make a new issue. |
Describe your environment
[REQUIRED] Describe the problem
When I load Firebase Web with analytics on Chrome with the
Google Analytics Debugger extension enabled, I get the following warning from the console: "GTAG script is installed twice."
Steps to reproduce:
Load a page with Firebase Analytics.
Relevant HTML head scripts:
Google Analytics Debugger extension logs:
Relevant Code:
The text was updated successfully, but these errors were encountered: