46

I am making an app and I want to get analytics from the users. I tried to use the Phonegap Plugin, but I didn't have any luck trying to implement it.

I was wondering if it was possible to get Google Analytics by treating the app like a normal webpage and putting some javascript in the head of my page.

Is there a better way to do this? and is the Phonegap Google Analytics THAT much better than what I'm trying to do?

Mike
  • 2,185
  • 6
  • 25
  • 39

14 Answers14

34

Check out the video to see it in action:

http://screencast.com/t/6vkWlZOp

After some research, I found a solution. I came across this thread on the Phonegap Google Group: https://groups.google.com/forum/#!msg/phonegap/uqYjTmd4w_E/YD1QPmLSxf4J (thanks TimW and Dan Levine!) In this thread I found that it is possible to use Google Analytics without a plugin. All you have to do is download the ga.js file from Google http://www.google-analytics.com/ga.js (just save the page into your www folder)

Then modify the ga.js file by adding one character to it. Search the ga.js file for the word "file:" and replace it with "_file:".

In the thread I linked to above, "TimW" explains the reasoning for this:

Essentially, Google Analytics won't work if its being used from a file:/// url. In iOS/PhoneGap this is the case. In order to solve this problem you must first download the ga.js file from google and include it as part of your local build. You'll notice the this file is obfuscated. Search the file for the string "file:" which should occur only once. When you find it, add an underscore to the beginning (so it becomes "_file:"). This prevents it matching the protocol of the page location (which is "file:").

After you added one character to the ga.js file, simply include this following in the top of your page:

<script type="text/javascript" src="ga.js"></script>
    <script>
 var _gaq = _gaq || [];
    _gaq.push(['_setAccount', 'UA-YOUR_ID_HERE']);
    _gaq.push(['_setDomainName', 'none']);
    _gaq.push(['_trackPageview', 'NAME_OF_PAGE']);
    </script>

I tested this on the simulator, and I got a proof that it was working using the Real-Time view in Google Analytics. The simulator was working on iOS 5.0. My phone is still on iOS 4.2, and when I tested it on my device, it didn't show up on the Real Time tracking.

In the thread, someone mentioned the same issues with Android 4.0+... Hopefully there will be a better solution for this in the future but for now this is the easiest and least complicated way to get basic analytics for my app. It can't do offline tracking, but that's kinda creepy anyways.

Even though iOS 4 and Android users are a minority in the market (see pie chart):

http://static7.businessinsider.com/image/4fd65fac6bb3f7925700000f/chart-of-the-day-ios-vs-android-june-2012.jpg

I would stil like to get data from all OS's.

Mike
  • 2,185
  • 6
  • 25
  • 39
  • Have you found a solution to the not tracking problem at all? I'm currently looking for a full solution, but haven't found a good one yet. – Caimen Sep 28 '12 at 20:03
  • What happens if there is not internet connection? – tersakyan Oct 07 '12 at 20:16
  • No internet conncection... no tracking :/ but when you think about it it's pretty creepy anyways to track you when your offline. A little too Big Brother-esque if you know what I mean. – Mike Oct 07 '12 at 20:48
  • I can't get this to work on any iOS device or Android device. For reference, I'm using iPad/iPhone with iOS 6.0.1 and Galaxy Tab with Android 4.0. – xdumaine Nov 08 '12 at 15:44
  • 1
    I created lib based on pokki GAPokki implementation (with LocalStorage) and it works great on android 4.0+ check it in the answer below – Guillaume Gendre Jan 04 '13 at 09:39
  • It's important to select "website" not "app" when creating the Google Analytics property. Otherwise it doesn't work. – Fiach Reid Sep 19 '14 at 08:33
  • @Mike The solution is working perfectly on browser but not on device (android 4.2.1), any idea? – Reza Feb 25 '15 at 15:56
  • This is no longer necessary. I've posted an updated answer (2017). – Louis Ameline Feb 14 '17 at 10:12
30

[edit] Google Analytics now works with localstorage in hybrid apps.

Google Analytics now have an options explained here to use LocalStorage instead of cookies and there is also a hack to make it work in webviews (file:// urls). So instead of using the code I suggested before, you can just do this :

// THIS IS FOR LOCALSTORAGE
var GA_LOCAL_STORAGE_KEY = 'ga:clientId';
ga('create', 'UA-XXXXX-Y', {
  'storage': 'none',
  'clientId': localStorage.getItem(GA_LOCAL_STORAGE_KEY)
});
ga(function(tracker) {
  localStorage.setItem(GA_LOCAL_STORAGE_KEY, tracker.get('clientId'));
});

// THIS IS FOR FILE URL SUPPORT
ga('set', 'checkProtocolTask', function(){ /* noop */});

// And then as usual...
ga('send', 'pageview');

previous answer content :

The pokki solution suggested by Alex is working fine with a few adjustments to remove the need of Pokki.

I created a git project for this cleaned-up version here :

https://github.com/ggendre/GALocalStorage

Works great on android 4.1 and ios6, I will test more device very soon. Hope this helps ! :)

Guillaume Gendre
  • 2,294
  • 24
  • 16
  • This seems to work great! Do you know what kind of support it has older Android/iOS versions? – OhmzTech Jan 15 '13 at 04:18
  • 2
    We've tested and it works fine from android 2.1 to 4.1. I don't have any device below 2.1 so I can't test on older than this. iOs is OK from ios 3.2 to ios6. – Guillaume Gendre Jan 18 '13 at 15:26
  • Do you know if there is any way to get screen size/resolution tracking accordingly with this? Mobile device names are tracked, but not screen size. – OhmzTech Jan 29 '13 at 20:19
  • Well, I don't know... this doesn't seems to be in the forked pokki package. maybe you can use custom vars as describer [here](https://developers.pokki.com/docs/tutorials.php) but that's not ideal. Feel free to add a feature request to the github project, I will have a look someday – Guillaume Gendre Jan 30 '13 at 08:50
  • This is just perfect!! worked without any problems and it was very easy to set up. Tested with android 4.3 – MazarD Oct 15 '13 at 18:03
  • This worked well with my phonegap app. But how to check an event if the app is offline. How to use google analytics when offline? – Nijil Nair Nov 28 '13 at 12:00
  • 1
    To do this you need to set up the GA property as website. What do you enter in the domain field? Because GA won't create a web property without it. Do you just enter random stuff? – Albert Feb 25 '14 at 20:33
  • 1
    @GuillaumeGendre works great thanks. But as Albert asked, what do you enter in the URL field when setting up analytics website property? – Sarah Feb 10 '17 at 22:36
  • 1
    I've posted an updated answer below, I believe this solution is no longer the best. – Louis Ameline Feb 14 '17 at 10:14
  • as @LouisAmeline said, this is not the best solution anymore. I edited my answer to show what you can use now instead. There is no need for what I previously done anymore. and that's a great news :) – Guillaume Gendre Jan 08 '18 at 11:10
  • 2
    After 3 days of trying Cordova's google-analytic plugins (all of the plugins.. seriously), and my app crashing on startup after installing them.. I reverted to attempt using the web method. This worked like magic. Thanks, Guillaume. Awesome solution!! – iPzard Jul 08 '18 at 20:11
  • hello, i add my cordova app like a website into google analytics, but i don't get anything. What website URL i need to put ? it's a cordova application so it don't have url... – Nizar Jul 04 '19 at 14:01
  • +1 for this answer, IF you are reading this and you are having problem with cordova's google analytics/ firebase plugins JUST LEAVE THEM and use this answer. Basically what I did was in Google Analytics Dashboard created new "Website view", for the website address I set up my API address since when is cordova you don't have an actual address, then followed @LouisAmeline's answer, on how to import the ga script and then I used this answer to set it up for working in webview. – chnging Nov 09 '19 at 15:25
  • I had to use this as last line to make it work: `ga("send", "pageview", { location: document.location.href.replace("file:///", "http://") });` – Melounek Jun 09 '20 at 12:44
26

This is February 2017 and there is no need to edit analytics.js, nor for a library or plugin anymore, or at least I had no need for them. Many things that were said in the past years are deprecated or just obsolete, so here is my up-to-date comprehensive guide.

1. The config.xml file

In your config.xml, you must allow the cross-site request:

<access origin="https://www.google-analytics.com" />

2. The HTML

In your CSP meta tag, if you choose to have one, you must also allow calls to Google. It may look like:

<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: 'unsafe-inline' 'unsafe-eval' https://ssl.gstatic.com https://www.google-analytics.com;">

3. The javascript

Here is the commented code for a webapp that can run both in the browser and in a Cordova packaged app. You can ignore the else block if you don't care about the browser.

// the default GA code, nothing to change
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

var fields = {
  // note: you can use a single tracking id for both the app and the website,
  // don't worry it won't mix the data. More about this in the 3rd section
  trackingId: 'UA-XXXXXXXX-Y'
};

// if we are in the app (the protocol will be file://)
if(document.URL.indexOf('http://') !== 0){

  // we store and provide the clientId ourselves in localstorage since there are no
  // cookies in Cordova
  fields.clientId = localStorage.getItem('ga:clientId');
  // disable GA's cookie storage functions
  fields.storage = 'none';

  ga('create', fields);

  // prevent tasks that would abort tracking
  ga('set', {
    // don't abort if the protocol is not http(s)
    checkProtocolTask: null,
    // don't expect cookies to be enabled
    checkStorageTask: null
  });

  // a callback function to get the clientId and store it ourselves
  ga(function(tracker){
    localStorage.setItem('ga:clientId', tracker.get('clientId'));
  });

  // send a screenview event
  ga('send', {
    // these are the three required properties, check GA's doc for the optional ones
    hitType: 'screenview',
    // you can edit these two values as you wish
    screenName: '/index.html',
    appName: 'YourAppName'
  });
}
// if we are in a browser
else {

  ga('create', fields);

  // send a pageview event
  ga('send', {
    // this is required, there are optional properties too if you want them
    hitType: 'pageview'
  });
}

3. Your GA account

  • To monitor the traffic of the mobile app, create a view of the App type.

If you don't need to monitor the traffic of your web app from a website, you can stop reading here, otherwise read on. I assume you are using a single account for the tracking of both the website and the app.

  • Apply the custom filter named "Application? => yes" on the created view so that it will only show the screenview hits. There is an official guide here
  • Then, to track the traffic from the website, create a second view of the Website type. Apply a custom filter "Application? => no" on it.
  • If you want a merged view of your traffic online and in-app, create a third view of the App type. By default (without filter), it will show all data.

Additional notes

  • Everything goes over https now, no need for the http protocol anymore in your <access> and CSP
  • Be aware that writing *.google-analytics.com in the CSP would not work. Although that policy works in Chrome (56), it doesn't in Cordova (5.6.0)
  • Google analytics does not require any application permissions like ACCESS_NETWORK_STATE or ACCESS_WIFI_STATE like I've read elsewhere
  • All of this was tested with an Android app (I expect it to work in iOS apps as well), with the Crosswalk plugin installed
Louis Ameline
  • 2,369
  • 1
  • 20
  • 23
  • This helped me out getting react-ga to work on ios/android. The main change I made being: ReactGA.set({checkProtocolTask: null, checkStorageTask: null}); Thank you for your great explanation. – jarbot Feb 23 '17 at 09:25
  • Worked beautifully for me! This should be the accepted solution. – Augustin Bralley Feb 28 '17 at 01:37
  • thanks for this answer. As per the latest google analytics update, we need to use ga.js and not the analytics.js. Does this solution be different with that approach? I already have website code which refers to ga.js as per the code and description suggested google analytics help. What do you suggest? – Jit Oct 24 '17 at 06:50
  • The official documentation says : "ga.js is a legacy library. If you are starting a new implementation, we recommend you use the latest version of this library, analytics.js". I haven't tried with ga.js. – Louis Ameline Oct 24 '17 at 11:51
  • thanks.Sorry I asked it wrong. On google site I saw,"The gtag.js library is the recommended tracking code for new implementations. However, there may be cases where you would prefer to use analytics.js" and I am also adding google tag manager per below links.So was making sure these together with your code would work for phonegap mobile app too. https://developers.google.com/analytics/devguides/collection/gtagjs/migration https://support.google.com/tagmanager/answer/6102821?authuser=1 https://support.google.com/analytics/answer/7538414?authuser=1 – Jit Oct 30 '17 at 05:28
  • I am trying to follow your instructions but when I am creating a new Google Analytics profile, it asks for a "Website URL". What should I write there? I tried putting "none" and "localhost" although I know thats wrong but it complains saying "URL ends with an invalid top-level domain name". ANy ideas? – Manish Pradhan Jul 21 '19 at 19:18
  • What happens when offline? – Velda Nov 18 '19 at 17:36
3

I was using Ionic app (based on cordova) as a mobile website and GA was working for it. When I shipped the same app to native ios, it stopped working.

Issue 1.
On checking the logs of simulator, found that GA was not being loaded correctly. It was trying the load file://. To fix this, I prepended https: to GA url under

(window,document,'script','//www.google-analytics.com/analytics.js','ga')

Issue 2. Google by default aborts the request if the page protocol is not http or https. To fix this

ga('set', 'checkProtocolTask', null);

And you should be set. After making these changes, I was able to confirm the events on GA. Hope it helps you too.

Nirav Gandhi
  • 1,835
  • 1
  • 23
  • 29
  • 1
    Note that the 'checkProtocolTask' call needs to come after the 'create' call. Source: https://developers.google.com/analytics/devguides/collection/analyticsjs/tasks – Gerard Aug 30 '16 at 13:40
3

The year is 2019 the month November, Google keeps updating their APIs, "best" pratices and etc. without ANY good documentation or backward compatibility.

Here is what I did for my solution I used combination from two of the answers here.

Before I start IF you are reading this and you are having problem with cordova's google analytics/ firebase plugins JUST LEAVE THEM, when using webview you don't need any of the plugins.

1) First you have to go to the Google Analytics and create a new "Property" that will measure "Website" activity (who knows by the time you are reading this how those will be called but everything should be in the "Admin" part of the panel).

One of the questions that comes to mind here is "But it wants url, I don't have url I am making Cordova App"

And yes you are right, for the URL I used my app's API (Which means most likely any url you enter there will work)

2) Then Follow the instructions in the answer of @Louis Ameline which is this one With that you will have the script loaded in your app and ready for usage.

3) By this time now if you run your app in browser everything should be fine and you probably will be able to see in the "Live analytics" that there is 1 online user.

4) Now for this to work in Webview you should follow the answer of @Guillaume Gendre (the updated one) here. I just copy pasted the code (of course with my trackingId) and now when I build the application and run it on my Android it works as expected and the analytics are sent.


I hope my solution actually helps someone and saves some time. Just leave all plugins because they lead to a deep hole of unsuccessful builds that just does not end because of version problems.

Also my App is React based but that should not matter at all, it should work with all frameworks and libraries because this is pure js. I suggest you use that kind of solution for this type of problems because it is not connected to any specific libraries.

chnging
  • 636
  • 6
  • 24
  • are you still using analytics.js? Since right now, google is insisting to use gtag.js and it is not working for me in Cordova but works in browser. – bumblebeen Jan 10 '20 at 11:53
  • Yes I am still using the analytics.js and it is working, but my guess is that eventually it won't or it has to do something with the date I registered the website in order to have some kind of backward compatibility. (For example if you registered your app before the "insisting" of Google, maybe they don't force you to do it) – chnging Jan 12 '20 at 10:08
2

Didn't work for me. The problem that google code uses cookies and it doesn't work with file:// urls.

I found good implementation that uses localStorage in place of cookies: https://developers.pokki.com/docs/tutorials.php

Alex
  • 41
  • 1
  • 1
    Hi! thanks for your link, this worked great with a few hacking to remove the pokki need. I created a git repo here : https://github.com/ggendre/GALocalStorage – Guillaume Gendre Jan 04 '13 at 09:35
1

I have implemented the segment.io - analytics.js library in a HTML5/meteor application.

I have no analytics plugin in phonegap (3.1). Worked immediately for iOS.

After implementation, analytics from the Android app did not display for about 4 hours. It then started working without changes to phonegap or meteor settings.

Hopefully this helps someone avoid a few hours of looking for a mystery bug.

Note: Make sure correct access origin is set up e.g. add

kate
  • 141
  • 1
  • 6
1

this phonegap plugin will help to integrate the google analytics in phonegap app. Read this blog to learn more how to integrate google analytics in phonegap. you can also download the working demo code from here.

Shashi
  • 1,085
  • 4
  • 18
  • 38
0

For anyone running into problems with Guillaume Gendre's great solution on Android 4.1 or another specific platform, this might solve them.

If your Android console logs show "Unknown Chromium error: 0", it's likely that you need to refine your access permissions in config.xml. I fixed my problem and described it here.

Community
  • 1
  • 1
Wytze
  • 7,494
  • 8
  • 46
  • 61
0

Quick and dirty solution. Use can use a light-hidden iframe like this;

<iframe src="http://www.yourwebsite.com/userControls/GoogleAnalytics.html?param=extraParamHere" style="visibility: hidden"></iframe>

And every time you request a page in the PhoneGap app, reload this iframe to initialize the track.

Teoman shipahi
  • 43,086
  • 13
  • 113
  • 137
0

You can use GALocalstorage library, and it works fine on mobile devices

It's easy to setup

<script type="text/javascript" src="js/libs/GALocalStorage.js"></script>
<script>
    ga_storage._setAccount('UA-37167XXX-1'); //Replace with your own
    ga_storage._trackPageview('/index.html');

</script>

and that is it, no modification or anything else.

You need to create Website Account in Google analytics to use this library

Library on GitHub

Reza
  • 15,335
  • 4
  • 62
  • 120
0

NOTE: Google Analytics Client Traking ID generated for mobile platform only supports for IOS and Android.So if you want to Track your google analytics,Be Sure you have Created it for website. Only Tracking ID for website work with phone gap all platform apps. You can then Simply download GALocalStorage from below link and then place it in you js folder under www folder

www
 |__
    js
      |__
          GALocalStorage.js

Then write the below code under your < head> tag,and its start showing Realtime active Users in your dashboards.

https://github.com/ggendre/GALocalStorage

       <script>
        ga_storage._setAccount('UA-XXXXXXXX-X'); //Replace with your own
        ga_storage._trackPageview('Home Screen');
        </script>
9to5ios
  • 4,838
  • 2
  • 32
  • 59
0

For me it turned out that no plugin is needed! I have Angular 8 app wrapped in Cordova (so similar use case as with Ionic) I registered new web site in Google Analytics. I modified code form GA to look like this:

const gaScript = document.createElement('script');
        gaScript.src = "https://www.google-analytics.com/analytics.js";
        gaScript.type = "text/javascript";
        document.getElementsByTagName('head')[0].appendChild(gaScript);
        gaScript.onload = (ev: Event) => {
            const GA_LOCAL_STORAGE_KEY = 'ga:clientId';
            window['ga']('create', 'XXXX-XXXXX', {
                'storage': 'none',
                'clientId': localStorage.getItem(GA_LOCAL_STORAGE_KEY)
            });
            window['ga'](function(tracker) {
                localStorage.setItem(GA_LOCAL_STORAGE_KEY, tracker.get('clientId'));
            });

            // THIS IS FOR FILE URL SUPPORT
            window['ga']('set', 'checkProtocolTask', function(){ /* noop */});
            console.log('GA OK!')
        }

And then I can use GA in regular way: window['ga']('send', 'pageview', screenName); This is because there is no automatic tracking of page changes while serving using file:// protocol.

This solution is very handy as it is DRY, because I have just one way to embed Google Analytics in my app for both hybrid and hosted versions.

ToM
  • 312
  • 2
  • 14
0

I would like to add my 2 cents. As everybody here I had no luck with analytics plugins, so started to look for pure javascript solution.

I followed this answer and it is working for me. Means, I can see in Google Analytics Realtime separated user activity from browser and from iOS simulator. (Have not tested Android yet.)

I changed script a little.

1)

// if we are in the app (the protocol will be file://)
if(document.URL.indexOf('http://') !== 0){

changed to be

if(document.URL.indexOf('http') !== 0){

to include https case.

2) Unrelated to where I am: in browser or mobile app, I track events like this:

ga('send', 'event', '<myAppName>', '<eventName>');

so I can track different applications under same Analytics Property.

In Google Analytics I created one Property and under this Property three Views. One of type Web and two of type Mobile.

Applied custom filter(s) to each view:

To iOS view applied Include filter on field Operating System with value iOS

To Android view applied Include filter on field Operating System with value Android

To Web view applied two Exclude filters on field Operating System with values Android and iOS

Happy cordoving!

yurin
  • 3,512
  • 1
  • 29
  • 29