[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]