RACHEL COLLINS: Hey, everybody.
Thanks for joining me for the part 2
video of "Getting Started with Analytics on Android."
This time, we're going to be talking
about user properties and user-scoped custom dimensions.
What are they?
What's the relationship between them?
And how can you use them to better understand your users?
[MUSIC PLAYING]
I highly recommend watching part 1 of this series, where
we talked about logging events for analytics with Firebase.
In that video, you should have learned
a few things that will be really helpful for this one
and going forward.
Let's review.
You can log events in the code.
You can register event parameters
and see the generated event reports
in the Firebase Console.
And you should have also learned how
to put a test device into debug mode, which
is really helpful for trying to test whether or not
you're successfully logging analytics data.
That's a high-level review of the last video,
but something has changed in the Firebase Console UI
since that video was made.
I'll review the changes, since they relate to how
you configure user properties.
All of the concepts for logging analytics events are the same.
You're going to log them the same way in the code
and we'll still have to register those event parameters
as custom definitions in the Console
if we want to view those reports.
What has changed is how to navigate there.
Let's take a look.
Over in the Console, let's navigate to events.
We still see that our roll event is being logged as expected.
There's a side tab that says Custom Definitions,
and no surprise, that's where we're
going to go to manage custom definitions.
Let's go over how to register a custom dimension
to track the doubles parameter, just
as we did in the last video.
We'll click Create custom dimensions.
Enter the Dimension name, doubles;
the description, whether or not the user roll
doubles; and select doubles from our list of parameters.
That should all be pretty familiar.
Lastly, we'll choose Event under Scope.
Scope tells us to which data custom metric or dimension
will be applied.
Dimensions and metrics can only have one defined scope
and it can't be changed after they're created.
In this case, we've chosen event for our scope.
Event-scoped properties get their values from event
parameters that we logged in our code--
in this case, the doubles parameter.
Let's click Save to create our doubles dimension.
We can use the event-scoped custom
dimension we just created to report on as many events
as we wish.
For example, if I were to create a second set of dice
in my dice-rolling app with 12 sides,
I could log a 12-sided roll event in my code
with the doubles parameter.
I could then use the doubles dimension
I just defined to create a report of users rolling doubles
on that 12-sided roll event without having to create
another custom dimension.
All right, one last thing to mention with this review.
You may have noticed that the other option for Scope
is User, which is where custom definitions for user properties
are configured--
and will be the topic of the rest of this video.
So enough of that review.
Let's jump into some new content and talk about user properties.
First and foremost, what are they?
User properties are a way to track values for a user, maybe
a user's favorite animal or whether or not a user
is on the premium paid plan of your app.
Unlike our roll event, which occurs over and over again
whenever a user taps Roll in your app,
most user properties aren't changed very often.
They can be thought of as sticky event-scoped properties.
This is not to say that user properties can never
change for a user.
Your user may decide that dogs are their favorite animal
instead of cats, or they may stop
paying for the premium plan.
No matter how you use them in your app,
user properties can have a better understanding
of your app's users.
User properties are core tagging and collection concepts.
They're how you gather data about your users.
How do user properties relate to user-scoped custom dimensions?
User-scoped custom dimensions have
to be registered explicitly in the Console
and their values are supplied by user properties.
They're used for generating reports and doing analysis.
The relationship between user properties
and user-scoped custom dimensions
is the same relationship as event properties
and event-scope custom dimensions.
All in all, user properties and their associated custom
dimensions give better insight into who exactly
is using your app.
For example, do I have more dog or cat people in my app?
You can also filter reports by user scope dimensions
to see how different groups of users use your app.
Are my free tier users spending more time
playing my adventure game than my paid subscribers?
There are user properties that are automatically collected
by Google Analytics-- for example, age, gender, country,
or device model--
plus many more.
But instead of these automatically logged
user properties, we're going to focus
on user properties that are custom to your app
and your business model.
For example, take our dice-rolling app.
Users can tap Roll to roll the dice.
Now we want to know more about our users.
Let's create a dialogue, where our users
can self-declare themselves as either novices or experts.
We can log this information as a user property in the code.
With this information, we can better understand our users
and we can start making critical business decisions
about where to focus our development time or even
our ad spending.
Let's implement this.
In part 1 of the series, we developed our app
with a dice-rolling function.
We click Roll and we can see the results of those rolls.
For this video, we want to get a better understanding
of our users by tracking users' experience levels by setting
a user property.
In the code in the DiceViewModel class,
we make a call to analytics to log the roll event every time
we click the Roll button.
We're going to make a similar call this time
to set a user property.
It'll look like this.
firebaseAnalytic s.setUserProperty
with the name, experience, level,
and let's give it the value expert.
There's a few things less than ideal
about this implementation.
First, we've already decided what experience level our user
is-- expert--
without giving anyone a choice.
Second, doesn't really make sense
to set the user property every time
a user rolls since their experience level doesn't
change with every roll.
Instead, let's ask the developer just once per app session
We use the DiceViewModel class to control calls to analytics
to log the roll event.
So let's use a UserViewModel class to set
the user property we want.
We'll create a Kotlin class, call it UserViewModel,
and once that's created, we'll update
it to inherit from ViewModel.
Let's define the function that sets our user property with
analytics, updateExperienceLevel(),
which takes in one parameter, a string representing the value
that the user has chosen.
Within that function, we'll want to call Firebase Analytics,
so let's create an instance of that.
private val firebaseAnalytics = Firebase.analytics.
And as expected, we'll want to import that
and import analytics, as well.
Then in our function, we can say firebaseAnalytic
s.setUserProperty() and pass the name we want--
in this case, experience_level--
and pass it the parameter, which is the string, novice
or expert, depending on which the user has chosen.
Now you can call this function wherever it makes sense
to update a user's experience level
and pass a string variable representing
what the user's experience level should be updated to.
Let's prompt the user to choose their own experience
level with a dialog.
Over in the MainActivity, when the user opens the app,
the onCreate() method is called.
I've written a function that shows a dialog.
It already implements the UI elements.
The user has two options, to choose novice
or to choose expert.
Here is where it makes sense to set our user property,
so let's call that function we defined.
But first, we'll need to define an instance
of our UserViewModel class as a variable userModel.
Because it's a ViewModel class, like DiceViewModel,
its declaration will look similar.
Then when a user clicks novice, we can call our function
updateExperienceLevel() and pass it the value the user has
chosen--
in this case, novice.
Similarly, when a user clicks expert,
we'll pass the parameter expert to that same function.
We also want to update the UI to display what experience
level the user has chosen.
I've already written a function to do that,
so we'll just call it when the user chooses novice
and when the user chooses expert.
Let's rerun our app.
This is where your learnings from the previous video
hopefully will come in handy.
If you have your device enabled as a debug device, like I do,
you should expect these events to be logged in the debug view.
Let's choose Expert as our experience level
and log a few events.
Let's go over to debug view to take a look at what analytics
we received.
We can see that our experience_level user property
is being set to expert.
The UI clearly differentiates between user properties
and events, as you can see.
When our experience_level user property is set,
every event that occurs after will
include this user property.
Let's click into a few of these roll events.
On each, we can see the experience_level is logged.
We can even click on the screen_view event
and see that our user property is there, as well.
If I restart my app and choose Novice as my experience level
this time, we can see that the new experience_level value
is being set to novice.
And now each event following that
includes our user property.
I'm confident now that my code is working
and that my analytics events and user properties
are logged in my code.
Let's register a custom definition
for our user property.
To do that, we'll go over to Custom Definitions.
This is where I can see the doubles event
that I created earlier.
Now I'm following a similar process,
but for a user-scoped dimension.
I'll click Create custom dimensions,
and give this dimension the name experience_level.
Scope is User.
Then we'll add a Description, whether the user identifies
as an expert or novice, and User property
experience_level to match the one we logged in our code.
As we talked about earlier, scope
defines to which data a custom metric or dimension
will be applied.
User-scoped custom dimensions are
populated from user properties and will automatically
be reported with every event registered
as we saw over in debug view.
After clicking Save, we can see our new user-scoped custom
dimension in our list.
We can also look at our current quota for custom definitions.
We have one user-scoped custom dimension--
that's the experience_level one we just defined;
one event-scoped custom dimension--
that's the doubles one we defined earlier in this video;
and lastly, we have one event-scoped custom metric.
That's the sum metric we defined in the last video.
To review, we have custom dimensions,
which are discrete values, and custom metrics,
which are numerical values.
Then we have different scopes--
user-scoped and event-scoped, where user-scoped
are populated from user properties
and are automatically reported with every event,
and event-scoped, which take their values from event
parameters and can be reported on from as many events
as we choose.
As the quota information shows, there
are limits to how many of each custom definition
we can create.
But this menu helps us keep track.
And if we ever reach the limit, we
can archive any existing definition
we've created to make room for new ones.
All right, we've added our custom definition for the user
property, but we need to wait a few hours for the event report
to generate and show up in the Console.
Finally, it's a few hours later and we
can start looking at the Console to answer questions
about our users.
Let's go over to the event dashboard
and see our user property in action.
As you can see, we're still logging our roll event.
Let's click on the event to see more details.
We can then go up to Filters, User-scoped custom dimensions,
select our experience_level definition,
and choose Expert to filter only by rolls
by self-declared experts.
Hm.
We had some roll events in our app for experts,
but not as many as I expected.
It looks like we have a lot of experts using our app,
but they don't roll the dice as much as I thought they would.
Let's now go look at novices so we can compare.
We'll remove our current filter on experts
and instead add a filter for novice
the same way we did before.
For novices, we had lots of roll events,
way more than for experts.
Plus, we have less novices using our app than experts.
All this means that while we have more experts using
our app, the novices are clicking roll way more
than the expert dice-rollers are.
This makes me think that our novice users are
much more engaged with our current app
than our experts are.
Thanks to user properties and user-scoped custom dimensions,
I'm already beginning to see a potential audience
that I could create.
If I wanted to create an audience consisting of expert
players, I could, say, send them targeted messages
via Firebase Cloud Messaging to help
engage that group of users.
Using audiences is a way to identify
specific groups of users so you, as the app developer,
can develop a tailored user experience.
Now that I have a better understanding of my users,
I've decided to spend some development time adding
advanced functionality to the app
to help engage my expert user audience more.
I think they'd really love to be able to roll that 12-sided die.
I better start writing some code.
Thanks for following along, everybody.
Hopefully, you can get started setting user properties
in your app, creating user-scoped custom dimensions,
and thinking about how to break up your user base into segments
to better understand your users.
If you want more information, take a look
at our lovely documentation.
And last but not least, please subscribe to the Firebase
YouTube channel.
And I'll catch you next time.
[MUSIC PLAYING]