Google / Firebase Analytics not working on iOS with Capacitor 4 - firebase

Currently I am working on a Capacitor 4 app using VUE. To know which sections are used most I want to add Google or Firebase Analytics.
In the browser and Android everything works fine, however on iOS it doesn't. I tried 6 different solutions and now kinda out of options. My guess is that it has something todo with the Capacitor webview not being allowed to call Google/Firebase analytics or can set cookies.
Another issue could be that Capacitor serves the app from localhost. That would clarify why analytics is working when I add:
server: {
url: 'http://192.168.0.16:3333',
cleartext: true,
},
To the capacitor.config.ts since it then is not server from localhost but from an ip.
I was wondering if anyone has experienced the same (and might know a solution)
Solutions tried without any working outcome on iOS
1. Added extra consent flags to avoid using cookies
from: Disabling cookies in Google Analytics - gtag.js
gtag("consent", "default", {
ad_storage: "denied",
analytics_storage: "denied",
})
2. Added client_storage: "none",
gtag("config", "%VITE_APP_GOOGLE_TAG_MANAGER_TRACKING_ID%", {
send_page_view: false,
anonymize_ip: true,
client_storage: "none",
})
3. From https://github.com/ionic-team/capacitor/issues/1433#issuecomment-631404089
// allow capacitor:// as protocol
gtag('set', 'checkProtocolTask', function () { /* nothing */ });
4. Going back to analytics.js
ga("set", {
// don't abort if the protocol is not http(s)
checkProtocolTask: null,
// don't expect cookies to be enabled
checkStorageTask: null,
})
5. Firebase Analytics - Capacitor
https://github.com/capacitor-community/firebase-analytics Not maintained anymore since 25 Januari 2011
6. Firebase Analytics - Web
Used the web package for Firebase Analytics https://firebase.google.com/docs/reference/js/analytics

Related

Firebase 3rd-party AuthProvider (Google/Facebook/etc) login with chrome extension manifest v3

Manifest version 3 for Chrome extensions have been killing me lately. Been able to navigate around it so far, but this one has really stumped me. I'm trying to use Firebase authentication for a Chrome extension, specifically with 3rd party auth providers such as Google and Facebook. I've setup the Firebase configuration for Login with Google and created a login section in the options page of the Chrome extension and setup the Firebase SDK.
Now, there are two login options when using an auth provider, signInWithRedirect and signInWithPopup. I've tried both of these and both have failed for different reasons. signInWithRedirect seems like a complete dead end as it redirects to the auth provider, and when it attempts to redirect back to the chrome-extension://.../options.html page, it just redirects to "about:blank#blocked" instead.
When attempting to use signInWithPopup, I instead get
Refused to load the script 'https://apis.google.com/js/api.js?onload=__iframefcb776751' because it violates the following Content Security Policy directive: "script-src 'self'". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.
In v2, you could simply add https://apis.google.com to the content_security_policy in the manifest. But in v3, the docs say
"In addition, MV3 disallows certain CSP modifications for extension_pages that were permitted in MV2. The script-src, object-src, and worker-src directives may only have the following values:"
self
none
Any localhost source, (http://localhost, http://127.0.0.1, or any port on those domains)
So is there seriously no way for a Google Chrome extension to authenticate with a Google auth provider through Google's Firebase? The only workaround I can think of is to create some hosted site that does the authentication, have the Chrome extension inject a content script, and have the hosted site pass the auth details back to the Chrome extension through an event or something. Seems like a huge hack though and possibly subject to security flaws. Anyone else have ideas??
Although it was mentioned in the comments that this works with the Google auth provider using chrome.identity sadly there was no code example so I had to figure out myself how to do it.
Here is how I did it following this tutorial:
(It also mentions a solution for non-Google auth providers that I didn't try)
Identity Permission
First you need permission to use the chrome identity API. You get it by adding this to your manifest.json:
{
...
"permissions": [
"identity"
],
...
}
Consistent Application ID
You need your application ID consistent during development to use the OAuth process. To accomplish that, you need to copy the key in an installed version of your manifest.json.
To get a suitable key value, first install your extension from a .crx file (you may need to upload your extension or package it manually). Then, in your user data directory (on macOS it is ~/Library/Application\ Support/Google/Chrome), look in the file Default/Extensions/EXTENSION_ID/EXTENSION_VERSION/manifest.json. You will see the key value filled in there.
{
...
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgFbIrnF3oWbqomZh8CHzkTE9MxD/4tVmCTJ3JYSzYhtVnX7tVAbXZRRPuYLavIFaS15tojlRNRhfOdvyTXew+RaSJjOIzdo30byBU3C4mJAtRtSjb+U9fAsJxStVpXvdQrYNNFCCx/85T6oJX3qDsYexFCs/9doGqzhCc5RvN+W4jbQlfz7n+TiT8TtPBKrQWGLYjbEdNpPnvnorJBMys/yob82cglpqbWI36sTSGwQxjgQbp3b4mnQ2R0gzOcY41cMOw8JqSl6aXdYfHBTLxCy+gz9RCQYNUhDewxE1DeoEgAh21956oKJ8Sn7FacyMyNcnWvNhlMzPtr/0RUK7nQIDAQAB",
...
}
Copy this line to your source manifest.json.
Register your Extension with Google Cloud APIs
You need to register your app in the Google APIs Console to get the client ID:
Search for the API you what to use and make sure it is activated in your project. In my case Cloud Firestore API.
Go to the API Access navigation menu item and click on the Create an OAuth 2.0 client ID... blue button.
Select Chrome Application and enter your application ID (same ID displayed in the extensions management page).
Put this client ID in your manifest.json. You only need the userinfo.email scope.
{
...
"oauth2": {
"client_id": "171239695530-3mbapmkhai2m0qjb2jgjp097c7jmmhc3.apps.googleusercontent.com",
"scopes": [
"https://www.googleapis.com/auth/userinfo.email"
]
}
...
}
Get and Use the Google Auth Token
chrome.identity.getAuthToken({ 'interactive': true }, function(token) {
// console.log("token: " + token);
let credential = firebase.auth.GoogleAuthProvider.credential(null, token);
firebase.auth().signInWithCredential(credential)
.then((result) => {
// console.log("Login successful!");
DoWhatYouWantWithTheUserObject(result.user);
})
.catch((error) => {
console.error(error);
});
});
Have fun with your Firebase Service...

How to configure gatsby-plugin-google-analytics with cookies consent?

I have developed a website using gatsby and I am using google analytics plugin via gatsby-plugin-google-analytics, now to be nice with the users, I would like to add a cookie consent where the user will be two options whether to accept or decline cookies usages. If the user declines then I would like to stop google analytics to track the user activity. I dug into their documentation but unable to find the option to achieve this, is there any way around to achieve this.
{
resolve: `gatsby-plugin-google-analytics`,
options: {
trackingId: siteConfig.googleAnalyticsId,
// Defines where to place the tracking script - `true` in the head and `false` in the body
head: false,
},
},
For the movement my gatsby-config.js looks like this. how one can achieve this.
Thanks you in advance.
The plugin merely loads the library and instruments page tracking calls in a Gatsby-compatible way for you. All of the other Google Analytics calls, including disabling measurement for a user works the same as normal.
It's up to you to:
Build and show a cookie notice with an opt-out
Remember when a user has opted out
Communicate this on each page-load for the user (before any ga() calls are made) by setting window['ga-disable-UA-XXXXX-Y'] = true
You should be able to do this in a function exported as onClientEntry from gatsby-browser.js. For example:
export const onClientEntry = () => {
if (userHasOptedOutOfThirdPartyTracking()) {
window[`ga-disable-${process.env.GATSBY_GOOGLE_ANALYTICS_ID`] = true
}
}
For the Gatsby website, you could use a combination of gatsby-plugin-gdpr-cookies for analytics cookies management in your gatsby-config.js and react-cookie-consent to display the cookie banner.
# using npm
npm install --save gatsby-plugin-gdpr-cookies react-cookie-consent
# using yarn
yarn add gatsby-plugin-gdpr-cookies react-cookie-consent
You can find a more detailed tutorial here.

Google workbox offline analytics not working as expected

I am trying to follow the example in:
https://developers.google.com/web/tools/workbox/modules/workbox-google-analytics
I set up a Google analytics account, and then created a PWA using https://codelabs.developers.google.com/codelabs/workbox-lab/#0.
The PWA from the lab works as expected.
Then I created a custom dimension (dimension1) and a custom metric (metric1) in google analytics. When I send the dimension and metric in code on page load it shows up in the Google analytics reports.
ga('create', 'UA-125355230-1', 'auto');
//ga('send', 'event', 'category', 'action', { 'metric1': 100 });
ga('set', 'dimension1', 'online');
ga('send', 'pageview');
Then in the sw.js (the service worker js), I added the following code, as it says in the tutorial:
workbox.googleAnalytics.initialize({
parameterOverrides: {
dimension1: 'offline',
},
hitFilter: (params) => {
const queueTimeInSeconds = Math.round(params.get('qt') / 1000);
params.set('metric1', queueTimeInSeconds);
},
});
I stopped the app, and refreshed the index.html a few times. I brought the app back online and tried to sync the service worker by using the queue name workbox-background-sync:workbox-google-analytics.
This triggers the background plugin code, but it does not find anything to send.
Same results when I tried to make the network offline in devtools.
In debugger the createRequestWillReplayCallback of workbox-google-analytics.dev.js is called initially, but the replayRequests of workbox-background-sync.dev.js which is called when I try syncing seems to not find anything to replay.
During sync the
workbox-background-sync - http://localhost:8081
is created in indexedDB, but the queueName under requests seem to be empty:
What am I missing? Any pointers or help to get the offline analytics working with Workbox and test PWA is appreciated.

Firebase signInWithPopup gives auth/popup-blocked when used via built-in browser in mobile device

Problem: When used via 3rd-party app built-in browser (e.g. LINE, Twitter or Facebook messenger), the signInWithPopup returns auth/popup-blocked. The explanation by Firebase docs is:
auth/popup-blocked: Thrown if the popup was blocked by the browser, typically when this operation is triggered outside of a click handler.
Typical sequence triggering this error is: Link of my web app is sent to LINE, Twitter or Facebook messenger. When user uses mobile device and opens that link in those apps, their built-in browser is opened. Calling signInWithPopup then returns the error. The behavior is slightly different in iOS and Android but at least iOS/LINE combination results the error.
I am using Angular and building a web app. The error message is Unable to establish a connection with the popup. It may have been blocked by the browser. which comes from the firebase.js - not my own text.
When used in a normal browser, the signup works just fine.
Any ideas why the built-in browsers and signInWithPopup do not work together?
Firebase authentication should start with some user interaction, such as click on button. This solved the problem for me.
Many in-app embedded browsers block popups. I ran into the issue on instagram. Try using signInWithRedirect instead of signInWithPopup when kicking off the Oauth call.
Firebase documentation on usage of both methods can be found here - https://firebase.google.com/docs/reference/js/firebase.auth.Auth#signInWithPopup
signInWithPopup() is for the browser, however, if you're running iOS or Andriod emulator or device, you need to call signInWithCredential.
signInWithFacebook() {
if (this.platform.is('cordova')) {
return this.fb.login(['email', 'public_profile']).then(res => {
const facebookCredential = firebase.auth.FacebookAuthProvider.credential(res.authResponse.accessToken);
return firebase.auth().signInWithCredential(facebookCredential);
})
}
else {
return this.afAuth.auth
.signInWithPopup(new firebase.auth.FacebookAuthProvider())
.then(res => console.log(res));
}
}
If you're using Ionic + Firebase, you can find more info here
I have the same issue, with my web app on facebook ads campaign. I change my code from popup to redirect.
googleAuth() {
firebase
.auth()
.getRedirectResult()
.then(function(result) {
this.showLoading = true;
if (result.credential) {
var token = result.credential.accessToken;
console.log(token);
}
var user = result.user;
console.log(user);
});
this.showLoading = true;
const provider = new firebase.auth.GoogleAuthProvider();
provider.addScope("profile");
provider.addScope("email");
firebase.auth().signInWithRedirect(provider);
}
}
The problem now is save my utms from campaigns, because with redirect you lose them.

How to measure the number of people disabling push notifications from my progressive web app?

I'm using the new web push API with service workers in my progressive web app but am worried about users disabling the push notification permission after originally enabling it.
What is the best way to detect users disabling the notification permission (i.e. add instrumentation/analytics) so I can track this?
I believe what you're looking is covered in the Permissions API, which includes a change event. That event is fired both for the initial user decision and again if the user later changes their mind.
At its most basic, you could do:
if ('permissions' in navigator) {
navigator.permissions.query({name:'notifications'}).then(function(notificationPerm) {
// notificationPerm.state is one of 'granted', 'denied', or 'prompt'.
// At this point you can compare notificationPerm.state to a previously
// cached value, and also listen for changes while the page is open via
// the onchange handler.
notificationPerm.onchange = function() {
// Permissions have changed while the page is open.
// Do something based on the current notificationPerm.state value.
};
});
}
There are a few good resources out there demonstrating how this could be used:
https://developers.google.com/web/updates/2015/04/permissions-api-for-the-web
https://developer.mozilla.org/en-US/docs/Web/API/Permissions_API
https://github.com/GoogleChrome/samples/tree/gh-pages/permissions
The Permissions API is supported in Chrome as of version 43, and Firefox as of the upcoming version 45 release.

Resources