We're excited to announce the full speaker list and agenda for the first ever Firebase Dev Summit!
Find the latest schedule on our newly launched site herefeaturing sessions such as How to Develop Rock Solid Apps with Firebase, a Firebase Analytics deep dive, Develop Mobile Apps without Infrastructure , and more!
The Firebase Dev Summit is on Monday, November 7th with a full day of talks, codelabs and office hours. The Summit will end with an afterparty where you can enjoy drum and bass and mix and mingle with event attendees and the Firebase team.
Tickets are sold out, but you can sign up for the waitlist to be notified if a spot becomes available. We will also livestream the entire event in case you want to join us online. Sign up to receive an receive an email alert when sessions are about to start!
We want to hear from you! Join the conversation on Slack, G+ and Twitter.
We wanted to let you know that we've made some new updates to the Firebase libraries for iOS, Android, as well as the Javascript SDK. You can read the full release notes here, but let's give you a quick summary of some of the new features you should be aware of:
The Firebase Analytics library now includes screen tracking, to help you understand what parts of your app your users are spending most of their time on. This will automatically track screens by View Controller or Activity, but you can also set these manually, in case your app's concept of a "screen" is something different than that.
Firebase Crash reporting for iOS now supports Swift 2 and 3.
There are some new features in the Firebase console, like being able to give your projects nicknames (I've named mine "Kevin") and being able to set the currency for your analytics reports.
Dynamic Links has a REST endpoint you can call to automatically shorten any dynamic link you've created.
And, of course, a bunch of little bug fixes here and there.
You can read our release notes for iOS, Android, and webplatforms to get all the details. Or you can just start playing around with the new libraries. That's fun, too.
Private Backups is a good solution for backing up, scripting, and gathering analytics by regularly exporting your entire Database. Previously, setup involved a bit of back and forth between the user and Firebase Support. We are now offering a self-service user interface for Blaze customers in the Firebase console that seamlessly enables daily backups of your Firebase Database to a Google Cloud Storage bucket.
To get started, visit the new “Backups” tab in the Database section of the Firebase console, and the wizard will guide you through setting up your automated backups.
To save on storage costs, we enable Gzip compression by default, and you can choose to enable a 30-day lifecycle policy to have backups older than 30 days automatically purged.
When the setup process is complete, you will have a Google Cloud Storage bucket. On a daily basis, we will backup your Database’s application data and rules in JSON format to your bucket. You can view the status and history of all your backups directly in the Firebase console. There is also a “Manual Backup” button which lets you instantly enqueue a current backup of your database and rules, and is incredibly useful to take specific timed snapshots or as a safety action before you perform any code changes.
Here are three good reasons to start using automated backup today:
Offline Scripting
Automatic Database Backups let you crawl, analyze, and perform large scripted actions against your data without affecting the realtime performance of your customers connecting to the Database.
Historical Data Analysis
With historical snapshots of your database, you can retroactively analyze your data, look for trends, and make product decisions based on past data points.
Recovery From Corrupt or Lost Data
With Automatic Database Backups, you can easily restore your data in the event of data corruption or loss. To restore your database, simply download1 a backup file to your local machine from the backups tab. You can then click the "Import JSON" button2 under the data tab to restore your Database to a previously backed-up state.
We are continuing to streamline the experience for Firebase developers, and this new release gives developers more control over their data while reducing the need to go through support processes.
Notes
With Gzip enabled, you will need to decompress your database data before importing back into Firebase. ↩
For very large Databases, it is more efficient to contact support for data restoration from our own regular backups, rather than through the JSON files of Automatic Database Backups. ↩
Today we're announcing web support for Firebase Cloud Messaging (FCM) with the release of a JavaScript library. This extends our current browser support, enables a dramatically simpler implementation process, and brings powerful features such as Topics and Device Group Messaging to the web.
Notifications are one of the most compelling tools for developers to build engaging experiences. Since we introduced the technology in Chrome, we've seen tremendous adoption, with more than 10B notifications being sent per day to websites. However, developers often tell us that implementing this feature on the Web can be challenging and that they want to access the same advanced features of FCM that are available on native notifications.
Firebase Cloud Messaging is a powerful system that already supports sending messages to iOS apps, Android apps, and Chrome. Starting today, developers can use FCM to send messages to browsers that support the Push API, allowing you to go beyond Chrome and also send to Firefox, Opera and others.
It is easier than ever to send notifications to your web users with the FCM JavaScript library, as FCM handles complex server-side features such as payload encryption and client-side features such as service workers.
You can use a default service worker implementation to get started quickly, and when you are ready to extend and override it, you can do so easily. In addition to this, when you’re using the FCM APIs, our servers can manage payload encryption for you. FCM users don't need to change a thing in their server implementation to achieve this!
However, the technical aspect of web notifications is just a start. In order to make the most out of web notifications, you need to engage your users with the right content in the right manner. Check out our “What Makes a Good Notification?” post for best practices on notification content and “Best Practices for Push Notifications Permissions UX“ post for tips on interacting with Web users to get permission for sending notifications.
Which FCM features are supported?
Beyond providing an easier client implementation, the FCM JavaScript library also brings important FCM features to the Web.
With the FCM JavaScript library, you can send web push notifications to single devices, topics or groups of devices. With the addition of topic support on the Web, we are making it possible for developers to send a message to their Android, iOS and Web users who have opted in to a particular topic. To take advantage of topics and device groups, you can use the server-side APIs to manage your topics and groups subscriptions.
Browser Coverage
Currently the FCM JavaScript library enables developers to reach browsers that have Push API support. Namely:
Chrome Desktop and Mobile (version 50+)
Firefox Desktop and Mobile (version 44+)
Opera on Mobile (version 37+)
Microsoft Edge has announced plans to support the Push API and Samsung Browser will be covered once they have message payload support. This coverage will increase over time as more browsers introduce support for service workers. Make sure to check out our release notes for updates!
How do I Get Started?
Just follow our Getting Started guide, and make sure to checkout our Firecast video!
What have our partners done?
We have been working with early adopters to test, refine, and unleash the power of the new FCM JavaScript library, and create the best possible Web notification experience for users. Below are some of their success stories:
“We were unable to find any effective solution for notifications until we found FCM… FCM is the best solution because of its rich features, stable performance, and easy deployment.”
Zou Yu, Director of Alibaba.com Mobile
Alibaba.com, the leading wholesale marketplace connecting overseas buyers with suppliers in China, implemented our solution in two days and saw 4X higher engagement for users who receive web notifications compared with users who visit the website directly. See the full Alibaba.com case study.
AliExpress, a global retail marketplace, saw a 93.4% higher open rate on the web compared to their app notifications, and a 178% higher conversion compared to mobile site users who do not receive notifications. The AliExpress team is continuing to expand their uses cases. For instance, to promote sales on 11th November (also referred to as “Double 11”) - a festival commonly celebrated by young Chinese singles and also one of the biggest online shopping events in the world - AliExpress will be using FCM to send notifications on its website to remind users to take advantage of discounts on items they are interested in. See the full AliExpress case study.
“The initial implementation was very easy - really a one-day job.”
Filip Procházka, Developer
Settle Up, a fast-growing startup that helps users track shared expenses, wanted to send notifications to users when changes were made to a bill. After implementing in a day, they began to see 37% higher engagement for users who receive web notifications. Moreover, as a user of Firebase Analytics, Crash Reporting, Hosting, and Test Lab, Settle Up was able to easily access all their tools through Firebase as a unified solution. See the full Settle Up case study.
Start now
Firebase Cloud Messaging is part of the Firebase platform and is available for free. We are excited to announce this launch and can’t wait to hear what you think!
Firebase Authentication supports four federated Identity Providers out-of-the-box, making it super easy to authenticate with Google, Facebook, Twitter and GitHub. For example, in a web app all you need to sign in your Firebase users with Google is:
var google = new firebase.auth.GoogleAuthProvider(); firebase.auth().signInWithPopup(google);
However you may be interested in using other Identity Providers to let your users sign into your Firebase app. For example, Instagram can be a nice alternative especially if you plan on also using the Instagram API to let users share their Instagram photos.
Using Identity Providers for which Firebase doesn’t have built-in support is possible, but requires a bit more code, and a server. Let’s walk through the steps required to integrate Instagram Sign-In in a Firebase web app. Instagram uses OAuth 2.0 for sign-in, so this post should help you integrate with other OAuth 2.0 identity providers such as LinkedIn as well.
Design Overview
Instagram supports OAuth 2.0 as its main way to authorize apps and access user data which includes the Instagram user’s identity. You need to have the user go through the OAuth 2.0 auth code flow and grant access to your app. Here is how the OAuth 2.0 flow goes:
First the user needs to be redirected to the authorization endpoint of Instagram which will present the user with a consent screen the first time they are asked to grant access to your app. We’ll do that in a popup window.
After authorizing your app, users will be redirected back to your domain with an auth code. The auth code can be exchanged server side for an access token using your Instagram app’s credentials. In the process of exchanging the auth code, Instagram will also return the user identity (this sometimes requires an additional request with other OAuth 2.0 providers like LinkedIn).
On the server, once we have fetched the Instagram user information, we’ll create a Firebase custom auth token. This token will allow the user to sign-in into Firebase in our web app using the signInWithCustomToken method.
We’ll also pass the user profile information that we got from Instagram such as the display name and the photo URL so that we can update the Firebase profile on the client - Note: Instagram does not provide the email of the user so we we’ll have a Firebase account without an email, which is fine. Once done we close the popup and Voila! your user is signed into Firebase with profile data from their Instagram account.
Let's build it!
Let’s now go into a bit more details and look at how to implement the key points of this integration. We’ll be writing our backend in Node.js.
Register your app with Instagram
You’ll need to add a button on your web app which starts the Instagram auth flow. Before we do this you’ll first need to register your application on the Instagram Developers console so that we can get your app credentials which are needed for OAuth 2.0.
In your Instagram app’s configuration make sure you have whitelisted http://localhost:8080/instagram-callback (for testing) and https:///instagram-callback (your production domain) as valid redirect URIs. Now take note of your Instagram Client ID and Client Secret. You’ll need them for later.
This is a typical step you’ll have to make with every OAuth 2.0 providers: register your app and whitelist callback URLs in return for a Client ID and Secret.
Configure Instagram’s OAuth 2.0
On the server we’ll be using the simple-oauth2 package which helps with hiding the details of the OAuth 2.0 protocol. You need to provide a few values to set this up such as your Instagram Client ID and Secret and the Instagram’s OAuth 2.0 token and authorization endpoints. Here are the values you need to use for Instagram:
On your server, add a URL handler that redirects the user to the Instagram Consent screen. As part of this, you’ll need to provide a Redirect URI which is where the user will be redirected back to after going through the Instagram auth flow. In our case we’ll use /instagram-callback as our callback handler path.
app.get('/redirect', (req, res) => { // Generate a random state verification cookie. const state = req.cookies.state || crypto.randomBytes(20).toString('hex'); // Allow unsecure cookies on localhost. const secureCookie = req.get('host').indexOf('localhost:') !== 0; res.cookie('state', state.toString(), {maxAge: 3600000, secure: secureCookie, httpOnly: true}); const redirectUri = oauth2.authorizationCode.authorizeURL({ redirect_uri: `${req.protocol}://${req.get('host')}/instagram-callback`, scope: 'basic', state: state }); res.redirect(redirectUri); });
Also, to avoid session fixation attacks, pass a random string in the state parameter of the OAuth request and also save it as an HTTP cookie. This will allow us to compare the state parameter that we get back with the one saved in the cookie and make sure the flow originated from the app.
On the client, add a button which triggers a popup like this:
function onSignInButtonClick() { // Open the Auth flow in a popup. window.open('/redirect', 'firebaseAuth', 'height=315,width=400'); };
When a user clicks the sign-in button, a popup is opened and the user is redirected to the Instagram Consent Screen:
Upon approval the user is redirect back to the /instagram-callback URL handler with an Authorization Code passed in the code URL query parameter and the state value that we passed earlier.
Exchange the Authorization Code for an access token
Once the user has been redirected back to the callback URL we:
Check that the state cookie is equal to the state URL query parameter.
Exchange the auth code for an access token and retrieve the user identity from Instagram.
app.get('/instagram-callback',(req, res) => { // Check that we received a State Cookie. if (!req.cookies.state) { res.status(400).send('State cookie not set or expired. Maybe you took too long to authorize. Please try again.'); // Check the State Cookie is equal to the state parameter. } else if (req.cookies.state !== req.query.state) { res.status(400).send('State validation failed'); }
// Exchange the auth code for an access token. oauth2.authorizationCode.getToken({ code: req.query.code, redirect_uri: `${req.protocol}://${req.get('host')}/instagram-callback` }).then(results => { // We have an Instagram access token and the user identity now. const accessToken = results.access_token; const instagramUserID = results.user.id; const profilePic = results.user.profile_picture; const userName = results.user.full_name;
// ...
}); });
We’re now done with the OAuth 2.0 specific part of this implementation and what we’ll do next is mostly Firebase specific.
Next we’ll create a Firebase custom auth token and serve an HTML page that will sign the user in using the custom auth token and update the Firebase user profile (more about that later).
app.get('/instagram-callback', (req, res) => {
// ...
}).then(results => { // We have an Instagram access token and the user identity now. const accessToken = results.access_token; const instagramUserID = results.user.id; const profilePic = results.user.profile_picture; const userName = results.user.full_name;
// Serve an HTML page that signs the user in and updates the user profile. res.send( signInFirebaseTemplate(firebaseToken, userName, profilePic, accessToken))); }); });
Creating the Custom Auth Token
To create a Firebase custom auth token, you’ll need to setup Firebase with a service account credential. This is what gives you administrative privileges required to mint these tokens. Make sure you save the service account credentials file as service-account.json:
Minting a custom auth token is simple, you just need to choose a uid for the user based on its Instagram’s User ID:
function createFirebaseToken(instagramID) { // The uid we'll assign to the user. const uid = `instagram:${instagramID}`;
// Create the custom token. return firebase.auth().createCustomToken(uid); }
Note: Because service account credentials must be kept secure, creating custom tokens should always be done server-side.
Once we have the custom token we can pass it to the client to sign-in into Firebase.
Use the custom token to sign in
At this point the server will serve an HTML page that is ran inside the popup window and will:
Save the Instagram access token to the Realtime Database in case you need it to access the Instagram API later (Note: make sure you use security rules so that it’s only readable by the user).
Update the name and profile picture of the Firebase user.
Sign the user in and close the popup.
One trick is to use a temporary Firebase App instance to update the profile instead of using the default Firebase app. This prevents the Auth listener on your main page to trigger before the user’s profile has been updated:
app.get('/instagram-callback', (req, res) => {
// ...
// Serve an HTML page that signs the user in and updates the user profile. res.send( signInFirebaseTemplate(firebaseToken, userName, profilePic, accessToken))); }); });
function signInFirebaseTemplate(token, displayName, photoURL, instagramAccessToken) { return ` <script src="https://www.gstatic.com/firebasejs/3.4.0/firebase.js"></script> <script src="promise.min.js"></script><!-- Promise Polyfill for older browsers --> <script> var token = '${token}'; var config = { apiKey: MY_FIREBASE_API_KEY, // Change this! databaseURL: MY_DATABASE_URL // Change this! }; // We sign in via a temporary Firebase app to update the profile. var tempApp = firebase.initializeApp(config, '_temp_'); tempApp.auth().signInWithCustomToken(token).then(function(user) {
// Saving the Instagram API access token in the Realtime Database. const tasks = [tempApp.database().ref('/instagramAccessToken/' + user.uid) .set('${instagramAccessToken}')];
// Updating the displayname and photoURL if needed. if ('${displayName}' !== user.displayName || '${photoURL}' !== user.photoURL) { tasks.push(user.updateProfile({displayName: '${displayName}', photoURL: '${photoURL}'})); }
// Wait for completion of above tasks. return Promise.all(tasks).then(function() { // Delete temporary Firebase app and sign in the default Firebase app, then close the popup. var defaultApp = firebase.initializeApp(config); Promise.all([ defaultApp.auth().signInWithCustomToken(token), tempApp.delete()]).then(function() { window.close(); // We’re done! Closing the popup. }); }); }); </script>`; }
After the user is signed-in into the default Firebase app inside the popup, the auth state listener will trigger on your main page (remember, with Firebase the auth state is shared across tabs) and voila! You can display the user profile information, use the Realtime Database, Firebase Storage, etc...
The code shown in this article so far will work for your web apps. There are a few techniques to add Instagram auth to your Android or iOS app and we won’t cover them in this post, but stay tuned!
That's it!
Let us know in the comments, or using the GitHub repo issues if you are looking for samples for other Identity providers or if you’re having problems integrating with them and we’d love to help!
Angular version 2.1.0 - incremental-metamorphosis - is now available. This is a minor release following our announced adoption of Semantic Versioning, meaning that it contains no breaking changes and that it should be a drop-in replacement for 2.0.x. We encourage everyone to stay up to date with the latest version of Angular.
What's new?
The Router now supports preloading of lazy loaded modules, which gives users the best of both worlds; applications bootstrap quickly, and users don't need to wait for a round trip to the server to access lazy loaded content. Watch Victor Savkin present these capabilities at Angular Connect.
Animation in Angular has been enhanced by adding :enter and :leavealiases for the commonvoid => * and * => void state changes. The transition API documentation has been updated with these aliases.
This release is intentionally small. It matches what you should expect to see going forward. We are working hard to provide smaller more frequent releases with a smooth upgrade path.
One of my favorite features of Firebase Remote Config is its ability to deliver different content to different groups of users. For instance, you can change the look and feel of your storefront for people who have spent a lot of money in your app. Or you could emphasize one part of your fitness app for runners and another for weightlifters.
Ever since Remote Config first launched, you could accomplish some pretty sophisticated user targeting by delivering different content to people who were in different Firebase Analytics audiences.
But more recently, Remote Config added the ability for you to send different sets of data to people with different user properties, which has made this feature even more useful.
"Wait a second," you might be saying. "I can already target users with audiences, which allow more sophisticated targeting than just a user property. Why is this any better?"
And it's true; audiences give you some very powerful and very specific user targeting by enabling you to create groups of users who can be defined by a number of different events and user properties. For instance, you could create an audience of "Left-handed Canadians who have completed level 5 in my game."1
But audiences have two limitations that can make them more difficult to use within Remote Config:
First off, you're limited to 50 audiences, and they're shared among people who might be using these same audiences for other targeting features within Firebase, such as running Analytics reports, or building remarketing campaigns via Google AdWords. This makes it more difficult to create several smaller ad hoc user groups, or to edit existing audiences that other people in your organization might be using.
Second, with the way audiences currently work, once a user joins an audience, they can never leave. To your average marketer who uses audiences for remarketing campaigns, this might be exactly what they're expecting, but for Remote Config purposes, this can sometimes be problematic.
Imagine you wanted to create a "Newbies" audience of people who have started your game but not yet completed level 10. If you tried creating an audience out of this group, everybody who started your game would be placed into this audience. But then they would remain in this audience even if they reach level 15 or 20, essentially turning this into an "All players" audience.
And that's why, when I'm targeting users in Remote Config, I prefer to use User Properties as a way to personalize my content. They allow me to create lots of smaller one-off targeting groups, and let me be little more dynamic than with traditional audiences.
For instance, let's say you have a fitness app and wanted to deliver a different front page image based on the user's favorite fitness activity. If you have that favorite exercise stored as a user property, you can easily set that up by creating a new condition based on that property.
Then you can show a different front page image based on each one of those conditions.
In this way, you could easily create a half dozen different conditions and not worry about "using up" those Firebase Analytics audiences.2
Or imagine you have a game and you want to change aspects your game's behavior based on what level the user is at. You can do that by storing that level as a user property and then creating a number of different conditions based on these tiers. For instance, I can create a "intermediate" tier of players who are in between levels 4 and 10…
...and give a different daily bonus to those players.
As users progress in level, Remote Config will automatically start delivering them different values based on their level as their user property places them in different tiers. And I don't need to create new audiences for each one.
It's also simple to change these groupings later. If, in the future, I decide that my intermediate tier should really start at level 6, I can make that change within the Firebase control panel, and those changes are pushed out immediately to Remote Config.
Heck I could even add in a fourth tier if I suddenly decide I need to change my game's behavior for the the extra special players.
By default, user properties are stored as strings, which means you can run string comparisons like "exactly matches" or "contains" against them. If you stored your user's top 3 fitness activities as a pipe separated string (e.g. yoga|interval_training|running) you could create an "All runners" condition by targeting anybody whose fitness activities contained the string "running."
But you can also run numeric comparisons against them, as we did in the playerLevel example above. Remote Config will translate strings to numbers as you might expect; "42" evaluates to 42, "3.14159" evaluates to 3.14159, and so on. Numeric comparisons with user property strings that don't translate to integers or floats (e.g. "Level_42") will always fail, however.
Being able to target user properties is a relatively new feature, so if you haven't played with it yet, I encourage you to give it a try. Head on over to the Remote Config panel and try making a minor change based on a user property you're already storing. Once you have that working, stop and think what parts of your app could really benefit from personalization, and considering adding another user property or two to support that.
And if you end up building something cool, let us know! We'd be excited to hear about it.
1Assuming you targeted "handedness" as a user property, that is.
2To be fair, there is also a limit to the number of Remote Config conditions you can create, but it's 100, which gives you a lot more room to experiment.