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."
Load a page with Firebase Analytics.
Relevant HTML head scripts:
<head>
<script type="text/javascript" async="" src="http://www.googletagmanager.com/gtag/js?id=G-XXX&l=dataLayer&cx=c"></script>
<script src="https://www.googletagmanager.com/gtag/js?l=dataLayer" async=""></script>
</head>
Google Analytics Debugger extension logs:
__ _| |_ __ _ __ _ (_)___
/ _` | __/ _` |/ _` | | / __|
| (_| | || (_| | (_| |_ | \__ \
\__, |\__\__,_|\__, (_)/ |___/
|___/ |___/ |__/
11:35:18.946 Processing commands (1)
11:35:18.946 Processing GTAG command: ["js", Thu Feb 13 2020 11:35:18 GMT+0100 (Central European Standard Time)]
11:35:18.948 No tags fired for event: gtm.js
11:35:18.949 Processing commands (1)
11:35:18.949 Processing GTAG command: ["config", "G-XXX", {firebase_id: "XXX", origin: "firebase", update: true}]
11:35:18.950 GTAG Command: "config", target: "G-XXX", configuration: {firebase_id: "XXX", origin: "firebase", update: true}
11:35:18.952 Tag fired: {function: "__get", vtp_trackingId: "G-XXX", vtp_isAutoTag: true}
11:35:18.955 Processing commands (0)
11:35:18.956 Processing commands (1)
11:35:18.956 Processing data layer push: {event: "gtm.dom"}
11:35:18.956 No tags fired for event: gtm.dom
11:35:18.957 Processing commands (1)
11:35:18.957 Processing data layer push: {event: "gtm.load"}
11:35:18.957 No tags fired for event: gtm.load
11:35:19.010 _ _
__ _| |_ __ _ __ _ (_)___
/ _` | __/ _` |/ _` | | / __|
| (_| | || (_| | (_| |_ | \__ \
\__, |\__\__,_|\__, (_)/ |___/
|___/ |___/ |__/
11:35:19.014 Processing commands (4)
11:35:19.014 Processing GTAG command: ["js", Thu Feb 13 2020 11:35:18 GMT+0100 (Central European Standard Time)]
11:35:19.016 gsi could not be evaluated client side. This container may have different behavior outside debug mode.
11:35:19.016 ftld lookup could not be evaluated client side. This container may have different behavior outside debug mode.
11:35:19.017 icvr could not be evaluated client side. This container may have different behavior outside debug mode.
11:35:19.019 gsi could not be evaluated client side. This container may have different behavior outside debug mode.
11:35:19.019 ftld lookup could not be evaluated client side. This container may have different behavior outside debug mode.
11:35:19.019 icvr could not be evaluated client side. This container may have different behavior outside debug mode.
11:35:19.019 Tag fired: {function: "__gct", instance_name: "8", vtp_trackingId: "G-XXX", vtp_adFeatures: false, vtp_sessionDuration: 0, vtp_googleSignals: ["macro", 1], vtp_foreignTld: ["macro", 2], vtp_restrictDomain: ["macro", 3], vtp_eventSettings: ["map", "ecommerce_purchase", ["map", "blacklisted", false, "conversion", true], "purchase", ["map", "blacklisted", false, "conversion", true]], tag_id: 7}
11:35:19.023 Loaded existing client id: XXX
11:35:19.026 Event would be batched, but batching is disabled in debug mode.
11:35:19.027 Sending event "page_view" to undefined
11:35:19.027 Request parameters:
11:35:19.028 v: 2
11:35:19.028 tid: G-XXX
11:35:19.028 gtm: 2oe250
11:35:19.029 _p: 826320161
11:35:19.029 sr: 1920x1080
11:35:19.029 _dbg: 1
11:35:19.030 ul: en-us
11:35:19.030 _fid: XXX
11:35:19.030 cid: XXX
11:35:19.031 Event parameters:
11:35:19.031 en: page_view
11:35:19.032 ep.origin: firebase
11:35:19.032 Shared parameters:
11:35:19.033 dl: XXX
11:35:19.033 dr: XXX
11:35:19.033 dt: XXX
11:35:19.034 sid: XXX
11:35:19.034 sct: XXX
11:35:19.034 seg: XXX
11:35:19.035 Sending request: https://www.google-analytics.com/g/collect?v=2&tid=G-XXX&...
11:35:19.036 gsi could not be evaluated client side. This container may have different behavior outside debug mode.
11:35:19.037 ftld lookup could not be evaluated client side. This container may have different behavior outside debug mode.
11:35:19.037 icvr could not be evaluated client side. This container may have different behavior outside debug mode.
11:35:19.038 Processing GTAG command: ["config", "G-XXX", {firebase_id: "XXX", origin: "firebase", update: true}]
11:35:19.038 GTAG Command: "config", target: "G-XXX", configuration: {firebase_id: "XXX", origin: "firebase", update: true}
11:35:19.038 GTAG script is installed twice.
11:35:19.039 gsi could not be evaluated client side. This container may have different behavior outside debug mode.
11:35:19.039 ftld lookup could not be evaluated client side. This container may have different behavior outside debug mode.
11:35:19.039 icvr could not be evaluated client side. This container may have different behavior outside debug mode.
11:35:19.040 No tags fired for event: gtag.config
11:35:19.040 gsi could not be evaluated client side. This container may have different behavior outside debug mode.
11:35:19.040 ftld lookup could not be evaluated client side. This container may have different behavior outside debug mode.
11:35:19.040 icvr could not be evaluated client side. This container may have different behavior outside debug mode.
11:35:19.040 Processing data layer push: {event: "gtm.dom", gtm.uniqueEventId: 2}
11:35:19.041 gsi could not be evaluated client side. This container may have different behavior outside debug mode.
11:35:19.041 ftld lookup could not be evaluated client side. This container may have different behavior outside debug mode.
11:35:19.041 icvr could not be evaluated client side. This container may have different behavior outside debug mode.
11:35:19.041 No tags fired for event: gtm.dom
11:35:19.042 gsi could not be evaluated client side. This container may have different behavior outside debug mode.
11:35:19.042 ftld lookup could not be evaluated client side. This container may have different behavior outside debug mode.
11:35:19.042 icvr could not be evaluated client side. This container may have different behavior outside debug mode.
11:35:19.042 Processing data layer push: {event: "gtm.load", gtm.uniqueEventId: 3}
11:35:19.042 gsi could not be evaluated client side. This container may have different behavior outside debug mode.
11:35:19.042 ftld lookup could not be evaluated client side. This container may have different behavior outside debug mode.
11:35:19.043 icvr could not be evaluated client side. This container may have different behavior outside debug mode.
11:35:19.043 No tags fired for event: gtm.load
11:35:19.043 gsi could not be evaluated client side. This container may have different behavior outside debug mode.
11:35:19.043 ftld lookup could not be evaluated client side. This container may have different behavior outside debug mode.
11:35:19.043 icvr could not be evaluated client side. This container may have different behavior outside debug mode.
import * as firebase from "firebase/app";
import "firebase/analytics";
import React, { useState } from "react";
import { AnalyticsContext } from "./analyticsUtils";
const defaultConfig = {};
interface Props {
config?: { [key: string]: any };
}
const AnalyticsProvider: React.FunctionComponent<Readonly<Props>> = function(
props
) {
const analytics = firebase
.initializeApp({
...defaultConfig,
...props.config
})
.analytics();
const [value] = useState({
logEvent: analytics.logEvent
});
return (
<AnalyticsContext.Provider value={value}>
{props.children}
</AnalyticsContext.Provider>
);
};
export default AnalyticsProvider;
I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.
Sorry for the late response here, @emac3. Per this reference, it seems that you have to remove the Measurement ID from the googletagmanager script. When you connect Firebase and Gtag, the Gtag SDK needs to have the Measurement ID removed, because Firebase provides its own to connect with the SDK.
One question, are you simultaneously using Firebase Analytics (firebase.analytics().logEvent etc) and direct calls to gtag.js (gtag('event')) on this page, or is this page only using analytics through Firebase Analytics? If it's the latter (Firebase Analytics only) you can get rid of those script tags entirely. If the former, see the documentation @rommelpe linked above.
@rommelpe @hsubox76 thanks for your replies, fact is those two script tags are added by Firebase at runtime. I'm only using analytics through Firebase Analytics. I didn't install gtag by myself. See my code snippet above.
I can't seem to reproduce this with that code snippet.
I filled in my own project config, I substituted const AnalyticsContext = React.createContext({}); for the missing AnalyticsContext, and I rendered AnalyticsProvider as a child of a top level App component, with no child elements except some text. I also tried rendering 2 AnalyticsProviders under App, giving them 2 different configs through props. I did get an error (Firebase App named '[DEFAULT]' already exists (app/duplicate-app).) for calling initializeApp twice but that was fixed by allowing me to give a different name prop to each AnalyticsProvider and using it in initializeApp.
Is there any way you can provide a full minimal repro that includes how you call the AnalyticsProvider component (if it's multiple times, please include that) and what AnalyticsContext looks like? It doesn't have to be your whole repo, just whatever minimal part I can run to reproduce the error on my own machine.
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 Firebase.Analytics _and_ gtag at the same time. So please discard this message.
Anything new about that? I am having the issue as well. I am calling only firebase.analytics() and log some custom events to define a funnel. But it seams like the events are not reported reliably. Even if they are logged to be sent correctly to Analytics by the _GA Debug Plugin_, sometimes they don't or only some events show up at the _Debug View_ or the _Realtime Panel_ of Analytics. It appears randomly. Anybody with same behavior or any ideas how to fix that?
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: https://github.com/firebase/firebase-js-sdk/issues/2600#issuecomment-583013243 particularly checking for that POST call to the collect? endpoint? If that call is successful, the data should be being sent to the backend, and the problem may be on that side.
I can confirm I am having the same issue, this is how it looks like in Chrome DevTools:

I also have the GA Debug Plugin report that GTAG script is installed twice.
My config is just:
firebase.initializeApp(firebaseConfig)
and this also only gets called once.
I'm using firebase npm package 7.14.0
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 https://github.com/GoogleChromeLabs/bubblewrap/issues/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 http://www.googletagmanager.com/gtag/js is causing further problems now. Since other tools/projects rely on the appropriate lighthouse scoring, this call destroys the ability to use such.
I could unfortunately not trace it further down. I tried changing the import order of the imports
import firebase from 'firebase/app'
import 'firebase/analytics'
but it did also not help (side note: it is bundled with webpack afterwards).
So I - for now until this is fixed in the Firebase or gtag library - decided to work around this issue by adding the CSP
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
This instructs user agents to upgrade insecure requests - which the one we are talking about here is - automatically to secure ones.
So there are still 2 requests but at least the one is not http anymore.
It's definitely not optimal as it might not work for everybody and could cause other issues but if anyone else is being stuck with this bug, you could also try if this works as a temporary workaround for you.
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.
From what I see here in the logs, the event gets executed twice, in which one of them it says Sending event "notification_received" to undefined.

If it helps tracking this down:
measurementId in the config section, but now it does. It also changed the apiKey.Edit: I just found out that it's working if I use the OLD apiKey, not the one that is being shown in the project settings / config.
@hsubox76 any idea on why could be this happening?
@JFGHT which old apiKey do you mean and what do you mean by it is working? Is the duplicate initialization gone when using that old apiKey?
@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).
And all that even though the browser seems to correctly send events to the collect endpoint. But, its most of the time sending two events to the collect endpoint (1 ...&en=page_view, one ...&en=user_engagement) where the user_engagement request is pending for a long long time (I think it never completes):

First is the user_engagement call, second the page_view.
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 gtag loads happened during the prerender phase (vue + prerender-spa-plugin). I added post-processing rules to remove them and now just a single gtag injection happens at runtime
Edit: never mind, I still see the Sending event "page_view" to undefined and double gtag.js load in console even with the pre-rendered loads removed. But the above did resolve my http/https mixed content errors at least
@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:
<script type="text/javascript" async="" src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX&l=dataLayer&cx=c"></script>
<script src="https://www.googletagmanager.com/gtag/js?l=dataLayer" async=""></script>
This call stays pending forever:
https://www.google-analytics.com/g/collect?v=2&tid=G-XXXXXXXXXX>m=2oe920&_p=1584065445&sr=1920x1080&ul=en-us&_fid=cGypl-WCHc8S3LcQnzTKci&cid=1765209537.1599819643&_s=2&dl=https%3A%2F%2Fcostvine.app%2F&dr=&dt=Costvine%20%E2%80%A2%20Budgets%20made%20easy&sid=1600059793&sct=7&seg=0&en=user_engagement&_et=2966&ep.origin=firebase
This call returns quickly with a 204:
https://www.google-analytics.com/g/collect?v=2&tid=G-XXXXXXXXXX>m=2oe920&_p=1208409921&sr=1920x1080&ul=en-us&_fid=cGypl-WCHc8S3LcQnzTKci&cid=1765209537.1599819643&_s=1&dl=https%3A%2F%2Fcostvine.app%2F&dr=&dt=Costvine%20%E2%80%A2%20Budgets%20made%20easy&sid=1600059793&sct=7&seg=1&en=page_view&ep.origin=firebase
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 firebase.analytics() at build time when deploying my webapp. Note that I am not sure why it was working in my dev setting (running next dev), I was seeing the error in server logs (ReferenceError: navigator is not defined) but it would probably rerun the code on the client and work eventually.
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 firebase.analytics() call at build time (right after the call to firebase.initializeApp(config)) but move it inside a try/catch block, I can build and I get the correct behaviour with all events being properly sent and visible in the DebugView.
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 Sending event "screen_view" to undefined (but these now don't impact the functionality of GA).
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:
export default function FirebaseProvider({ children }) {
if (!firebase.apps.length) {
firebase.initializeApp(firebaseConfig);
try {
firebase.analytics();
} catch (error) {}
}
...
}
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:
1) gtag is always included twice when using Firebase Analytics. This is expected. It is not a bug (in the sense of being unexpected at least) or a sign your build process is wrong or not working with Firebase. It is not ideal but not currently avoidable. See comment above: https://github.com/firebase/firebase-js-sdk/issues/2628#issuecomment-590564032
2) In previous tests I didn't find any functionality issue that stemmed from gtag being included twice. There definitely could be an issue I didn't find, but in order to ensure the error is being caused by gtag being included twice and not by some other cause, we need to isolate the issue more narrowly than, seeing a functionality issue and also seeing gtag being included twice, because, as mentioned above, that happens in every case.
3) Here's a general Firebase Analytics debugging guide to help determine if the problem is your environment: https://github.com/firebase/firebase-js-sdk/issues/2628#issuecomment-590564032 It includes a website to test your environment on, as well as a minimal repo to test on your machine.
4) To help isolate if the problem is definitely with Firebase (as opposed to gtag itself), please try to 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. You can use the same measurementId as your Firebase app. If you see the same problems in that page (not receiving events, console errors), it seems like the problem is with gtag.js itself. Also let me know, but in that case I can only report it.
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.