From db1692a1464025900461f71f2bfb5a763e7795b8 Mon Sep 17 00:00:00 2001 From: Hannes Petersen Date: Sun, 9 Jul 2017 12:30:50 +0200 Subject: [PATCH 1/6] changed trackMetric behaviour for Android and Windows platform to the same as iOS and Browser. trackMetric() now behaves more like addCustomDimension(). --- README.md | 21 +++- android/UniversalAnalyticsPlugin.java | 53 ++++++---- windows/GoogleAnalyticsProxy.js | 136 ++++++++++++-------------- www/analytics.js | 11 ++- 4 files changed, 124 insertions(+), 97 deletions(-) diff --git a/README.md b/README.md index 6beed024..8bf2d324 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,18 @@ To track an Event and create a new session: * `window.ga.trackEvent('Category', 'Action', 'Label', Value, true)` Label, Value and newSession are optional, Value is numeric, newSession is true/false To track custom metrics: -* `window.ga.trackMetric('key', Value)` Value is optional +* `window.ga.trackMetric(Key, 'Value')` +* Key should be integer index of the dimension i.e. send `1` instead of `metric1` for the first custom metric you are tracking, +* Value will be parsed as an integer, or a fixed point decimal value, if the metric is configured to a currency type in the analytics backend. +* e.g. `window.ga.trackMetric(1, 'Value', success, error)` +* trackMetric doesn't actually send a hit, it's behaving more like an addCustomMetric method (see `addCustomDimension()`). +* The metric is then added to every hit (view, event, error, etc...) sent, but the defined scope of the custom metric in analytics backend +(hit or product) will determine, at processing time, which hits are associated with the metric value. +* **Issue for Ionic 2** users: currently `@ionic-native/google-analytics` defines the typescript signature with `trackMetric(key: string, value?: any)`. +So be aware to pass the metric index as a string formatted integer and a non empty string as a value, like `window.ga.trackMetric('1', 'Value', success, error)`! +* **Issue for Windows platform**: there is currently a bug in version 1.5.2 of the [UWP.SDKforGoogleAnalytics.Native package via NuGet](http://nuget.org/packages/UWP.SDKforGoogleAnalytics.Native), +that for metrics the wrong data specifier `cd` is taken, whereas `cm` should be the correct specifier. +So as long as this bug is not fixed, trackMetrics will overwrite previous addCustomDimension with same index!! To track an Exception: * `window.ga.trackException('Description', Fatal)` where Fatal is boolean @@ -88,9 +99,11 @@ To add a Transaction Item (Ecommerce) * `window.ga.addTransactionItem('ID', 'Name', 'SKU', 'Category', Price, Quantity, 'Currency Code')` where Price and Quantity are numeric To add a Custom Dimension -* `window.ga.addCustomDimension('Key', 'Value', success, error)` -* Key should be integer index of the dimension i.e. send `1` instead of `dimension1` for the first custom dimension you are tracking. -* e.g. `window.ga.addCustomDimension(1, 'Value', success, error)` +* `window.ga.addCustomDimension(Key, 'Value', success, error)` +* Key should be integer index of the dimension i.e. send `1` instead of `dimension1` for the first custom dimension you are tracking, +e.g. `window.ga.addCustomDimension(1, 'Value', success, error)`. +* The dimension is then added to every hit (view, event, error, etc...) sent, but the defined scope of the custom dimension in analytics backend +(hit or product) will determine, at processing time, which hits are associated with the dimension value. To set a UserId: * `window.ga.setUserId('my-user-id')` diff --git a/android/UniversalAnalyticsPlugin.java b/android/UniversalAnalyticsPlugin.java index 23c20023..eaafaaf4 100644 --- a/android/UniversalAnalyticsPlugin.java +++ b/android/UniversalAnalyticsPlugin.java @@ -41,6 +41,7 @@ public class UniversalAnalyticsPlugin extends CordovaPlugin { public Boolean trackerStarted = false; public Boolean debugModeEnabled = false; public HashMap customDimensions = new HashMap(); + public HashMap customMetrics = new HashMap(); public Tracker tracker; @@ -177,9 +178,9 @@ private void addCustomDimension(Integer key, String value, CallbackContext callb callbackContext.success("custom dimension started"); } - private void addCustomDimensionsToHitBuilder(T builder) { + private void addCustomDimensionsAndMetricsToHitBuilder(T builder) { //unfortunately the base HitBuilders.HitBuilder class is not public, therefore have to use reflection to use - //the common setCustomDimension (int index, String dimension) method + //the common setCustomDimension (int index, String dimension) and setCustomMetrics (int index, String dimension) methods try { Method builderMethod = builder.getClass().getMethod("setCustomDimension", Integer.TYPE, String.class); @@ -196,6 +197,23 @@ private void addCustomDimensionsToHitBuilder(T builder) { } catch (SecurityException e) { } catch (NoSuchMethodException e) { } + + try { + Method builderMethod = builder.getClass().getMethod("setCustomMetric", Integer.TYPE, String.class); + + for (Entry entry : customMetrics.entrySet()) { + Integer key = entry.getKey(); + String value = entry.getValue(); + try { + builderMethod.invoke(builder, (key), value); + } catch (IllegalArgumentException e) { + } catch (IllegalAccessException e) { + } catch (InvocationTargetException e) { + } + } + } catch (SecurityException e) { + } catch (NoSuchMethodException e) { + } } private void trackView(String screenname, String campaignUrl, boolean newSession, CallbackContext callbackContext) { @@ -208,7 +226,7 @@ private void trackView(String screenname, String campaignUrl, boolean newSession tracker.setScreenName(screenname); HitBuilders.ScreenViewBuilder hitBuilder = new HitBuilders.ScreenViewBuilder(); - addCustomDimensionsToHitBuilder(hitBuilder); + addCustomDimensionsAndMetricsToHitBuilder(hitBuilder); if(!campaignUrl.equals("")){ hitBuilder.setCampaignParamsFromUrl(campaignUrl); @@ -234,7 +252,7 @@ private void trackEvent(String category, String action, String label, long value if (null != category && category.length() > 0) { HitBuilders.EventBuilder hitBuilder = new HitBuilders.EventBuilder(); - addCustomDimensionsToHitBuilder(hitBuilder); + addCustomDimensionsAndMetricsToHitBuilder(hitBuilder); if(!newSession){ tracker.send(hitBuilder @@ -260,21 +278,18 @@ private void trackEvent(String category, String action, String label, long value } private void trackMetric(Integer key, String value, CallbackContext callbackContext) { - if (!trackerStarted) { - callbackContext.error("Tracker not started"); + if (key <= 0) { + callbackContext.error("Expected positive integer argument for key."); return; } - if (key >= 0) { - HitBuilders.ScreenViewBuilder hitBuilder = new HitBuilders.ScreenViewBuilder(); - tracker.send(hitBuilder - .setCustomMetric(key, Float.parseFloat(value)) - .build() - ); - callbackContext.success("Track Metric: " + key + ", value: " + value); - } else { - callbackContext.error("Expected integer key: " + key + ", and string value: " + value); + if (null == value || value.length() == 0) { + callbackContext.error("Expected non-empty string argument for value."); + return; } + + customMetrics.put(key, value); + callbackContext.success("custom metric started"); } private void trackException(String description, Boolean fatal, CallbackContext callbackContext) { @@ -285,7 +300,7 @@ private void trackException(String description, Boolean fatal, CallbackContext c if (null != description && description.length() > 0) { HitBuilders.ExceptionBuilder hitBuilder = new HitBuilders.ExceptionBuilder(); - addCustomDimensionsToHitBuilder(hitBuilder); + addCustomDimensionsAndMetricsToHitBuilder(hitBuilder); tracker.send(hitBuilder .setDescription(description) @@ -306,7 +321,7 @@ private void trackTiming(String category, long intervalInMilliseconds, String na if (null != category && category.length() > 0) { HitBuilders.TimingBuilder hitBuilder = new HitBuilders.TimingBuilder(); - addCustomDimensionsToHitBuilder(hitBuilder); + addCustomDimensionsAndMetricsToHitBuilder(hitBuilder); tracker.send(hitBuilder .setCategory(category) @@ -329,7 +344,7 @@ private void addTransaction(String id, String affiliation, double revenue, doubl if (null != id && id.length() > 0) { HitBuilders.TransactionBuilder hitBuilder = new HitBuilders.TransactionBuilder(); - addCustomDimensionsToHitBuilder(hitBuilder); + addCustomDimensionsAndMetricsToHitBuilder(hitBuilder); tracker.send(hitBuilder .setTransactionId(id) @@ -353,7 +368,7 @@ private void addTransactionItem(String id, String name, String sku, String categ if (null != id && id.length() > 0) { HitBuilders.ItemBuilder hitBuilder = new HitBuilders.ItemBuilder(); - addCustomDimensionsToHitBuilder(hitBuilder); + addCustomDimensionsAndMetricsToHitBuilder(hitBuilder); tracker.send(hitBuilder .setTransactionId(id) diff --git a/windows/GoogleAnalyticsProxy.js b/windows/GoogleAnalyticsProxy.js index b101a6d2..8643051e 100644 --- a/windows/GoogleAnalyticsProxy.js +++ b/windows/GoogleAnalyticsProxy.js @@ -3,12 +3,13 @@ var _supported = null; // set to null so we can check first time var _tracker = null; var _customDimensions = {}; +var _customMetrics = {}; function isSupported() { // if not checked before, run check if (_supported === null) { _supported = (GoogleAnalytics && GoogleAnalytics.AnalyticsManager && GoogleAnalytics.AnalyticsManager.current && - GoogleAnalytics.HitBuilder); + GoogleAnalytics.HitBuilder); } return _supported; } @@ -66,12 +67,8 @@ function uncaughtExceptionHandler(err) { try { var hit = GoogleAnalytics.HitBuilder.createException(err.message, true); - // add previously added custom dimensions - for (var key in _customDimensions) { - if (_customDimensions.hasOwnProperty(key)) { - hit = hit.setCustomDimension(key, _customDimensions[key]); - } - } + // add previously added custom dimensions and metrics + hit = addCustomDimensionsAndMetrics(hit); const data = hit.build(); getTracker().send(data); @@ -81,9 +78,28 @@ function uncaughtExceptionHandler(err) { return true; } +function addCustomDimensionsAndMetrics(hitBuilder) { + if (hitBuilder) { + // add previously added custom dimensions + for (var key in _customDimensions) { + if (_customDimensions.hasOwnProperty(key)) { + hitBuilder = hitBuilder.setCustomDimension(key, _customDimensions[key]); + } + } + + // add previously added custom metrics + for (var key in _customMetrics) { + if (_customMetrics.hasOwnProperty(key)) { + hitBuilder = hitBuilder.setCustomMetric(key, _customMetrics[key]); + } + } + } + return hitBuilder; +} + module.exports = { - setOptOut: function(win, fail, args) { + setOptOut: function (win, fail, args) { if (!args || args.length === 0 || typeof args[0] !== "boolean") { fail("Expected boolean argument"); return; @@ -93,7 +109,7 @@ module.exports = { win(); }, - enableUncaughtExceptionReporting: function(win, fail, args) { + enableUncaughtExceptionReporting: function (win, fail, args) { if (!args || args.length === 0 || typeof args[0] !== "boolean") { fail("Expected boolean argument"); return; @@ -114,23 +130,23 @@ module.exports = { win(); }, - dispatch: function(win, fail, args) { + dispatch: function (win, fail, args) { getAnalyticsManager().dispatchAsync().done(win, fail); }, - debugMode: function(win, fail, args) { + debugMode: function (win, fail, args) { const ga = getAnalyticsManager(); ga.isDebug = true; // hook debug events ga.addEventListener("hitfailed", onHitFailed); ga.addEventListener("hitsent", onHitSent); - ga.addEventListener("hitmailformed", onHitMalformed); + ga.addEventListener("hitmailformed", onHitMalformed); win(); }, - startTrackerWithId: function(win, fail, args) { + startTrackerWithId: function (win, fail, args) { if (!args || args.length === 0 || args[0] === "") { fail("Expected non empty string argument"); return; @@ -140,7 +156,7 @@ module.exports = { fail("Expected numeric integer argument"); return; } - + if (isTrackerStarted()) { fail("Tracker already started!"); return; @@ -158,8 +174,8 @@ module.exports = { _tracker = ga.createTracker(args[0]); win(); }, - - setUserId: function(win, fail, args) { + + setUserId: function (win, fail, args) { if (!args || args.length === 0 || args[0] === "") { fail("Expected non empty string argument"); return; @@ -169,7 +185,7 @@ module.exports = { win(); }, - setAnonymizeIp: function(win, fail, args) { + setAnonymizeIp: function (win, fail, args) { if (!args || args.length === 0 || typeof args[0] !== "boolean") { fail("Expected boolean argument"); return; @@ -179,12 +195,12 @@ module.exports = { win(); }, - setAllowIDFACollection: function() { + setAllowIDFACollection: function () { // not supported fail("not supported on Windows platform"); }, - setAppVersion: function(win, fail, args) { + setAppVersion: function (win, fail, args) { if (!args || args.length === 0 || args[0] === "") { fail("Expected non empty string argument"); return; @@ -194,52 +210,42 @@ module.exports = { win(); }, - getVar: function(win, fail, args) { + getVar: function (win, fail, args) { if (!args || args.length === 0 || args[0] === "") { fail("Expected non empty string argument"); return; } - + const value = getTracker().get(args[0]); win(value); }, - setVar: function(win, fail, args) { + setVar: function (win, fail, args) { if (!args || args.length === 0 || args[0] === "") { fail("Expected non empty string argument"); return; } - + getTracker().set(args[0], args[1]); win(); }, - trackMetric: function(win, fail, args) { - if (!args || args.length === 0) { - fail("Expected positive numeric integer argument"); - return; - } - const key = Number.parseInt(args[0]); - if (Number.isNaN(key) || key < 0) { + trackMetric: function (win, fail, args) { + if (!args || args.length === 0 || !Number.isInteger(args[0]) || args[0] < 0) { fail("Expected positive numeric integer argument"); return; } - var metric = Number.NaN; - if (args.length >= 2) { - metric = Number.parseFloat(String(args[1])); - } - if (Number.isNaN(metric)) { - fail("Expected numeric integer argument"); + if (args.length < 1 || args[2] === "") { + fail("Expected non empty string argument"); return; } - const data = GoogleAnalytics.HitBuilder.createScreenView().setCustomMetric(key, metric).build(); - getTracker().send(data); + _customMetrics[args[0]] = args[1]; win(); }, - addCustomDimension: function(win, fail, args) { + addCustomDimension: function (win, fail, args) { if (!args || args.length === 0 || !Number.isInteger(args[0]) || args[0] < 0) { fail("Expected positive numeric integer argument"); return; @@ -254,30 +260,26 @@ module.exports = { win(); }, - addTransaction: function(win, fail, args) { + addTransaction: function (win, fail, args) { // not supported fail("not supported on Windows platform"); }, - addTransactionItem: function(win, fail, args) { + addTransactionItem: function (win, fail, args) { // not supported fail("not supported on Windows platform"); }, - trackView: function(win, fail, args) { + trackView: function (win, fail, args) { if (!args || args.length === 0 || args[0] === "") { fail("Expected non empty string argument"); return; } var hit = GoogleAnalytics.HitBuilder.createScreenView(args[0]); - - // add previously added custom dimensions - for (var key in _customDimensions) { - if (_customDimensions.hasOwnProperty(key)) { - hit = hit.setCustomDimension(key, _customDimensions[key]); - } - } + + // add previously added custom dimensions and metrics + hit = addCustomDimensionsAndMetrics(hit); if (args.length >= 2 && args[1] !== "" && getAnalyticsManager().isDebug === true) { console.warn("Campaign details not supported on Windows platform!"); @@ -292,7 +294,7 @@ module.exports = { win(); }, - trackEvent: function(win, fail, args) { + trackEvent: function (win, fail, args) { if (!args || args.length < 2 || args[0] === "" || args[1] === "") { fail("Expected non empty string argument"); return; @@ -305,19 +307,15 @@ module.exports = { var hit = GoogleAnalytics.HitBuilder.createCustomEvent(args[0], args[1], args[2] || null, args[3] || 0); - // add previously added custom dimensions - for (var key in _customDimensions) { - if (_customDimensions.hasOwnProperty(key)) { - hit = hit.setCustomDimension(key, _customDimensions[key]); - } - } + // add previously added custom dimensions and metrics + hit = addCustomDimensionsAndMetrics(hit); const data = hit.build(); getTracker().send(data); win(); }, - trackException: function(win, fail, args) { + trackException: function (win, fail, args) { if (!args || args.length === 0 || args[0] === "") { fail("Expected non empty string argument"); return; @@ -326,19 +324,15 @@ module.exports = { const fatal = ((args[1] || false) === true); var hit = GoogleAnalytics.HitBuilder.createException(args[0], fatal); - // add previously added custom dimensions - for (var key in _customDimensions) { - if (_customDimensions.hasOwnProperty(key)) { - hit = hit.setCustomDimension(key, _customDimensions[key]); - } - } + // add previously added custom dimensions and metrics + hit = addCustomDimensionsAndMetrics(hit); const data = hit.build(); getTracker().send(data); win(); }, - trackTiming: function(win, fail, args) { + trackTiming: function (win, fail, args) { if (!args || args.length === 0 || args[0] === "") { fail("Expected non empty string argument"); return; @@ -354,20 +348,16 @@ module.exports = { return; } - var hit = GoogleAnalytics.HitBuilder.createTiming(args[0], args[2] || null, - args[1] || 0, args[3] || null); + var hit = GoogleAnalytics.HitBuilder.createTiming(args[0], args[2] || null, + args[1] || 0, args[3] || null); - // add previously added custom dimensions - for (var key in _customDimensions) { - if (_customDimensions.hasOwnProperty(key)) { - hit = hit.setCustomDimension(key, _customDimensions[key]); - } - } + // add previously added custom dimensions and metrics + hit = addCustomDimensionsAndMetrics(hit); const data = hit.build(); getTracker().send(data); win(); } - + }; require("cordova/exec/proxy").add("UniversalAnalytics", module.exports); diff --git a/www/analytics.js b/www/analytics.js index 03b4a9d4..f47c96e7 100644 --- a/www/analytics.js +++ b/www/analytics.js @@ -51,7 +51,16 @@ UniversalAnalyticsPlugin.prototype.debugMode = function(success, error) { }; UniversalAnalyticsPlugin.prototype.trackMetric = function(key, value, success, error) { - cordova.exec(success, error, 'UniversalAnalytics', 'trackMetric', [key, value]); + // as key was formerly documented to be of type string, + // we need to at least accept string formatted numbers and pass the converted number + var numberKey = key; + if (typeof key === "string") { + numberKey = Number.parseInt(key); + if (isNaN(numberKey)) { + throw Error("key must be a valid integer or string formatted integer"); + } + } + cordova.exec(success, error, 'UniversalAnalytics', 'trackMetric', [numberKey, value]); }; UniversalAnalyticsPlugin.prototype.trackView = function(screen, campaignUrl, newSession, success, error) { From a2a146c2beccbd4fc46a57d07a4b31db90132dd5 Mon Sep 17 00:00:00 2001 From: Hannes Petersen Date: Sun, 9 Jul 2017 20:27:01 +0200 Subject: [PATCH 2/6] added conversion of trackMetric() value parameter to string. --- www/analytics.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/www/analytics.js b/www/analytics.js index f47c96e7..1a37b9a9 100644 --- a/www/analytics.js +++ b/www/analytics.js @@ -60,7 +60,16 @@ UniversalAnalyticsPlugin.prototype.trackMetric = function(key, value, success, e throw Error("key must be a valid integer or string formatted integer"); } } - cordova.exec(success, error, 'UniversalAnalytics', 'trackMetric', [numberKey, value]); + + // as google analytics sdk expects value of type string and internally converts it to type number, + // this plugin expects a number as value. + // all platform implementations expect value of type string, + // so value has to be casted to string type before calling the platform plugin. + var stringValue = value; + if (typeof value !== "string") { + stringValue = String(value); + } + cordova.exec(success, error, 'UniversalAnalytics', 'trackMetric', [numberKey, stringValue]); }; UniversalAnalyticsPlugin.prototype.trackView = function(screen, campaignUrl, newSession, success, error) { From 46e592d8ca43c8230e49221e549855237dd6bcc7 Mon Sep 17 00:00:00 2001 From: Hannes Petersen Date: Mon, 10 Jul 2017 19:12:37 +0200 Subject: [PATCH 3/6] fixed trackMetric value parameter to float for Android implementation. --- android/UniversalAnalyticsPlugin.java | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/android/UniversalAnalyticsPlugin.java b/android/UniversalAnalyticsPlugin.java index 2de56083..606e976e 100644 --- a/android/UniversalAnalyticsPlugin.java +++ b/android/UniversalAnalyticsPlugin.java @@ -41,7 +41,7 @@ public class UniversalAnalyticsPlugin extends CordovaPlugin { public Boolean trackerStarted = false; public Boolean debugModeEnabled = false; public HashMap customDimensions = new HashMap(); - public HashMap customMetrics = new HashMap(); + public HashMap customMetrics = new HashMap(); public Tracker tracker; @@ -180,7 +180,7 @@ private void addCustomDimension(Integer key, String value, CallbackContext callb private void addCustomDimensionsAndMetricsToHitBuilder(T builder) { //unfortunately the base HitBuilders.HitBuilder class is not public, therefore have to use reflection to use - //the common setCustomDimension (int index, String dimension) and setCustomMetrics (int index, String dimension) methods + //the common setCustomDimension (int index, String dimension) and setCustomMetrics (int index, Float metric) methods try { Method builderMethod = builder.getClass().getMethod("setCustomDimension", Integer.TYPE, String.class); @@ -199,11 +199,11 @@ private void addCustomDimensionsAndMetricsToHitBuilder(T builder) { } try { - Method builderMethod = builder.getClass().getMethod("setCustomMetric", Integer.TYPE, String.class); + Method builderMethod = builder.getClass().getMethod("setCustomMetric", Integer.TYPE, Float.TYPE); - for (Entry entry : customMetrics.entrySet()) { + for (Entry entry : customMetrics.entrySet()) { Integer key = entry.getKey(); - String value = entry.getValue(); + Float value = entry.getValue(); try { builderMethod.invoke(builder, (key), value); } catch (IllegalArgumentException e) { @@ -288,7 +288,15 @@ private void trackMetric(Integer key, String value, CallbackContext callbackCont return; } - customMetrics.put(key, value); + Float floatValue; + try { + floatValue = Float.parseFloat(value); + } catch (NumberFormatException e) { + callbackContext.error("Expected string formatted number for value."); + return; + } + + customMetrics.put(key, floatValue); callbackContext.success("custom metric started"); } From 43c3acad808c0c0b130ff1849866305d69f560ad Mon Sep 17 00:00:00 2001 From: Hannes Petersen Date: Mon, 10 Jul 2017 19:13:40 +0200 Subject: [PATCH 4/6] fixed trackMetric value parameter to number for Windows implementation. --- windows/GoogleAnalyticsProxy.js | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/windows/GoogleAnalyticsProxy.js b/windows/GoogleAnalyticsProxy.js index 8643051e..4623cb9c 100644 --- a/windows/GoogleAnalyticsProxy.js +++ b/windows/GoogleAnalyticsProxy.js @@ -235,13 +235,25 @@ module.exports = { fail("Expected positive numeric integer argument"); return; } - - if (args.length < 1 || args[2] === "") { - fail("Expected non empty string argument"); + + if (args.length < 1) { + fail("Expected second argument"); return; + } + var value = args[1]; + if (typeof args[1] !== "number") { + if (typeof args[1] !== "string") { + fail("Expected either numeric or string formatted number argument"); + return; + } + value = Number.parseFloat(args[1]); + if (isNaN(value)) { + fail("Expected either numeric or string formatted number argument"); + return; + } } - _customMetrics[args[0]] = args[1]; + _customMetrics[args[0]] = value; win(); }, @@ -251,7 +263,7 @@ module.exports = { return; } - if (args.length < 1 || args[2] === "") { + if (args.length < 1 || args[1] === "") { fail("Expected non empty string argument"); return; } From a8d804bc89afe3d590697a4e9a4bc8767c071746 Mon Sep 17 00:00:00 2001 From: Hannes Petersen Date: Mon, 10 Jul 2017 19:15:09 +0200 Subject: [PATCH 5/6] hopefully clarified comment on trackMetric value conversion to string for backwards compatibility. --- www/analytics.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/www/analytics.js b/www/analytics.js index 1a37b9a9..b96f9b25 100644 --- a/www/analytics.js +++ b/www/analytics.js @@ -61,10 +61,9 @@ UniversalAnalyticsPlugin.prototype.trackMetric = function(key, value, success, e } } - // as google analytics sdk expects value of type string and internally converts it to type number, - // this plugin expects a number as value. - // all platform implementations expect value of type string, - // so value has to be casted to string type before calling the platform plugin. + // as value was formerly documented to be of type string + // and therefore platform implementations expect value parameter of type string, + // we need to cast the value parameter to string - although gathered metrics are infact number types. var stringValue = value; if (typeof value !== "string") { stringValue = String(value); From faf28e3c8cb41024ba2aa634e30e34ee931f24d4 Mon Sep 17 00:00:00 2001 From: Hannes Petersen Date: Mon, 10 Jul 2017 19:15:50 +0200 Subject: [PATCH 6/6] changed example comment on trackMetric doc (value parameter is not optional!) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e4580073..a58631ec 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ window.ga.trackEvent('Category', 'Action', 'Label', Value, true)// Label, Value //(trackMetric doesn't actually send a hit, it's behaving more like the addCustomDimension() method. // The metric is afterwards added to every hit (view, event, error, etc...) sent, but the defined scope of the custom metric in analytics backend // (hit or product) will determine, at processing time, which hits are associated with the metric value.) -window.ga.trackMetric(key, Value)// Key and value are numeric type, Value is optional +window.ga.trackMetric(Key, Value) // Key and value are numeric type //To track an Exception: window.ga.trackException('Description', Fatal)//where Fatal is boolean @@ -130,7 +130,7 @@ window.ga.debugMode() // set's dry run mode on Android and Windows platform, so that all hits are only echoed back by the google analytics service and no actual hit is getting tracked! // **Android quirk**: verbose logging within javascript console is not supported. To see debug responses from analytics execute // `adb shell setprop log.tag.GAv4 DEBUG` and then `adb logcat -v time -s GAv4` to list messages -// (see [Android SDK Documentation on deprected Logger class](https://developers.google.com/android/reference/com/google/android/gms/analytics/Logger)) +// (see https://developers.google.com/android/reference/com/google/android/gms/analytics/Logger) //To enable/disable automatic reporting of uncaught exceptions window.ga.enableUncaughtExceptionReporting(Enable, success, error)// where Enable is boolean