WorryFree Computers   »   [go: up one dir, main page]

Laurence Moroney
Stewart Miles
Staff Software Engineer

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 game developers . 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!

Laurence Moroney
Laurence Moroney
Developer Advocate
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.
Exploring Email Verification
Let's see this in action. The following screenshots are taken from the Firebase Auth quickstart, available at https://github.com/firebase/quickstart-android.

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:

mStatusTextView.setText(getString(R.string.emailpassword_status_fmt,
                    user.getEmail(), user.isEmailVerified()));

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.

James Tamplin
James Tamplin
Product Manager
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!

Todd Kerpleman
Todd Kerpelman
Developer Advocate
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!


Laurence Moroney
Laurence Moroney
Developer Advocate
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!
You can find FirebaseUI for Android here.

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.
  1. 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
  2. If there is only one Google Account, and you used it previously to sign in, then you can sign in right away with it.
  3. 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:

 FirebaseAuth auth = FirebaseAuth.getInstance();
        if (auth.getCurrentUser() != null) {
            startActivity(SignedInActivity.createIntent(this, null));
            finish();
        }

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:

@OnClick(R.id.sign_in)
    public void signIn(View view) {
        startActivityForResult(
                AuthUI.getInstance().createSignInIntentBuilder()
                        .setTheme(getSelectedTheme())
                        .setLogo(getSelectedLogo())
                        .setProviders(getSelectedProviders())
                        .setTosUrl(getSelectedTosUrl())
                        .setIsSmartLockEnabled(mEnableSmartLock.isChecked())
                        .build(),
                RC_SIGN_IN);
    }


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:

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == RC_SIGN_IN) {
            handleSignInResponse(resultCode, data);
            return;
        }

        showSnackbar(R.string.unknown_response);
    }


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:

  private void handleSignInResponse(int resultCode, Intent data) {
        IdpResponse response = IdpResponse.fromResultIntent(data);

        // Successfully signed in
        if (resultCode == ResultCodes.OK) {
            startActivity(SignedInActivity.createIntent(this, response));
            finish();
            return;
        } else {
            // handle failure conditions
  }
    }


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:

<style name="DarkTheme" parent="FirebaseUI">
        <item name="colorPrimary">@color/material_gray_900</item>
        <item name="colorPrimaryDark">@android:color/black</item>
 …
</style>

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.

You can find the FirebaseUI Auth classes on GitHub at: https://github.com/firebase/FirebaseUI-Android -- check them out and get involved!

Todd Kerpleman
Todd Kerpelman
Developer Advocate
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]:

  FIRAnalytics.logEvent(withName: "workout_complete", parameters: [
    "time": 1804
    "exercise_type": "interval"
    "intensity": 2
  ])
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…
FIRAnalytics.logEvent(withName: "workout_complete", parameters: [ "time": 1804 "exercise_type": "interval" "intensity": 2 kFIRParameterValue: 1804 ])
...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. :)

Parul Soi
Parul Soi
Developer Relations Program Manager
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.


Laurence Moroney
Laurence Moroney
Developer Advocate
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!



Jacob Wenger
Software Engineer
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.