If you haven't heard yet, the Firebase team is at the Game Developers Conference this week to show
all you game developers out there how Firebase can make it easier for you to
develop successful games. And one of our big announcements at the show is that
the official Firebase SDKs for Unity and C++ have now graduated to full General Availability!
This means that they're both primary supported platforms that
Firebase is committed to supporting in the future.
Both SDKs let you take advantage of: AdMob: Monetize your games with targeted, in-app advertising, include native ads
and rewarded video. Guides: Unity/C++.
Analytics: Record events that happen in your game with our free and unlimited
analytics service, now complete with real time views! Guides: Unity/C++
Realtime Database: Magically sync your app's data across all devices, usually
within a few hundred milliseconds. Guides: Unity/C++
Dynamic Links: Create mobile deep links that you can use to point players to any
element of your game (if they have it installed), or take them to the Play Store
/ App Store (if they don't). Guides: Unity/C++
Authentication: Sign in your users in from third party providers like Facebook,
Google, and Github, or use our built in username and password system. Guides: Unity/C++
Cloud Messaging: Send notifications to iOS, Android and web clients through a
single endpoint, or use the Firebase Notifications panel to schedule
notifications without having to worry about writing any custom server code or
curl calls. Guides: Unity/C++
Remote Config: Tweak variables from the cloud, and then use Firebase Analytics
to see if they give you the results you expect. You can even use Remote Config
to deliver custom values to specific groups of people, like your expert players.
Guides: Unity/C++
Storage: Store user-created binary data in Cloud Storage buckets directly from
the app - fantastic for uploading screenshots or videos. Guides: Unity/C++
You can jump in today with our new getting started guide for gamedevelopers . As a bonus for
developers working in Cocos2D-x, we've also released a set of new samples that
demonstrate how to integrate the C++ SDKs into your Cocos2D-x games. As always,
if you have questions or comments, reach out to us through our support team, Stack Overflow or
the firebase-talk
group!
When Firebase Auth launched at Google I/O 2016, it allowed your users to create
an account on your app where they signed in with an email address and a
password. But this email address could be anything -- as it wasn't linked to the
actual account through a verification process: so, for example, your users could
identify themselves as [celebrity name]@[anydomain] if they wanted to.
To solve this problem, Email Verification has been added to Firebase
Auth -- where, in the above case, Firebase will send an email to that address
containing a validation link. So if that celebrity really is signing up for your
app, he'll get the link and click on it. You can check to see if the account is
verified at sign in, and take an action in response -- such as blocking them
from signing in.
When you run the app, and select the Email/Password authentication activity,
you'll see this screen, where it gives you the option to sign in (if you have an
account already), or create one (if you don't).
When you click the 'Create Account' button, you'll get taken to a new activity,
showing the user identity, and the Firebase User ID associated with it. You'll
also see that the email isn't verified, with a button allowing you to verify it:
Clicking the Verify Email button will then send an email to that address. This
email will contain a link, and once the user clicks on that link, the account
will be verified.
This email is shown on the Email
Templates tab in the Authentication section of the Firebase console. From
here you can edit the action link, or the reply address so that it appears to be
from your domain, instead of authui-xxxx.firebaseapp.com as shown above.
Here you can see what happens once the account is verified and I sign in again.
You'll also see that this identity is present as a user in the Firebase console.
You can manage them from there -- including changing their password or removing
them from your app altogether.
Coding for Email Verification
Details on coding for email verification can be found in the Manage Users
section of the Firebase documentation (Android,
iOS, Web). For the
rest of this post, I'll be looking at the Android code, but the implementation
on the other platforms is very similar.
The core functionality is found on the FirebaseUser
object. On it is a sendEmailVerification() method, which returns as Task
used to asynchronously send the email, and report on the status. If the task is
successful, you know the email was sent. Here's an example:
final FirebaseUser user = mAuth.getCurrentUser();
user.sendEmailVerification()
.addOnCompleteListener(this, new OnCompleteListener() {
@Override
public void onComplete(@NonNull Task task) {
// Re-enable button
findViewById(R.id.verify_email_button).setEnabled(true);
if (task.isSuccessful()) {
Toast.makeText(EmailPasswordActivity.this,
"Verification email sent to " + user.getEmail(),
Toast.LENGTH_SHORT).show();
} else {
Log.e(TAG, "sendEmailVerification", task.getException());
Toast.makeText(EmailPasswordActivity.this,
"Failed to send verification email.",
Toast.LENGTH_SHORT).show();
}
}
});
In this case, the user is retrieved from mAuth.getCurrentUser(),
and the sendEmailVerification() method is called on it. This gets
Firebase to send the mail -- and if the task was successful, you'll see that a
toast will pop up showing that it happened.
After the user clicks the link in the email, subsequent calls to user.isEmailVerified()
will return true. Here's how it is used in the sample app:
Do note that the FirebaseUser object is cached within an app session, so if you
want to check on the verification state of a user, it's a good idea to call
.getCurrentUser().reload() for an update.
In the sample app it just shows on the activity if the user's email address is
verified or not. For your app you could limit functionality based on this state
-- even to the extent of denying them access to the signed in section of the
app.
You can learn more about Firebase Auth, including sign-in with other providers
such as Google, Facebook, Twitter and more on the Firebase developers
site.
Google Cloud Next 17 is three
weeks away! It's a great event for anyone looking for insight on Firebase and
mobile development. Scanning through the session catalog, here's a sampling of
the must-see sessions that mobile developers should attend.
If you're a mobile development rookie, your first stop should be "What
to consider when developing mobile apps," in which Laurence Moroney, Google
staff developer advocate, surfaces some of the gotchas of developing for mobile
devices such as poor connectivity and offline devices, access control and
battery life.
Then, march on over to "Zero
to App: Live coding an app with Firebase and GCP," which will be a very cool
live demo. Watch in awe as Googlers Mike McDonald, Jen Tong and Frank van
Puffelen do simultaneous live coding of an app across both iOS and Android.
You'll leave with an appreciation of how easy it is to code with Firebase, and
how easy it is to scale with GCP.
For mobile devs that just want to focus on delivering a great UX, "serverless"
development helps remove a big set of concerns from their plate. If that
describes you, go see "Google
Cloud Functions and Firebase," with Firebase team members Thomas Bouldin,
software engineer and Brendan Lim, product manager, who will show you how to
extend Firebase backend services with Google Cloud Functions to make the next
generation of mobile and web apps.
Once you've built that awesome mobile app, you'll want analytics to understand
how people use it. But building analytics infrastructure can be painful, and the
same goes for log ingestion pipelines, and managing a data warehouse. We've got
you covered. In "Gaining
deeper insights from Firebase Analytics with Google BigQuery," Google
developer advocates Todd Kerpelman and Arun Venkatesan will show you how to use
Firebase Analytics and augment it with BigQuery and data visualization tools
like Data Studio.
Of course, that's just the tip of the iceberg. For the full story, check out the
schedule for a full
listing of the keynotes, bootcamps and over 200 breakout sessions. Hope to see
you there!
One frequent scenario we encounter with developers is that they like the idea of
using Firebase Analytics to track and understand in-app event data, but they've
already spent the last several years tweaking and tuning their Google Analytics
implementation just they way they like it, and aren't keen to start all over
again with a brand new reporting tool.
However they're still interested in taking advantage of Firebase Analytics and
some of the nifty cross-functional features it offers. Things like creating
custom Audiences to use for more targeted Notifications, or creating User
Properties that can be used for Remote Config targeting.
So, how do you get both working at the same time? Let's look at a few different
strategies you can try if you're interested in adding Firebase Analytics to your
Google Analytics-enabled app.
First, Let's Talk Events
To make our example a little more concrete, let's assume that we've got a mobile
game that is sending across these three events to Google Analytics at the end of
every round: Total score, enemies beaten, and rounds survived. Our method to
record these values to Google Analytics might look a little like this:
func recordGameOver() {
let tracker = GAI.sharedInstance().defaultTracker
let gameOverEvent = GAIDictionaryBuilder.createEvent(withCategory: "gameOver",
action: "totalScore",
label: "",
value: myGameStats.totalScore as NSNumber)
let enemiesBeatenEvent = GAIDictionaryBuilder.createEvent(withCategory: "gameOver",
action: "enemiesBeaten",
label: "",
value: myGameStats.enemiesBeaten as NSNumber)
let roundsSurvivedEvent = GAIDictionaryBuilder.createEvent(withCategory: "gameOver",
action: "roundsSurvived",
label: "",
value: myGameStats.roundsSurvived as NSNumber)
tracker?.send(gameOverEvent.build() as [NSObject: AnyObject])
tracker?.send(enemiesBeatenEvent.build() as [NSObject: AnyObject])
tracker?.send(roundsSurvivedEvent.build() as [NSObject: AnyObject])
}
And before you ask: Yes, this could also be done using a single event with
custom dimensions. The general concept is the same -- perhaps a little easier,
in fact -- if that's what you're doing.
This gives us some nice little reports in Google Analytics where we can see,
over time, our players' final score, enemies beaten, and the number of rounds
they survived.
Now let's think about how we might want to translate this into Firebase
Analytics events. While Google Analytics is structured around hierarchical
events with one associated value each, Firebase Analytics is more about
recording a single event with a number of associated key-value pairs passed
along as event parameters.
So you could perform a fairly literal one-to-one translation from Google
Analytics events to Firebase Analytics events like this...
FIRAnalytics.logEvent(withName: "gameOverTotalScore",
parameters: [kFIRParameterValue: myGameStats.totalScore as NSObject])
FIRAnalytics.logEvent(withName: "gameOverEnemiesBeaten",
parameters: [kFIRParameterValue: myGameStats.totalScore as NSObject])
FIRAnalytics.logEvent(withName: "gameOverTotalScore",
parameters: [kFIRParameterValue: myGameStats.totalScore as NSObject])
...but it's more natural in the Firebase Analytics world to record this as a
single event with a number of custom parameters:
let finalStats = ["totalScore": myGameStats.totalScore as NSObject,
"enemiesBeaten": myGameStats.enemiesBeaten as NSObject,
"roundsSurvived": myGameStats.roundsSurvived as NSObject]
FIRAnalytics.logEvent(withName: "gameOver", parameters: finalStats)
(And for those of you using the custom dimensions approach, this is probably
even closer in line with what you're already doing.)
Going with this second approach does mean that you may want to use BigQuery to
analyze the custom parameters that have been sent along with your events, but
honestly, it's probably something you should be looking at anyway if you're
really serious about your analytics data. And, as luck would have it, we've got
a whole video all
about that!
Adding Firebase the Correct Way
One of the first areas of confusion in getting Firebase Analytics up and running
is that both Google Analytics and Firebase Analytics use a similar setup
process.
On iOS, for instance, many developers have generated and added a
GoogleService-info.plist file to their Xcode
project in order to get Google Analytics up and running. But to configure
Firebase Analytics correctly, you also need to generate another
GoogleService-info.plist file, and add it to your
Xcode project. How can you do both?
The answer here is to install Firebase not by creating a new Firebase project at
the console, but by importing your existing Google Analytics-enabled project
into Firebase.
When you create your Firebase project, you'll do so by clicking the "Import
Google Project" button. Select your Google Analytics-enabled project, and then
re-download your GoogleService-info file from the
project settings.
What you'll get back will be a superset of the plist file you'd get from both
Firebase Analytics and Google Analytics -- if you examine its contents, you
should see a TRACKING_ID entry equal to your
Google Analytics tracking ID, along will a whole bunch of new Firebase info.
Replace your old GoogleService-info file with this
new one, go through the rest of the Firebase installation process, and you're
ready to go.
On Android, the process is basically the same, except that you're looking at a
.json file instead of a .plist. And probably using Android Studio instead of
Xcode.
Okay, so assuming we have our project set up correctly, how do we move ahead
with including our data in both Google Analytics and Firebase Analytics? Here
are three options we can try.
Option 1: Just Use Two Analytics SDKs
The simplest scenario here would simply be to keep the Google Analytics service
up and running, while also adding Firebase Analytics tracking to your app. The
resulting code on the client would look a little like this:
func recordGameOver() {
// All the old code you had previously to record Google Analytics
// …
// … So much code …
// …
// Now add the Firebase stuff
let finalStats = ["totalScore": myGameStats.totalScore as NSObject,
"enemiesBeaten": myGameStats.enemiesBeaten as NSObject,
"roundsSurvived": myGameStats.roundsSurvived as NSObject]
FIRAnalytics.logEvent(withName: "gameOver", parameters: finalStats)
}
Now from a developer standpoint, I could see why this kind of solution would be
appealing; it's very simple to implement, and it's low risk. You don't have to
worry about any disruptions to your current Google Analytics reports, because
all of your client code is still there making all the same calls to Google
Analytics like always. It's just that now, you're also making calls to Firebase
Analytics and getting data into that system as well.
But this solution has a few drawbacks. For starters, you're now sending down
data to two different analytics packages, which generally means that your client
is making more network calls then before, and that means your app is using more
of your user's mobile data and negatively impacting their battery life. On the
other hand, Firebase Analytics tends to be quite conservative when it comes to
making network calls, so we're only looking at a minor bump on top of your
Google Analytics traffic.
Perhaps a bigger drawback is that you now have double the analytics code all
over the place. Now, if you've already abstracted your analytics call into a
separate method that hides the implementation details underneath, perhaps this
isn't a big deal. You'll just now add Firebase to this one method. But if you
haven't, the of idea adding all this code throughout your app probably isn't
super appealing to you. So there's another option you could consider, which is…
Option 2: Use Google Tag Manager to Report Events Everywhere
Google Tag Manager is this neat Swiss-army-knife of tools that has perpetually
been on my, "One day I should spend more time learning about this thing" list.
And it turns out for good reason. One really neat feature that Google Tag
Manager provides is that when it sees an outgoing Firebase Analytics event, it
can help you report those same events to Google Analytics, as well as some other
third party analytics providers.
The nice part about this solution is that you only need one set of
analytics-reporting code on your client. In our example, we would have a much
simpler implementation where we could completely eliminate the Google Analytics
calls:
func recordGameOver() {
let finalStats = ["totalScore": myGameStats.totalScore as NSObject,
"enemiesBeaten": myGameStats.enemiesBeaten as NSObject,
"roundsSurvived": myGameStats.roundsSurvived as NSObject]
FIRAnalytics.logEvent(withName: "gameOver", parameters: finalStats)
// That's it!
}
To use Google Tag Manager to report these events to Google Analytics, you'd need
to install the library via CocoaPods / Gradle and add a .json file to your
project. And that's about it on the client side. Most of the work is done within
the Tag Manager console.
Over in the Tag Manager console, you'll want to create a Firebase Event
Parameter Variable for every value you'll want to send to Google Analytics. In
our example, we'd need a value for totalScore, enemiesBeaten, and
roundsSurvived.
Next, you'll create a trigger for each Firebase Analytics events you want to
correspond to. In our case, we'd want to create a trigger that fires whenever we
see an event name called "gameOver"
Finally, you'll create tags where you respond to these triggers by sending off
events to Google Analytics (referred to as Universal Analytics within Google Tag
Manager). You can also send off events to services such as AppsFlyer, Kochava,
Tune, and others.
Now I like this approach because, frankly, any opportunity you get to write less
code is usually a good thing. This also gives you the flexibility to report some
events to Google Analytics but not others, (if you wanted to start reporting
some events exclusively to Firebase Analytics), or change how you're reporting
your Firebase Analytics events to Google Analytics, even after the app has
shipped!
One important note here is that you currently can't use Firebase Analytics and
Google Tag Manager together to send ecommerce data to Google Analytics. This is
something the team is working on addressing, but in the meantime, if you need
ecommerce data in Google Analytics, you might want to consider one of the other
options, or simply leave in the code to send ecommerce events to Google
Analytics directly.
You're also still double-reporting analytics calls from the client, which, as we
discussed above, isn't great. You also have to spend a chunk of time up front
adding all your triggers, events and tags to the Google Tag Manager panel. But
hey, I can think of worse ways to spend an afternoon.
But what if you're against the idea of running two analytics SDKs on the client?
What other options are available to you? Glad you asked!
Option 3: Use BigQuery to Merge Everything
Another option you can consider is to completely replace Google Analytics with
Firebase Analytics on the client, and then use BigQuery on the backend to merge
your old Google Analytics data with your new Firebase Analytics data.
Now, granted, this solution only really makes sense if you're already a Google
Analytics 360 customer and are currently using BigQuery to drive most of your
custom reports. If this sounds like you, then updating your BigQuery queries to
grab data from both data sources may be a reasonable option.
Going back to our example, let's assume we've already been generating a "Daily
average final score" report within BigQuery by running a query that looks like
this:
SELECT
AVG(hit.eventInfo.eventValue)
FROM
`my_awesome_app.ga_sessions_20170123`,
UNNEST(hits) AS hit
WHERE
hit.eventInfo.eventCategory = "gameOver"
AND hit.eventInfo.eventAction = "totalScore"
So now let's make the switch to Firebase Analytics. On the client, we can use
the simple implementation from the previous example that only makes a call to
Firebase Analytics...
func recordGameOver() {
let finalStats = ["totalScore": myGameStats.totalScore as NSObject,
"enemiesBeaten": myGameStats.enemiesBeaten as NSObject,
"roundsSurvived": myGameStats.roundsSurvived as NSObject]
FIRAnalytics.logEvent(withName: "gameOver", parameters: finalStats)
// That's it!
}
And then if we want to see the average enemies beaten over time, we'd need to
merge the two datasets. The SQL for this might look a little something like
this:
SELECT
COUNT(*),
AVG(total_score) AS average
FROM (
SELECT
event_param.value.int_value AS total_score
FROM
`firebase-project.com_example_awesome_app.app_events_20170123`,
UNNEST(event_dim) AS event,
UNNEST(event.params) AS event_param
WHERE
event.name = "gameOver"
AND event_param.key = "totalScore"
UNION ALL
SELECT
hit.eventInfo.eventValue AS total_score
FROM
`my_awesome_app.ga_sessions_20170123`,
UNNEST(hits) AS hit
WHERE
hit.eventInfo.eventCategory = "gameOver"
AND hit.eventInfo.eventAction = "totalScore" )
Obviously, this is a pretty simple example. Things can quickly get more
complicated, depending on what you want to do and how your data is structured.
But I've got some (much smarter) co-workers who are working on a blog post for
the Google Cloud Big Data
Blog that will cover some of these more sophisticated queries. So keep an
eye out for that!
So there ya go, folks; a few pointers on how to add Firebase Analytics to your
app that's already set up for Google Analytics. (Or, for that manner, any other
analytics platform.) Once you've gotten that set up, I recommend trying out some
Firebase features that make use of Firebase Analytics data: deliver a new
Remote Config setup to users with a specific user property, or send a
Notification to a Firebase Analytics Audience that you've created. And feel free
to start tracking more Firebase Analytics events -- remember, it's free and
unlimited, no matter how many users your app might have. There's a lot more
exciting tools and features coming out for Firebase Analytics over the next
year, so it's never too early to start adding Firebase Analytics to your mobile
app. Give it a try!
Firebase Auth is a secure
authentication system that allows users to sign in and sign up for your
application. It also allows federated identity sign-in through providers like
Facebook, Twitter and of course, Google.
Users expect a rich experience and the the open source FirebaseUI project makes
all of this possible by solving complex identity management problems. Firebase
UI uses a number of new tools and UX innovations to assist users through the
sign-in and sign-up process. These enhancements come from years of research by
the Google identity team in learning how to optimize sign-in conversion.
In this post, you'll see how to use the feature to do sign-in and sign-up in an
Android app using both Google Sign-In and an email/password combination.
Getting Started
The best way to get started is to go to GitHub and use FirebaseUI!
After clicking the Download button, you'll get a zip file containing the code,
as well as a sample app. We'll explore the sample app in this post to see how
you can use FirebaseUI for yourself.
To access it, use Android Studio, and from the File->Open menu, navigate to the
directory where you unzipped the code. You'll see an Android Studio project is
available. It should look like this:
Before you can run it, you'll need a Firebase project in the Firebase console,
which in turn will give you a google-services.json configuration file. To get
this, follow these steps:
In Android Studio, click Tools->Firebase. The Firebase Assistant will open on
the right hand side of the Android Studio window. You'll see an Authentication
section, that you can select. It will have an action for 'Email and password
authentication'
Click it, and you'll see some actions that you need to follow. The first of
these is to 'Connect your app to Firebase'.
Click the button, and you'll see the 'Connect to Firebase' dialog.
You can select either an existing application, or create a new one as shown.
Once you're done, press the 'Connect to Firebase' button.
Android Studio will create a Firebase application for you on the console. It may
take a few moments. When it's done, you'll see status like this:
Next up, you'll need to add Firebase Authentication to your app. Note the text,
and the link within it -- you have to go to the Firebase console, and from there
you can set up the desired sign-in methods.
In the console, turn on the Email/Password and Google Sign-In providers. It
should look like this:
Now click the 'Add Firebase Authentication to your app' button in the assistant,
and you'll see the 'Add Authentication' dialog:
Select 'Accept Changes', and Android Studio will add the required libraries to
your app. You're now ready to run it!
Running the FirebaseUI Auth App
You're now ready to run the app. On some versions of Android Studio, you might
get an error telling you that Instant Run isn't working. If that's the case, you
can disable it on the Android Studio->Preferences->Instant Run menu.
After running, you'll see this screen:
Select 'Auth UI demo', and you'll see this:
Be sure to leave 'Google' and 'Email' checked as shown. Try experimenting with
them by clicking 'Start'. You will first see Android's
hint selector, which automatically helps channel the user into either the
sign-in or sign-up flow. In thisexample, on my device I have 2 Google IDs signed
in on the device (and saved with Google Smart Lock), so when I click 'Sign In',
I get a card showing both -- allowing me to bypass the sign-in screen. The hint
selector will also include other accounts on the device as well as any other
email addresses saved with Smart Lock for Passwords. If you aren't
signed into Google or any other accounts on the device, you won't see this, and
will get taken to the Sign-in Screen instead. After signing in, you
have the option to add the account to Smart Lock, giving you this option.
And if I click 'None of the Above' -- I get my sign-in screen -- giving me the
option to sign in with Google or sign in with Email.
Think of all the different user flows that you'd need to implement with this.
If there's no Google Account, but you sign in with Google, you should have
the option to create a new one, or use an existing one
If there is only one Google Account, and you used it previously to sign in,
then you can sign in right away with it.
If there are multiple Google Accounts, you should be given the option to
choose one, add an existing one, or create a new one.
Play with the app and you'll see all of these are implemented in a standard way.
Once you've signed in, you'll see something like this -- where metadata about
the signed-in user is available:
Remember that the same can apply for Email or other identity provider accounts.
That's a lot of code you'd have to write. But let's take a look at the code for
this app -- and you'll see just how much has been encapsulated for you in
FirebaseUI Auth.
Exploring the Code
To explore the code, go back to Android Studio, and look in the App folder. In
it, you'll see an 'auth' folder, and within that there are three activities.
The first of these, the AuthUiActivity renders the sign-in buttons, and handles
the sign-in request and response. The LeakCatcher, as its name suggests, helps
you detect memory leaks. Finally the SignedInActivity renders the details of
your sign-in session -- which you saw above.
Let's take a look at the AuthUiActivity. In the onCreate method, you'll see this
code:
This gets an instance of the abstract class FirebaseAuth, and if there's a
current user -- i.e., if someone is already signed in, then go straight to the
SignedInActivity.
While there may be multiple buttons (i.e. Sign In with Google, Sign In with
Email etc), there's only one button control, called R.id.sign_in, and
it handles the user interaction. So, in your code you should see this:
This creates a SignInIntent from the AuthUI class. The logic within handles all
of the user flows mentioned earlier! AuthUI is fully open source, so you can
inspect how it does it, but if you want to use it, this is all you need to do!
The intent will return an activity result when done, and if this is the result
of the above, the request code will be RC_SIGN_IN, so we call the
handleSignInResponse function, passing it the resultCode and the data that came
back from the intent:
This function queries the data that came back from the activity, and if it
indicates a successful sign in, then it starts the SignedInActivity, passing it
the response data, from where it will parse the user metadata:
The UI is also fully customizable, and you can see an example of this if you
explore the styles.xml file in the project. This allows you to set the colors of
the sign in activities provided. Here's an example of the 'dark' theme:
Then, when creating the sign in intent, you can set the theme.
@OnClick(R.id.sign_in)
public void signIn(View view) {
startActivityForResult(
AuthUI.getInstance().createSignInIntentBuilder()
.setTheme(R.style.DarkTheme)
.setLogo(getSelectedLogo())
Or, as you can see in the snippet above, you can also set the logo -- see the
getSelectedLogo function for details. It's as easy as adding your logo to the
resources and configuring that function to return it based on its resource id.
And that's all you need to do! All of the user flows are encapsulated in the
AuthUI classes, giving you a high conversion UI for signing in and signing up,
freeing you up to focus on your application logic! FirebaseUI is not just on
Android. You can get the same easy to drop-in and customize high conversion UI
for iOS
and Javascript.
Firebase Analytics provides a lot of nice reports for you out of the box --
things like retention, active users, and some demographic information about the
people using your app. And for specific events, you can see useful stats like
the number of events fired over time or the average number of events per
session. But one thing that you currently can't do (outside of BigQuery) is see
values associated with any custom parameters that you send down in a Firebase Analytics event.
While the team is looking into ways they can make this experience better, there
is one feature you can use right now to get some of the answers you're looking
for. Every event you record in Firebase Analytics can accept a "value" parameter
-- this can be a floating point number or integer -- and Firebase Analytics will
give you back the average of this value over time.
For instance, let's say your fitness app is recording an end-of-workout event
that looks a little like this[1]:
Within the Firebase Analytics reports, you'll be able to see the total number of
workouts completed over time, the average number of workouts completed in a session, and the general age and gender breakdown of people completing
workouts. But you can't, for instance, track the average amount of time people
spent working out.
On the other hand, if you were to provide that same workout time
information in a value parameter like so…
...you'd be able to see this workout time over the lifetime of your app by
looking at the "Value" graphs for the
workout_complete event. In the example screenshot
below, we can see that in the last 30 days, my users have completed about 1400
workouts (the "Event count" graph), and have spent a total of about 1.5 million
seconds (the "Value" graph) doing so. That works out to about 17 minutes per
workout.
Of course, the value parameter won't always give you all the information you
need. If you were interested in comparing the average workout time for your
interval workouts to the average workout time for your yoga workouts, you'd
still need to use
BigQuery to get that kind of data analysis. But I think you'll find you can
get a surprising amount done just with the value parameter.
This value parameter can track completely different values for completely
different events. So you could track average workout length in your
workout_complete event, number of friends invited
in an invite_friends event, or number of calories
consumed in an eat_meal event.
I encourage you take a look at the events you're recording in your app and see
if there's any useful information you might want to see that could be uncoveblack
using these value parameters. You can check out our
docs for more info, and find us on StackOverflow with the Firebase tag.
Happy tracking!
[1] I'm cheating a bit here. Swift 3 requires that I cast all of these values as
NSObjects, but that tends to hide the point of this sample behind a lot of extra
code, so just pretend I'm casting values appropriately. :)
Over the course of this series, I've introduced the concept
of Pirate Metrics, followed by individual posts discussing how to track (and
improve) acquisition,
activation,
retention
and referral
with Firebase and its' suite of products.
After making a great app experience, you probably turned your attention to
making some money with it. And the reason you're interested in "Pirate Metrics"
and Firebase is probably because you want help doing just that. If you put into
practice some of our earlier suggestions, you should have already seen an impact
on your numbers. We also have some tools specific to revenue that might be of
help.
The first is for those of you who have in-app or E-commerce purchases as part of
your product. If you connect your Play Store account with Firebase, all your
in-app purchases will automatically be tracked for you. For E-commerce
purchases, there's just a simple event that needs to be fired. You can see your
collective revenue on your dashboard and also create audiences based on users
who made specific purchases.
The benefit of doing this is that you can segregate your paying users from your
non-paying ones, see their behavior patterns and focus more specifically on
their needs. You can also understand what made them pay and then craft the user
experience in a manner to increase the proportion of your paying users.
Additionally, AdMob can now be
integrated using the Firebase SDK, allowing you to monetize with a range of
ad formats such as banners, interstitials, native and more. You can see your
advertising revenue right inside Firebase Analytics, allowing you to understand
trends and take action.
For example, if your product gets news coverage in a particular part of the
world, you might start seeing strong growth there. In Firebase, you would be
able to spot any growth and tweak mediation settings for AdMob to capitalize on
it.
As with all other elements, the power of Firebase's offering with a specific
"Pirate Metric" is that the tool is deeply integrated with our analytics
platform. This allows you to not only make decisions on what actions need to be
taken for growth, but also follow up and determine whether the decision had the
intended consequence.
We hope you enjoyed and benefited from this series. For additional information,
do visit the official Firebase documentation.
Firebase Auth is a secure authentication system that allows users to sign up and
sign in for your application. It allows you to use federated identity through
providers, such as Facebook, Twitter, and of course - Google. When doing this,
your users will demand a rich user experience, and the burden of implementing
this will fall on you as a developer. In addition, creating apps that allow for
sign in involves a lot more than just signing in -- there are many other user
flows, such as choosing from multiple accounts, signing up for new accounts,
resetting passwords and more. This can be a lot of work!
Luckily, the open-source
FirebaseUI libraries make all of this really easy. In this post, you'll take
a look at building a simple web site that allows for sign in and sign up. You'll
use two providers: The built-in Email/Password on Firebase, and federated
identity using Google Sign-In.
Getting Started
To use FirebaseUI, you need a Firebase app or site, and you created these on the
Firebase Console. From here,
select 'Authentication' on the left (1).
When you select 'Sign-In Method' at the top, you'll be given a list of Sign-in
providers. Choose 'Email/Password' and 'Google' (2). Make sure they're enabled.
Additionally, if you are going to host these pages on your own domain, make sure
the domain is added to the list of OAuth redirect domains at the bottom of the
screen. (3).
Now, back on the Overview screen for your project, click 'Add Firebase to your
Web app', and you'll see a popup like this:
This contains all the code you need to initialize Firebase on your web site.
Let's take a look at a simple 2-page web site next: one page for signing in, and
one page for after you've signed in.
A simple site with Sign In
I've built and hosted a simple site using FirebaseUI Auth here. The first page you see when
you go to this site looks like this:
As you can see, it's pretty straightforward, with two sign-in options -- Google
and Email, matching what we configured in the Firebase console.
Clicking Sign-In with Google can have multiple effects based on the context:
If you've signed in previously on this browser, you'll be taken straight
back into the site
If you have multiple Google accounts, you'll be given the account chooser, with
the choice to pick a different account, or create a new one, like this:
If you haven't signed in on this browser, and don't have a Google account,
you'll be given the option to enter one, or create a new one, like this:
Clicking on the Create account link will take you through the standard user flow
for creating an account, which will return you to your site to sign in when
you're done.
Similarly when using Email/Password auth, you'll get the full user flow.
If you've signed in with an Email/Password combination before, and you're the
only user, you'll go straight into the site.
If you've signed in with an Email/Password combination before, but aren't the
only user, you'll get a list of accounts to choose from, like this:
This also gives you the facility to add a new account, and doing so creates a
new account on firebase that you can use to sign in in future. There are many
scenarios, with a very complex flow. To see a detailed flowchart of these, click
here.
So let's look at the code needed to implement this!
Coding the Log In Page
Here's the full source code for the Log In page you've seen in this post. You'll
see that there are two highlighted blocks. The first is the initialization code
that you got from the Firebase console earlier. The second uses the FirebaseUI open source
code to create the user interface widgets.
The things to note in the second block are the signInSuccessUrl parameter, which
is the address of the page to redirect to once the sign in is successful. Also,
note the signInOptions setting where Google Sign-In and Email Sign-In are
configured.
<!DOCTYPE html>
< html lang="en">
< head>
< title>EasyAuth</title>
<meta charset="UTF-8">
</head>
<!-- Below is the initialization snippet for my Firebase project. It will vary for each project -->
<script src="https://www.gstatic.com/firebasejs/3.6.4/firebase.js"></script>
<script>
// Initialize Firebase
var config = {
apiKey: "AIzaSyAPtNmUso5tA8d83vaJlgDHA_4C7HEgYNY",
authDomain: "authui-6818f.firebaseapp.com",
databaseURL: "https://authui-6818f.firebaseio.com",
storageBucket: "authui-6818f.appspot.com",
messagingSenderId: "596916061379"
};
firebase.initializeApp(config);
</script>
<!-- The code below initializes the sign-in widget from FirebaseUI web. -->
<script src="https://cdn.firebase.com/libs/firebaseui/1.0.0/firebaseui.js"></script>
<link type="text/css" rel="stylesheet" href="https://cdn.firebase.com/libs/firebaseui/1.0.0/firebaseui.css" />
<script type="text/javascript">
var uiConfig = {
signInSuccessUrl: 'loggedIn.html',
signInOptions: [
// Specify providers you want to offer your users.
firebase.auth.GoogleAuthProvider.PROVIDER_ID,
firebase.auth.EmailAuthProvider.PROVIDER_ID
],
// Terms of service url can be specified and will show up in the widget.
tosUrl: '<your-tos-url>'
};
// Initialize the FirebaseUI Widget using Firebase.
var ui = new firebaseui.auth.AuthUI(firebase.auth());
// The start method will wait until the DOM is loaded.
ui.start('#firebaseui-auth-container', uiConfig);
</script>
<!-- Include a simple background image & and title -->
<div></div>
<body>
<h1 align="center" style="color:white;">Firebase Auth Quickstart Demo</h1>
<div id="firebaseui-auth-container"></div>
</body>
</html>
Note that this is all the code you need to implement to get the user flows
mentioned earlier. Everything is encapsulated in the open source library.
The Signed-In page will need the first block of code in order to ensure that it
uses Firebase, and then, when the firebase.auth().onAuthStateChanged event
fires, you know the user is signed in, and you can query their exposed metadata.
Here's the code:
<!DOCTYPE html>
<html lang="en">
<head>
<title>EasyAuth</title>
<meta charset="UTF-8">
</head>
<!-- Below is the initialization snippet for my Firebase project. It will vary for each project -->
<script src="https://www.gstatic.com/firebasejs/3.6.4/firebase.js"></script>
<script>
// Initialize Firebase
var config = {
apiKey: "AIzaSyAPtNmUso5tA8d83vaJlgDHA_4C7HEgYNY",
authDomain: "authui-6818f.firebaseapp.com",
databaseURL: "https://authui-6818f.firebaseio.com",
storageBucket: "authui-6818f.appspot.com",
messagingSenderId: "596916061379"
};
firebase.initializeApp(config);
</script>
<body>
<!-- A simple example script to add text to the page that displays the user's Display Name and Email -->
<script>
// Track the UID of the current user.
var currentUid = null;
firebase.auth().onAuthStateChanged(function(user) {
// onAuthStateChanged listener triggers every time the user ID token changes.
// This could happen when a new user signs in or signs out.
// It could also happen when the current user ID token expires and is refreshed.
if (user && user.uid != currentUid) {
// Update the UI when a new user signs in.
// Otherwise ignore if this is a token refresh.
// Update the current user UID.
currentUid = user.uid;
document.body.innerHTML = '<h1> Congrats ' + user.displayName + ', you are done! </h1> <h2> Now get back to what you love building. </h2> <h2> Need to verify your email address or reset your password? Firebase can handle all of that for you using the email you provided: ' + user.email + '. <h/2>';
} else {
// Sign out operation. Reset the current user UID.
currentUid = null;
console.log("no user signed in");
}
});
</script>
<h1>Congrats you're done! Now get back to what you love building.</h1>
</html>
And that's it! Hopefully this primer will help you understand the power that you
get with the FirebaseUI Auth libraries, and how they make it much easier for you
to build web apps that sign in!
With Firebase, we've been working towards a world where developers don't have to
deal with managing servers and can instead build web and mobile apps with only
client-side code. However, there are times when you really do need to spin up
your own server. Towards that aim, we announced
the Firebase Admin
SDKs this past November.
Today, I'm excited to share two new Admin SDK features:
The Node.js SDK now contains an Admin API for sending messages via Firebase
Cloud Messaging (FCM).
The Java SDK can now be initialized from a set of built-in credentials,
making it easier to use, especially on Google infrastructure.
Admin Node.js FCM API
The new Admin
Node.js FCM API simplifies the process of sending messages via FCM. There is
no extra setup required to use this new API as the existing credential used to
authenticate the Node.js SDK handles everything on your behalf. The new API
contains methods for sending messages to individual devices, device groups,
topics, and conditions.
As an example, let's assume you are building an app for the upcoming Super Bowl
and you want to send a notification to anyone subscribed to either the Atlanta
Falcons' topic (/topics/falcons) or the New England Patriots'
topic (/topics/patriots):
var admin = require("firebase-admin");
// Fetch the service account key JSON file contents
var serviceAccount = require("path/to/serviceAccountKey.json");
// Initialize the app with a service account, granting admin privileges
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://<DATABASE_NAME>.firebaseio.com"
});
// Define who to send the message to
var condition = "'falcons' in topics || 'patriots' in topics";
// Define the message payload
var payload = {
notification: {
title: "Super Bowl LI: Falcons vs. Patriots",
body: "Your team is Super Bowl bound! Get the inside scoop on the big game."
}
};
// Send a message to the condition with the provided payload
admin.messaging.sendToCondition(condition, payload)
.then(function(response) {
console.log("Successfully sent message! Server response:", response);
})
.catch(function(error) {
console.log("Error sending message:", error);
});
You can optionally provide a third option to any of the FCM methods to provide
options for the message. For example, since the game is a little under a week
away, let's send the message with high priority and give it a time to live of
one week:
// condition and payload are the same as above
var options = {
priority: "high",
timeToLive: 60 * 60 * 24 * 7
};
admin.messaging.sendToCondition(condition, payload, options)
.then(function(response) {
console.log("Successfully sent message! Server response:", response);
})
.catch(function(error) {
console.log("Error sending message:", error);
});
This is just a taste of what the new Admin Node.js FCM API allows you to do. See
Send
Messages for more code samples and detailed documentation.
Admin Java Credential Interface
Since the launch of the Admin SDKs last November, the Node.js SDK has supported
several initialization methods while the Java SDK has only allowed
initialization via a service account certificate file. As of the latest Admin
Java SDK release, both SDKs now provide a full credential interface with some
helpful default implementations.
Upgrading to the new API is straightforward. The previous way of initializing
the SDK is via the setServiceAccount() method:
FileInputStream serviceAccount = new FileInputStream("path/to/serviceAccountCredentials.json");
FirebaseOptions options = new FirebaseOptions.Builder()
.setServiceAccount(serviceAccount)
.setDatabaseUrl("https://<DATABASE_NAME>.firebaseio.com")
.build();
FirebaseApp.initializeApp(options);
The updated way of initializing the SDK is via the
setCredential() method.
FileInputStream serviceAccount = new FileInputStream("path/to/serviceAccountCredentials.json");
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredential(FirebaseCredentials.fromCertificate(serviceAccount))
.setDatabaseUrl("https://<DATABASE_NAME>.firebaseio.com")
.build();
FirebaseApp.initializeApp(options);
The Admin Java SDK now includes a credential implementation based on Google
Application Default Credentials. This allows for auto-discovery of service
account credentials on Google infrastructure like Google App Engine and Google
Compute Engine. This means you don't need to manage service account credentials
yourself. Instead, you can make use of Google Application Default Credentials to
run the same exact code on your local, staging, and production environments, no
configuration required.
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredential(FirebaseCredentials.applicationDefault())
.setDatabaseUrl("https://<DATABASE_NAME>.firebaseio.com")
.build();
FirebaseApp.initializeApp(options);
See Initialize
the SDK for more code samples and detailed documentation.
What's next for the Admin SDKs?
We are continually striving to expand our first-class support for backend
developers in the Firebase ecosystem. Stay tuned for more features to be added
to the Firebase Admin SDKs in the future! If you'd like to see a specific
feature, let us know by sending us a note through our feature
request support channel.