[AUDIO LOGO]
SUMIT CHANDEL: Have you ever wanted
to release a really cool new feature for your app
but weren't sure if your users would feel as excited about it
as you did?
Or maybe you had an idea for a new onboarding flow in your app
but imagined a few different ways it could be implemented
and wanted to figure out which option would work best?
Well, Remote Config is well-suited
for both of these scenarios and can provide a solution
in just a few lines of code.
So Remote Config, as the name suggests,
allows you to remotely configure different app experiences
or features and gives you control for how you expose them
to your users.
It does this by providing a set of key-value pairs
that live in the cloud and that are consumed in your app
that you can configure with different values
based on different conditions.
This makes rolling out features, personalizing app experiences,
and running AB tests in your apps
possible with just a few lines of code.
So for example, let's say there's
a new feature you want to test out
but only to 30% of your users at first
to get feedback and see if the feature is stable
and users are liking it.
Well, you can configure a boolean remote config parameter
called new_feature with the value
false for 70% of your users and true for a random 30%
to set this up and test it out.
Or let's say you're building a game
and want to AB test different game difficulties
to see what leads to the most user engagement.
Using more complex remote config parameters, like a JSON
variable, you can configure different game setting variants
and run an AB test to see which one users like best,
or even cater different difficulty
settings for different players based on their skill level.
Also we've recently added personalization
in Remote Config, a new feature which can automatically
select personalized values on a per-user basis using machine
learning algorithms to optimize for a specific goal
you care about.
For example, maybe personalizing the best time
to prompt the user to visit your store
and make a purchase to optimize the likelihood that they'll
buy something.
There are a lot of possibilities,
and one of the great things is that after doing
an initial implementation of remote config
for one of these scenarios, you can keep making changes
without the need to build, deploy, and publish
new versions of your app.
So let's get started on how we can
use Remote Config in my sample Android app.
Meet Saying Hello.
It's a pretty simple app that lets
people say hello to each other in as many words
as they'd like to use.
The app works well enough, but there's definitely
room for improvement.
For one, the current UI is a bit bland.
I wonder if there is a way to make that a bit more
exciting by testing out a new visual element on the screen?
Also, at the moment, there's no limit to how much text
I can enter in my greeting, which can make for some rather
lengthy greeting messages.
I wonder if the length of messages
is impacting how much users read and write greetings in the app
and if there is a sweet spot for a length limit
that will lead to optimal engagement?
Let's use Remote Config to help with both of these use cases.
First, I'll use Remote Config to do
a phased rollout of a new visual element in my interface,
and second, I'll use remote config
to do an AB test for different length limits
on my greetings messages.
Let's look at how we can use Remote Config to implement
both of these use cases.
The neat thing is that the process for any use case
will look very similar to what I'll cover here,
so you'll be able to adapt these steps for whichever
use cases you want to implement in your app too.
Let's get started.
Now, before we get into it, you'll
need to have an Android app and a Firebase project
set up and ready to go in order to follow along.
If you don't have a Firebase project and Android app ready,
no worries.
Just check out this video on getting started with Firebase
on Android to get one set up.
The link is in the description, so go on and do that first
and come right back to keep following along.
One quick note is that when you're creating your Firebase
project for the first time, you'll
be given the option to enable Google Analytics.
I'd recommend doing this, because while Remote Config
doesn't need Google Analytics to work,
there are additional features that
are enabled through Google Analytics like AB testing
that will be useful to have for the second use case
we're going to cover today.
Now that you have a Firebase project configured
and your Android app ready, let's
walk through how to add Remote Config to your Android app.
First up, we need to add the Firebase SDK dependencies
to our Android app build.gradle file.
There are a few ways to do that--
one, using a Firebase BOM, or Bill of Materials,
which makes it easy to manage Firebase SDK
versions in our app.
Or two, adding each SDK dependency individually.
The nice thing about the BOM method
is that I only need to keep track of the latest
version of the BOM and can then use canonical SDK
dependencies for the products I want to use--
namely, your Remote Config and Google Analytics.
Specifying the correct BOM automatically
ensures that I'll have the latest
version of any other Firebase SDKs I'm using in my project,
so I'll go with that.
Now, as I mentioned before, you can use Remote Config
without Google Analytics, but RC is a lot more powerful with GA,
so I recommend adding it on here too.
And that's it.
We're now ready to start using a remote config in our app.
Let's start with my first use case
and use Remote Config to do a phased rollout
for a new visual element to my app.
As for the visual element that I'll add in,
maybe a new background image in my greetings text input area
could add a bit of pizzazz to my app--
there.
Now, I want to use remote config to do
a phased rollout of this new feature
to see how users like it and to make sure it's stable before I
roll it out more widely.
I'll need to create a remote config
parameter that can act as a feature flag
for my new background image.
A boolean flag will probably do the trick,
so let's use that and go to the console
to see how I can set it up.
So here I am in my Firebase project.
I'll scroll on down to the Remote Config section
in the side panel, select it, and then click on
Create Configuration to create my first Remote Config
parameters and conditions.
I'll name this parameter show_background_image
and set its data type to boolean and give it
a meaningful description.
Now, I can set a default value, and I
can choose between true or false or toggle this setting here
to use in-app default values.
We'll look at setting in-app defaults in our second use
case.
For now, I'll set the default value to false
since we won't be showing the new background
image to most users just yet.
This leads me to add my first Remote Config conditional value
by clicking on Add new, Conditional value,
and selecting Create new condition.
Here is one instance where we can
see how flexible and powerful Remote Config actually
is since I can set new values for my parameters
based on many different kinds of conditions.
For example, I can choose a set of different values based
on which platform, language, country, and region my users
are in as well as which analytics
audience a user belongs to.
This is one example of how Google Analytics powers up
Romote Config even further since you
can create different analytics audiences
and customize their experience to what best suits them.
For example, customizing game difficulty
based on the expertise level of the player
or adjusting the in-store purchasing experience
between purchaser and non-purchaser groups
to optimize your app revenue.
There are many use cases possible here,
but in the case of doing our phased rollout
of the new background image feature,
we can just use the user and random percentile condition
and set this to say 30%.
I'll then name this condition random 30% of users
and click on Create condition.
Now, I can select the value for this condition.
And for this random 30% group of users,
I'll set the value to true so that they'll
be exposed to the new background image feature.
Then I'll hit save and click on Publish changes
to make it available to any app instances
out there so 30% of my users can see the new feature.
There's only one problem--
my application code isn't using a remote config yet,
so let's look at the steps needed to add it in.
So the first thing I'll need to do
is access and configure the remote config singleton
instance in my application code, which
can be done with this handy reference right here.
Next, I'll need to configure my remote config instance.
The main thing I need to configure
is how often I want Remote Config to check
for new parameter values that could
apply to this app instance.
So as I create, update, and publish
new remote config parameter values as I just
did in the console, I need to tell a Remote Config
how often I want my app to check for those new values
and apply them to my app instance.
So let me configure that now.
A good place to do this configuration
is probably in my main activity, so I'll create a remote config
settings object and set the minimum fetch
interval in seconds parameter to 3,600 seconds,
so once every hour.
You'll want to adjust this value based
on what makes the most sense for your app, but be careful.
You don't want to set this value too low since checking
too often from every app instance
out there could lead to a rate-limiting error
from the remote config servers.
For my app, once an hour sounds about right
since I don't anticipate that my RC parameter values will
be updated so often, and this value works within the bounds
to make sure I don't hit any rate limits.
Next, I'll need to make the call to fetch
and activate the remote config parameters.
This will perform both the act of fetching the parameter
values from the server and activating
those retrieved values for use.
These calls are also available separately
as fetch and activate if you need
to break down each of the actions in your app.
Now, since this is an asynchronous call,
I can add an on-complete listener
that returns when the fetch and activation is completed
and that I can use to log that fact.
And now, I can go to my fragment and make the call
to retrieve the RC parameter to determine
if I'm going to show the new background image or not.
Now, you might think that I should be all set to go,
but if I were to try and run this now,
my background image will still never show up
even if I was in the 30% group exposed to the new feature.
The reason why this won't work, as you might expect just yet,
is because the call to fetch and activate my remote config
parameters is asynchronous, which
means that the call may not have completed before my app has
completed updating the remote config parameter values.
There are a few options to address this.
The first option is to move the initialization and loading
of the rest of my visual components
into the completion listener, but it seems like a bad idea
to delay the rest of the app from loading up
based on when the network call from the RC service completes.
Another option is that it's actually fine
if the app doesn't use the remote config parameter values
the very first time the app is opened
as long as the values get applied
and the new feature is loaded from the next time my user
opens the app and onwards.
This is actually fine for this example,
and so I'll add some functionality
to check the feature flag for my new background
image in my fragments on-resume method
as well which ensures it'll get picked up later.
For your own app, you'll want to choose whichever works best.
The first option can still be the best one
if you're careful about how your app is structured,
and the rest of your app can still
load up independently from the new feature
that you want to test, so only that component
needs to wait for the network call to complete to load up.
In my case, since I'm not holding up
the loading of other components based on the retrieved
remote config parameters, I'll need a default
that will work here instead.
Thankfully, for the getBoolean method,
that default is false when there are no previously retrieved
values available or a default hasn't been set.
But there are times where we'll want
to set a different default, and we'll
see how to do that in the second use case
we set up when AB testing different text limits next.
Finally, the last thing to do is to test out the implementation.
In order to do that, I'll set the minimum
fetch interval to 0 seconds so that I'm always
getting fresh values from the RC servers in my fetch
and activate call.
And maybe I'll also toggle the default value for the show
background image parameter to true so
that it shows up for all users and then ensure
that it's getting picked up in my app.
I could also temporarily remove the 30% condition
during testing and reapply it when I'm ready for deployment
too.
I'm done setting up the feature flag for my new background
image.
Now, let's move on to the second use case where I want to AB
test different length limits on my greetings messages.
First thing I'll need to do is to go back to the Firebase
console to set up the remote config parameters for the test.
So I'm back in the console in the Remote Config section,
and I'll click on add parameter.
I'll name this one greeting_max_length
and give it a good description.
But in this case, for the default value,
I'll use in-app defaults, which I'll configure in a moment.
Then I'll click on Save and then Publish
changes in order to make this new parameter
available to my app.
Next, let's set up an AB test for this parameter.
I'll click on the overflow menu here
and select AB test which opens up the remote config experiment
section.
I'll leave the default experiments name
and add a helpful description and click next.
Now, I can select the target app for the test, which
is my Android app, and choose how many users I
want to expose to this AB test.
I'll say 15% and click Next where I can
set the goals for this test.
This will determine what metric I want
to use to determine the winner between my different AB testing
variants.
In terms of goals to choose, there
are few predefined ones like user retention
and crash-free users as well as Google Analytics
events we want to optimize for.
This is where the integration with Google Analytics
comes in handy.
In this case, even though I haven't
logged this event in my app yet, I
can create a new analytics event that I want to optimize for.
Let's see-- message_sent sounds like a good goal here.
Then there are some additional metrics
I can track for each variant to make sure that there aren't
any unintended impacts or to see if there
are additional benefits for any of the variants
in addition to the main goal I'm tracking.
And finally, that takes me to defining my variants.
For the baseline, I'm going to use the in-app default, which
will probably be something like 100 characters.
For the other variants, I'll set one really short one and one
much longer one.
Then I'll click on review, and I'm
ready to start my experiment.
But before I go ahead and hit that Start Experiment button,
I need to add and use the new remote config parameters I just
created in my application code.
So I just need to get the new remote config parameter value
and set it as the max length from my edit text component.
Note that I've already made the calls to configure
remote config and fetch and activate
my remote config parameters, so no need to do that again.
But I'm not completely done just yet.
I also need to set the in-app default
value for my new remote config parameter.
This is particularly important because I
want to ensure a consistent experience for users
who open the app for the first time,
and I don't want the app to have to wait for a full round
trip to the remote config servers
before having a default value to load for this part of my app.
First, I'll create an RC defaults XML file right here
in the resources XML folder.
The contents are just a simple map
of key value pairs describing the default values for each
of my remote config parameters.
Then, I'll set the defaults by going back to my main activity
and making the call remoteConfig.setDefaultsAsync,
passing in the ID of the default XML file I just created.
Note that although this is an asynchronous call, because it's
just reading from a local file, it completes
nearly instantaneously.
So if I did want to load the rest of my visual components
in a callback here, it would be a lot safer
and keep my app responsive while it loaded up
the correct default values.
And that's it.
My application code is now set up
to be assigned to one of the three text length size
variants that I've configured in the console.
And I can let the experiment run and come back
to the results in the console after a while like, say,
3 to 4 weeks or so, provided I get enough test data.
Here's an example of what a complete AB
test that determined a winner looks like in the console.
Now, you might remember that I also mentioned that we recently
launched personalization, which automatically selects the best
experience on a per-user basis using
some machine-learning algorithms on the backend.
Let's say I wanted to personalize the character
limit for greeting messages in my app to each user
rather than determine if there is one winning
option via AB testing.
Well, I could stop my AB test, and then
using the same remote config parameter,
open it to instead create a new personalization.
From here, I could enter the same values
for the personalization, and for my objective
I could either choose to optimize
for user engagement or the same custom message
sent event I used for my AB test.
Next, I can choose my target condition.
And rather than limit it to just 15% or 30% of my users,
I can target it to all users on my Android app,
because again, personalization will
choose the best option for each user
and adjust it based on what works
best on an individual basis.
And the code to implement this would be exactly the same
as what I already have set up for the previous AB test,
so I would already be all set to go.
For something as fundamental to my app as a character limit,
though, I probably wouldn't want to use personalization
here and instead, save it for something like ad frequency
or placements or difficulty levels in a game.
And that's it.
You are now ready to use Remote Config.
Now, get out there and build something wonderful,
and let us know in the comments if you have any questions
or want to let us know about what you built.
[AUDIO LOGO]