PATRICK MARTIN: Hi, everybody, and welcome
to another "Firecast."
Today, I'll go over the basics of using
Google Analytics and your Kotlin Android application
and maybe help settle an argument or two
amongst your friends.
Against wild accusations of cheating
and maybe a flip table or two, I've
created this dice rolling app to help play a board
game with my friends.
Right now it rolls two standard dice,
that is 2D6, for you cool kids out there,
and outputs the result of each die,
as well as the total rolled.
Of course, not more than 30 seconds
passed before accusations moved from you're
not rolling correctly to the app clearly is cheating.
That can't be the case.
Look at this app.
It's pretty simple.
Two rounded rectangles display the results of each die.
The little label underneath tells me the total.
I also have a big ol' button at the bottom to simulate a roll.
I have a very basic main activity
class that just bridges my layout to an underlying view
model.
This way there won't be any shenanigans when
the user rotates their phone.
I'm also using view bindings to get the relevant controls
for my layout so I don't mess up my fine view by ID calls
and registering an on-click listener for the roll button.
The button click listener and my update UI function
call into this dice view model.
And you can see that it's just using Kotlin's random.nextInt
to update my die.
This should be plenty random for this test.
But how can I prove it?
I'm going to use Google Analytics to track every roll
of every user of this app.
I can then verify at scale that I'm
seeing the distributions I'd expect for a truly random dice
roll.
To start, make sure you already have
a Firebase project set up and configured
for your application.
See the link in the description below to get started.
You also need to make sure you've already explicitly
enabled Google Analytics.
If you'll open up the Analytics dashboard
and see Enable Google Analytics, just click
on that button and associate with the Analytics
account you want to use.
Google Analytics accounts can be thought of as folders.
If your team is already using Google Analytics, for example,
to measure your website, you may already
have a folder structure to follow.
I'm also going to add a dependency
on Firebase Analytics KTX.
Firebase Analytics will work.
But since I'm using Kotlin, I would
like to use the KTX extensions to take advantage
of some fancy Kotlin syntax that'll make my life easier
when logging events.
Finally, I'll go over to my dice view model
and just grab an instance of Firebase Analytics
with firebase.analytics.
Once I do this, Google Analytics immediately
goes to work gathering basic Analytics for my app.
I can see how many active users I have,
overall revenue, and my user retention.
Now that that's out of the way, I'll
jump on over to my handy-dandy view model
and find my roll function.
To log an event, I'll write logEvent
followed by some string for the name of the event.
There are a bunch of suggested events
under FirebaseAnalytics.Event, such as level up and add
to cart.
If your app user flow matches one of these suggestions,
you should definitely use it.
Since Firebase knows about them, it
can do some custom visualization and reporting automatically,
which is a huge win.
Outside of maybe post score, I don't
see anything that could possibly match rolling some dice.
So I'll just make up my own event called Roll.
This still isn't that useful.
The whole purpose of this app is to roll dice.
So I know players are going to roll some dice on it.
To make sure that my dice are rolling fairly,
I'll want to verify that the sum of the two dice
converge to the average over time.
You may be inclined to log an event like roll sum,
such as roll seven.
But the Firebase console won't really
know how to visualize this in a useful manner.
You also only get 500 different events per app.
This technique just burned 11 of them.
This is isn't sustainable in the long run.
Instead, I'll add what's called a parameter to the roll event.
Parameters are additional pieces of custom metadata
that you send out with your event
as a series of key value pairs.
If you're still using Java, you'd have to set up a bundle
and send that with your event.
But thanks to the Firebase Kotlin extensions,
you can use a DCL to just append parameters, like this.
I'll add a long parameter called sum for the sum of two dice.
But parameters can be double, long, or string.
The best part is that I get 25 unique parameters per event.
So I have 24 left to go on roll.
Later, when I view the roll event in the dashboard,
I'll hope to see an average value of seven
for the sum of all my rolls from all of my users.
Another thing that literally everyone
complains about is that they roll doubles too often.
Or more accurately, their opponent
is clearly cheating and getting all the doubles.
A double will happen one out of every six rolls.
So I'll add another parameter called doubles and set this
to the string true if they roll a double or false if they
didn't.
I use strings rather than converting it
to a zero or a one just so it's easier to read
and the Firebase dashboard.
So after running my app and rolling a few times,
I can see that I have one user.
That that'll be me.
But I don't see any events coming in.
What's the deal?
You generally want your Analytics
to have as little impact as possible
on your app's user experience.
It really wouldn't be cool if [? we ?]
added Analytics and immediately users' battery life
tanked and their data usage went through the roof.
So the Google Analytics for Firebase SDK
does something clever.
It will batch up your events and upload them every hour or so.
This uses Google Play services when available.
So these events will get uploaded,
even if these are [? uninstalled to your ?]
application.
Even with this delay, your event reports
will only get generated every few hours or so.
Once you app is in the wild, these optimizations
are pretty useful.
But it's a huge pain when you're debugging them.
I want to know sooner than tomorrow
that everything's working.
To continue, I need to be able to run commands using ADB.
If you run into errors with this command,
see this page linked in the description below.
To start, I can verify that my Analytics are logging correctly
by entering ADB shall setprop log.tag.FA.VERBOSE and FA-SVC
VERBOSE to enable verbose logging of Firebase Analytics
events.
Then I can jump back to Android Studio and click Debug.
If I open my Logcat window, I can select Firebase
from this dropdown box on the side.
This will filter my logging output
to help me view only Firebase-specific logs.
Now, if I roll a few times, I can
see these logging event logs coming through with sum
and doubles appended to the end.
Also note that there are rules around the event and parameter
[? names. ?] Generally, you're safe if use snake case,
like I have.
But if I were to use roll 'em instead of roll
and monitor this output, you can see that I get a log saying,
event will not be logged.
This is a great way to make sure my code is working locally.
But it can also verify that my events are making it
to the server in real time.
Since my package name is com.firebase.example.diceroller,
I'll open up my terminal and type EDB shell setprop
debug.firebase.analytics.app, followed
by com.firebase.example.diceroller.
Now my application will be in debug mode until I enter this
command again, replacing my bundle ID with .none,
or I reboot my phone.
Also note that in debug mode, events
won't get rolled into your overall Analytics data
and won't get included with your BigQuery exports.
This way, you can experiment with event
reporting without polluting your live data.
So now I'll jump on over to the Debug View
under Analytics in my Firebase dashboard then run my app.
I can see my events coming in up here.
I also see doubles and sum and can
expand each one to see the [? values ?] [INAUDIBLE]..
The really cool thing here with debug view
is that since it's a sticky setting, I can unplug my phone
and continue debugging.
If I'm using events to debug app behavior,
I can even put a QA phone into debug mode
and let a tester go wild while monitoring the results.
Since it does take up to 24 hours for an event report
to get generated, let's time travel a bit into the future.
As you can see, my dashboard has been
populated with some event data.
I can apply filters, like I can set this to show the Android
version of my app.
And take note of this in the future.
If I eventually port my app to iOS or the web
and use the same event names and parameters,
I'll be able to view all of my event data
combined into one view.
And if I click on my Roll Event, I
can see more details about it, like how many users
have triggered this event and where in the world
an event came from.
Once you get enough users, and if you activate Google Signals,
you'll also see some demographic information.
But I won't cover that now.
I don't see my parameters, though.
While my event parameters are being sent over,
the console doesn't create reports for every single event
parameter.
By default, only does this for a few parameters
for the suggested events I mentioned earlier.
Now, you can get reports generated
for these event parameters.
And at the time of this writing, you
can do this for about 100 parameters.
But you'll need to tell the console which parameters
you want to see reports for.
To register the sum parameter, I'm
to go back to my Event screen and click Manage Custom
Definitions.
Here you have two things you can create, custom dimensions
and custom metrics.
But these are shared across multiple events,
meaning that once I define sum, it'll
appear identically in any event that has sum as a parameter.
First, let's focus on custom metrics.
These are parameters that describe
something quantitative, such as the sum of your die rolls.
So I'll click Create Custom Metric,
select Sum as the parameter name and leave
the unit of measurement as Standard, since value of a die
doesn't really have a unit associated with it.
This does change how the value is shown in the dashboard,
with Standard letting me see an average of all my rolls.
Doubles, on the other hand, I'm going
to register as a Dimension.
Dimensions are used more for qualitative measurements.
Typical examples include which level the player's on
or the name of a purchased item.
In my case, whether or not you roll doubles
doesn't quite make sense as a numerical range to evaluate.
I am sending up strings, after all.
But I will want to see how many trues I have versus falses.
Unfortunately, adding dimensions and metrics to my events
will not apply retroactively to my reports.
So I'll have to wait another day for new events
to start showing up in my Analytics report
with these parameters included.
And here I am a day later.
Check this out.
I have sum and doubles showing up right here
in the bottom of my roll event.
Right here I see that my average is six.
This should be seven.
Let's go look at my code again.
Aha!
The dice were cheating-ish.
nextInt's max is exclusive.
So I'm only rolling a five-sided die.
Wow.
That's embarrassing.
Let's look at my doubles now.
I can divide this number next to true
and divide it by the total and hope .17, or 17%.
But all bets are off now.
I'll push the change out to my friends with an apology
and make sure that my stats start
to look more correct after a few more days.
So thanks to Google Analytics, I found a fairly subtle bug
and will be able to monitor my application's
health in the future.
If folks still think that my dice are cheating,
I can also use these analytics to design and test
additional changes.
Like, maybe I can add a heat map that
shows the distribution of dice rolls against the expected
average so players can see that their session is fair.
Then I'd be able to measure how many times players
open that heat map, using Google Analytics to see
if it was a useful addition.
And that's it.
With a few clicks and literally five lines of code,
I can efficiently and scalability monitor
the health and usage of my app.
There's still plenty more that I can do,
such as adding custom user properties to further
categorize my event results.
I can even build audiences out of users
that appear to behave similarly, measure
the effectiveness of a future ad campaign,
or gauge the popularity of certain theme dice,
once I offer in-app purchases.
The Firebase dashboard is also only one view into my data.
I can open the Google Analytics dashboard,
or even run complicated queries against all of my data
using BigQuery, depending on my needs and expertise.
But those are all subjects for another video.
Until then, check out the documentation here.
And don't forget to subscribe to the "Firebase" YouTube channel.
Let me know what you want to hear me talk about next,
either in the comments below or [? @puxOr3 ?] on the Twitter.
So long and have a wonderful time.
[MUSIC PLAYING]