So if you’ve never used audiences before, they can be a really powerful way to segment your user base so that you can deliver tailored and relevant experiences to specific groups of users. Maybe that’s sending them a customized notification in Firebase Cloud Messaging, maybe that’s creating a unique experience for them in Remote Config, or maybe that’s targeting them with a remarketing campaign in Google Ads.
At least, that’s the idea in theory. In practice, audiences were a bit limited in the past. One of the biggest limitations was that, once a user was placed into an audience, they could never leave. It’s what we in the industry call the “Hotel California” rule.1
For example, imagine you tried to create a “Beginners” audience of all users who are at level 10 or less in your app. While that might work initially, the problem was that users would stay in that audience, even when they reached level 11, 20, or 300. So your “Beginners” audience would gradually morph into an “All players” audience over time.
But all of that has changed with the new dynamic audience features that we announced at the Firebase Summit in October. With dynamic audiences, users will join an audience when they meet the criteria for it, but also leave that audience when they no longer do. Along with these features, the folks on the Google Analytics for Firebase team have added a number of controls to make audiences more powerful and more flexible than before.
Understanding how audiences are evaluated
Before we start, let’s take a moment to understand how users are added to an audience, because this can clear up a lot of confusion that developers first have when creating them.
When you create an audience in the Firebase Console, most of the conditions you create are sent up to each of your clients on an hourly basis. Your clients will look at the user properties and the events being triggered on the device and decide if that user has met the conditions you’ve defined. When a user does meet those conditions, the client will send that information back to the server, which will then combine that information with some other data it might be storing server-side (like some demographics data) to place the user in the appropriate audience.
This is important to understand because I think it helps to clear up three big misunderstandings people have about audiences:
- All audiences you create will be empty at first. This is because you need time for those audience conditions to be sent to your client, for your client to then determine if that user meets those conditions, and then for the client to send that information back down to Analytics. So you should expect all new audiences to start off empty, then gradually grow over time.
- Your client doesn’t keep your entire event history on the device. So if you create an audience of people who have placed an item in their shopping cart, your users won’t be added to that audience until they add an item to their cart from that point forward. It doesn’t matter how many purchases they might have made in the past.
- All the new audience behaviors I’m about to describe require a recent version of the mobile SDK because, again, a lot of audience logic is evaluated on the client. In the iOS world, you should make sure you at least have version 5.2.0 of the Firebase/Core SDK. In the Android world, your users just need to have a fairly recent version of Google Play Services.
Make sense? Great! Let’s take a closer look now at what you can do with audiences in Firebase.
You primarily create audiences based on your users triggering one or more events that meet certain criteria, or their having user properties of a certain value.
So, for instance, let’s say you’re building a fitness app, and one of the user properties you’re tracking is a
fitness_goal property. Now let’s say you wanted to create an audience of users whose fitness goal is to lose weight. Well, you can do that now fairly easily in the Firebase console.
With this audience, your app will start adding users who have listed their fitness goal as losing weight. And if they were to change their goal to
get_stronger, they’ll no longer be in that audience.
What’s new from a UI perspective is the checkbox at the end that says “At any point”. By leaving this unchecked, you’re using the new dynamic behavior, where users enter or leave this audience as this user property changes. If you really wanted an audience of “Anybody who lists weight loss as their fitness goal, even if they change it later”, then you could check that box.
Next, let’s say you wanted to create a “Long distance runners” audience by recording anybody who completes a
exercise_completed event with a
exercise_type value of “running” and a
distance value greater than 10. That’s something you could do by creating an audience based on a user logging this event with those two event parameters.
And remember, this will only include users who complete a long run from this point forward
Similarly, let’s say you wanted to create a “frequent exercisers” audience by looking at anybody who has exercised 3 or more times a week. You could do this by using the “Count” property of
exercise_completed, like so:
This is another area where Audiences got more powerful. Notice that there’s now a “in any day period” checkbox. If you left this checkbox blank, you’d essentially be saying “Anybody who completes 3 or more exercises ever”. That’d be useful if you wanted to create an audience of people who have at least given your app a solid try, but that’s not really what I would consider a frequent exerciser.
This is more like a “People who gave my app a reasonable try” audience
So by checking this box, you’re saying that your user needs to complete more than 2 exercises in a 7 day period to be included in this group.
Does this mean, by the way, that a user leaves this group as soon as they hit a week without exercising? Nope. I’ll talk a little more about how a user would leave this group in the next section.
Keep in mind that while you can add multiple event parameters into the same audience definition, like our long distance runners, you can’t add other event parameters alongside this
Count property. So I can’t, for instance, create a “Frequent runners” audience by asking for users who hit the
exercise_completed event with
running and a
Count > 2.
You’ll notice at the bottom of each of these examples is a “Membership duration” field which is, by default, equal to 30 days. What does this mean?
Here’s how this value works: Basically, your app is continually evaluating whether or not your users belong to each one of these audiences that you’ve defined, and is “renewing” your user to audiences that they’ve qualified for. What this duration field will do is look at a user’s last “I’ve qualified for an audience” time and remove them from the audience if that time was longer than the current membership duration.
So, let’s go back and reevaluate some of these audiences we’ve created based on this membership duration, assuming it’s set to the default value of 30 days.
For the “Weight loss” audience, users are continually renewing their membership by keeping their
fiteness_goal property set to
weight_loss. So a user will really only expire out of that audience if they haven’t opened up their app in more than 30 days.
Let’s move on to the “Long distance runners” audience. Again, every time a user completes a long run, they’ll renew their audience membership. So this audience will consist of everybody who’s completed a run greater than 10 miles sometime in the last 30 days.
This 30 day value is adjustable, too. If you want to create an audience of “Anybody who’s completed a long run in the last year”, you would simply set the membership duration of the “long distance runners” to 365 days. Or click the checkbox and that will set your duration to the maximum value (currently 540 days).
Along those lines, our “Frequent exercisers” audience will “renew” their membership every time they complete 3 exercises in a 7 day period. So if you wanted an audience of “Users who have completed 3 exercises in the last 7 days”, you could create an audience of people who have completed 3 exercises in any 7 day period, set the membership duration to 7 days, and that will get you fairly close.2
ANDin and ORing
You can AND and OR definitions together, and they generally work the way you’d expect. A person will be considered part of the audience if they meet all of the conditions that are ANDed together, or any one of the conditions that are ORed together.
So you could create a “Women marathoners” audience by creating an audience of people who have completed a running exercise with a distance of greater than 26 miles and are female.
Or you can create a “Basic usage” audience by creating an audience of people who have completed one exercise OR recorded 7 meals in our app’s meal tracker.
Do these operations help us create our “Frequent runners” audience? Unfortunately, not quite. You could create an audience of people who have completed more than 3 exercises in 7 days AND have completed an exercise where they run…
…but this audience will also include people who, for instance, take 3 yoga classes in a week, and then go running once.
If we really wanted that “Frequent runners” audience, we’d probably have to break up our
completed_exercise event into individual ones:
completed_weightlifting, etc. Then you could create an audience just based on this individual event.
The tradeoff is that this would make it harder to calculate an overall “frequent exercisers” audience, so make sure you consider what audiences you’re really going to want before you go ahead and start breaking up all your events.
In addition to ORs and ANDs, you have access to NOT logical operations, by excluding certain groups. These can be really useful in creating other conditions in which a user could leave an audience.
For example, in an ecommerce app, you could create an audience of people who have added an item to a cart, but haven’t made a purchase yet.
You could send this audience a notification to remind them that they still have items in their cart waiting to be checked out.
A game could create an audience of people who have played levels 1-19, but haven’t made it past level 20. This might be a good group to send beginners tips and tricks via an In-App Messaging campaign.
In this example, we’re assuming that
level_number is a property attached to the
Going back to our fitness app, you could create a “users just getting started” audience by creating a group of people who have exercised more than 5 times, while excluding users who have exercised more than 20 times.
Or you could create a “Users who are actively using my app but haven’t tried tracking meals yet” audience by creating a group of people who have exercised more than 5 times, while excluding users who have used the meal tracking feature more than once. This audience might also benefit from a messaging campaign to remind them of this great new feature of your app.
Finally, one other note about excluding audiences is that most of our product features allow you to target “all of your app users except those in an audience”. This is sometimes an easier way to target the users you’re interested in.
For instance, let’s say if you created an audience of everybody who’s performed an exercise in the last 14 days…
…you could target lapsed users in Firebase Cloud Messaging simply by sending a notification to anybody who’s used your app in the last 180 days, except those who are in this “Exercised in the last two weeks” audience.
Regex in audiences?
Up until now, we’ve been evaluating all of our user properties and event parameters against numeric and text operations like ”>=” or “exactly matches”, but you’ll notice you have the option to measure these values against regular expressions. In theory, you could use this to add more flexibility to audience creation, and possibly eliminate some of the more complex AND or OR creations you might have above.
For example, if we wanted to create an audience of users who either meditate or perform yoga, we could do this with a couple of OR clauses…
But we could also do this more efficiently by using a regular expression on the
exercise_type event parameter.
However, writing regular expressions can be a little tricky. Of course, I always write my regular expressions properly on the first try, (cough), but here’s a few things you need to be aware of:
Regexes are evaluated using the Java Pattern class in Android, and the NSRegularExpression class in iOS. Essentially, the string you specify as your regular expression in the console is passed directly to the constructors in each of these classes.
This does mean that you either need to write a regex string that works correctly in both classes, or confine your audience to a single version of your app if you’re planning on getting more sophisticated with your regular expressions.
Luckily, much of the syntax is the same across both classes. Simple operators like
 work the same, and the Firebase console will automatically escape backslashes for iOS. This means you can use a pattern like
\w to represent whitespace, and it will be properly converted into
\\w on iOS. But if you start getting into more complex regular expressions, there might be cases where the two patterns are evaluated differently, so be careful.
You might have noticed that you don’t need to add any “decorations” to the regular expression. That is, I just specify my regular expression as
yoga|meditation, and not
/yoga|meditation/. Along those lines, you can’t really add flags or options to your regular expressions, but all regular expressions are already set to be case insensitive by the SDK, which is usually the flag most folks are interested in.
Right now, testing whether or not a user has joined an audience isn’t that easy. So I highly recommend testing your regular expression in an external tool before adding it into your app. For Android, check out a site like this one. On iOS, probably your best best is to try it out in a playground.
In the end, when it comes to regular expressions, they can be quite helpful if you’re careful and not trying to get too clever with what you do. But I’m also reminded of my favorite quote by Jamie Zawinski on the topic:
Some people, when confronted with a problem, think “I know, I’ll use regular expressions.” Now they have two problems.
Do more with audiences!
There are a lot of great things you can do now with audiences, now that we’ve dropped the Hotel California rule3. By carefully curating which users receive a notification, an in-app message, or a specially tailored app experience, you can make sure you’re creating the most effective campaigns, while not spamming other users with notifications or messages that they don’t care about.
The new dynamic audience features were one of the biggest requests from our Analytics partners, and we’re excited to see what you do with them. So if you haven’t given audiences a try lately, give them another look! As always, if you have questions, you can hit us up on the Firebase Talk group, or Stack Overflow.