I am using a simple Google Analytics code. When I look the real-time users on Google Analytics, I can see "1 active user now". There is no problem, but I am suspicious that this code will give wrong results on Google Analytics because When I look their guides, their implementations is different. Can this code give wrong result on Google Analytics?
My Code:
Declaration in MainActivity
public static GoogleAnalytics analytics;
public static Tracker tracker;
Implementation in onCreate
analytics = GoogleAnalytics.getInstance(this);
analytics.setLocalDispatchPeriod(1800);
tracker = analytics.newTracker(unitid);
tracker.enableExceptionReporting(true);
tracker.enableAdvertisingIdCollection(true);
tracker.enableAutoActivityTracking(true);
No more code, just 6 lines.
If there is no problem for this code, why their guide is complex?
Note: There is no problem now, but I am suspicious about future.
This is, indeed, close to the simplest implementation possible.
The problems with it, however, is that:
GA library has hardcoded triggers that are qualified to be "screenviews". While it may be sufficient for very simple apps, it poorly handles layered views logic that is commonly used in more complex apps.
GA library has to send screen identifiers. And there's little to none of what it can use for that. So what it does is it tries to pull class names as identifiers for screen names when no explicit name is set (which is the case in automated tracking). This results in the data being hard to read.
Personally I've never seen auto activity tracking being used in production. Maybe it makes sense to be used by the developers to improve exceptions logging in Firebase, but the data is way too inconsistent and hard to decode to be flexibly use for business reporting.
You achieve a lot better tracking quality when you set each screenname explicitly. That is the best practice.
Related
Very open architectural question.
I have an Android offline app.
In one of the actions user can change a configuration, in my specific case it is the day of the forecast.
So to do that, the flow is this:
Activity on click event;
Preferences View Model;
Preferences Business;
And finally persisted on the persistence layer;
The actual effect will happen in parallel (no important for my question).
My questions are:
Where is the best place to add the analytics track?
What exactly should I be considering when positioning my analytics track events?
Just in case, this is the app I'm talking about: https://play.google.com/store/apps/details?id=pozzo.apps.travelweather
Thank you
Analytics is part of the domain layer, so It should ideally be kept in the domain layer. Often projects have analytics in the view layer (ViewControllers, activities or fragments or ViewModels). This leads to inconsistency and analytics calls are often fired from views or view models, controllers etc.
Therefore, it is ideal to keep analytics inside UserCase/interactor classes, these are often re-usable classes, which makes logging easier with less duplication.
In terms of clean architecture analytics it's business layer, so it should be implemented in Interactor/Use case, but I think it's not so bad to keep analytics in a view, because it's simplest way.
I have an application with a reused activity (its used for different purposes so just tracking the activity name would not help me, thats why I want to define the screen name manually while still using the EasyTracker. My code looks like this:
EasyTracker t = EasyTracker.getInstance(this);
t.set(Fields.SCREEN_NAME, screenName);
// MapBuilder map = MapBuilder.createAppView();
// map.set(Fields.SCREEN_NAME, screenName);
// t.send(map.build());
t.activityStart(this);
I got these information from https://developers.google.com/analytics/devguides/collection/android/v3/screens
I dont want to do this without the EasyTracker because I didn't find any information what exactly happens in the methods activityStart() and activityStop() of the easy tracker so I cant reproduce this behaviour with a custom tracker and I think the inforation which is collected in the activityStart() method in addition to the screen name is also very usefull. So has someone experience with defining custom values in the easy tracker? Is it a good way to do it this way or is there a better solution?
If anyone comes across the question, the as per the v3 of the Google Analytics SDK,
EasyTracker.getInstance(this).activityStart(SCREEN_NAME); // Add this method.
where SCREEN_NAME is the user defined constant for the reused Activity.
Using custome screen names instead of the default ones i.e the full qualified path name of the Activity
doesn't cause any issues in data collection.
Recommendation, Use Google Tag Manager for your Tracking purpose, it provide you better flexibility like changing the UA property ID in future as well the screen names to be sent to Google Analytics. Read more # Developer Guide For Android
I have an application which most of the time works in the background, as a Service. There is a lot of examples and tutorials online on how you can use Google Analytics API with EasyTracker library to track multiple Activities, but there is not a single one that explains, how to use Google Analytics API in a Service. Is it even possible?
Good news! You can. and it's quite easy.
You'll need the application context let's call it mCtx
When you have this you need an instance of GoogleAnalytics, you can get it by calling
GoogleAnalytics mGaInstance = GoogleAnalytics.getInstance(mCtx);
now you need to set any parameters you want (which you would normaly put in analytics.xml when using EasyTracker).
now you need a Tracker instance:
Tracker mTracker = mGaInstance.getTracker("UA-XXXX-Y"); // your ID here
and that's basically it.. now you can send events with this tracker
mTracker.sendEvent(....);
etc..
Hope this helps. This is the very basics but GoogleAnalytics and Tracker replace the EasyTracker.
You can read more about it here:
Advanced Configuration - Android SDK
Just note that until you'll see the reports on the GA website, it can take up to 24 hours.. so be patient :) or use mGaInstance.setDebug(true) to see in the logcat that it has been sent
I would suggest not to do so unless you are very sure what you are doing.
I implemented GA events in my service but it corrupted a lot of my GA stats such as session duration, daily percentage of new sessions, daily sessions etc.
GA thinks that events are caused after a screen view and so it pushes the GA event with a screen name "(not set)".
Since services ran in the background a lot of times, it ended up corrupting the various stats.
The real-time display of active users also went wrong.
So I'm still mucking around with this Google Analytics SDK. According to this, I should be able to send custom vars with a visitor scope that include the app version, and the phone model.
Using tracker.getVisitorCustomVar(i) I can see that the information is indeed stored, and the log shows NetWorkRequestUtil/ConstructPageviewRequestPath with a message that contains the custom vars.
But it does not show up in the analytics report along with the other tracking information. I thought I would find it under Visitors->Custom Variables, but that only says
There is no data for this view.
Where can I see the custom variables? :(
How long ago did you incorporate the custom vars? Analytics is not realtime, there can be an --i think-- 24 hour gap?
I'm doing this, and it works for me. I'm assuming you do get other data, so your initialisation and 'dispatching' of the tracker is correct?
You can set your customvar like so (as I imagine you are doing allready).
tracker.setCustomVar(TRACK_SLOT_AUTH, TRACK_CVAR_AUTH, isAuth, TRACK_SCOPE_SESSION);
(using global vars to be sure not to override already used slots here, but the intention should be clear)
The data shows up under Visitors->Custom Variables
Custom variables have been replaced by Custom Dimensions and Metrics.
https://developers.google.com/analytics/devguides/collection/android/v2/migration#update-methods
I already published an android app where you can see a list of specific objects and detailed informations about them. The list changes every day but some of the objects can appear again.
The application is communicating with a PHP server over HTTP and periodically pulls the list of objects.
I now plan to extend the app to make it possible to rate the objects and add a comment similar to how it is done in the android market. I'd like to avoid forcing the user to sign up for an account for being able to comment.
I see two problems:
The comment-system could be abused by spammers
A comment could be added from another system
So my questions are:
How to protect the system from spam?
How to authenticate the application with the server?
How do I limit the number of comments to one per user and object?
What about the androids device id? Is it unique enough to use it as identifier for the user?
Which other problems do you see?
2020 Commenting/Rating/Reviews Options
Since Socialize is out, here are a few options you can explore:
Build your own comment/rating implementation. Personally I love reddit and how it handles nested comments and ratings. Here's a library I found that implements it beautifully. Please note you'll need to tie this with a cloud-database. This is based on groupie. Article & implementation. Many ways to do this - https://stackoverflow.com/a/59472206/668240
Disqus - SDK's coming soon to iOS and Android.
BazaarVoice - commercial
Social Networks SDKs like Facebook, Twitter, etc. Personally I dislike this as we'll need to authenticate users with respective networks to use the APIs. It's like we are shipping off users of our apps to social networks. If you don't have a problem with that - then it might be for you
Legacy Option in 2014:
You can try out Socialize SDK which is open-source and a really good SDK for the rating and commenting you are looking for. It already has a well-functioning Commenting system built-in along with a 'like/love' facility and sharing to FB and Twitter. Each 'entity' (object in your case) can have metadata associated with it. So all you have to do is construct/use a rating widget, then send that rating with the entity attached to your object. To display your rating/comment is as simple as retrieving them from Socialize.
Each object (element from your app) should be associated with an entity which has a unique key in the form of a URL - sort of like a primary key to recognize your items. This entity can have meta-data - any data that you can insert on behalf of your object. Once you do that, you can retrieve that metadata any time you want.
I've been using Socialize for around a year now. They've matured over this period and are always aspiring to be the best at what they do.
Look at the Socialize Bar at the bottom. Its can be customized to your needs.
What's more - Socialize is free.
As for your questions:
There is comment moderation built into the Socialize Web Component
where you can filter out anything you feel is out of place.
Socialize allows you to authenticate through Facebook and Twitter.
Limiting to one comment per user can be achieved by using their User
and Comments API.
Socialize has both Anonymous authentication as well as Social A/c
authentication. I believe you can remove anonymous auth. So that
ensure that every user is authenticated before rating/commenting.
For authentication, you could use OpenID like StackOverflow does or Facebook authentication. Once you have them authentication, it shoud be easy to limit the number of comments to one per user per object. As far as spam, you could follow StackOverflow's model and allow users to vote comments up or down or flag as spam. Perhaps users with comments that have been voted up would have more power and be able to flag comments as spam.
You'll need some sort of rate limiting. I've used this one in this example before.
So you need a table with the user's ID and how many api calls they have left, and then when their last api call was. Then use the algorithm to update the values in the table every time a method is called.
Read through this, I think it should be possible to create an UUID for every case:
http://android-developers.blogspot.de/2011/03/identifying-app-installations.html
And then keep a hidden api key which is hard coded, or at least get's everytime calculated the same or in enigma style influenced by the time it is used. But you will be never be sure, that it won't be find out by crackers/hackers and maybe abused, you will always have this Problem.
Authenticate with the UUID of the user + api-key.