So while looking into Google Cloud Platform, Frank discovers Firebase, Google Cloud's mobile platform. So he starts digging more into what Firebase has to offer and he gets really excited after he learns about all of Firebase's great products. More specifically, Frank's interested in using Firebase's back end products to help him build his app quickly and easily. He can use Firebase authentication to manage all of his users. He can use the real-time database to store and retrieve chat messages. He can also use Cloud storage to store all those images that are going to be uploaded by his friends. So this will save Frank a bunch of time. And since he can use these products right away, he doesn't have to worry about setting up his own servers or building out all these features from scratch on his own. So there is a problem though. This might not be as easy as he originally thought. So Frank mapped out a few great core features that he really wants to add to Hipster Chat.
Many of these common use cases are found across many different mobile apps. For instance, he wants to send notifications when messages are posted to a particular chat room. He wants to resize images after they've been uploaded to Cloud storage. He also wants to filter offensive language that's written to the database. So Frank also wants use data from Firebase analytics to somehow incentivize his most engaged users. So now Frank's a little concerned because these are all extremely important features to him, and he's worried because this is becoming much more complicated than he originally thought. So let's take one of those use cases, resizing images. So sure, resizing images is actually quite simple from when you're trying to create your own custom back end. But the issue here is if he puts it back in between his app and Firebase, Frank loses out on some of the best features that Firebase actually has to offer. So, Frank's custom back end will be able to handle thumbnail creation no problem.
But he'll have to re-implement many of the features that he would have gotten for free if he were using the Firebase SDKs and communicating directly with Cloud storage. One, he'll have to re-implement rezoomable uploads as well as rezoomable downloads. He won't get tight integration with Firebase auth to help with end user authentication. With his custom back end, he may end up having to pay for resources that he's not actually utilizing. Now Frank may also have to worry about building and scaling a custom back end from scratch to meet the demands of his app, which is surely going to be a top 10 app. So well starting today, Frank can actually do all of this in Firebase. So he can do this without the added complexity of setting up servers and creating his own custom back end. Best of all, he can still do all these things very quickly and very easily. So today we launched Cloud Functions for Firebase in a public beta. We've been working very closely with the Cloud Platform team on this for quite some time.
If these conditions are met, your function will be triggered and a new instance will be spun up. Then the code within your function will be executed. Now within this code, you can make calls to other services and APIs and as a result, you can choose to invoke other functions since some of these services may actually emit events as well. So after your code is finished executing, your function will spin down and you only pay for what you use with Cloud Functions. So let's quickly jump back to Frank's app and see how he can actually resize images now that he has Cloud Functions. First, you'll notice that he no longer has to deal with setting up his own servers and a custom back end. His app can now communicate directly to Cloud storage using the Firebase SDKs. So this will give him all the added benefit that we talked about earlier. So now Frank can create a Cloud Function to resize images that'll be triggered when any image is uploaded to Cloud Storage at a specific bucket.
So he won't need to set up and manage his own servers, he won't need to worry about manually scaling his service to meet the demands of Hipster Chat, and Frank can have a completely serverless back end for his mobile app using Cloud Functions. And he can still do everything that he wants quickly and easily. And that makes Frank really happy. So Cloud Functions for Firebase has support from many different event providers from Firebase as well as Cloud. These integrations allow you to extend their functionality through Cloud Functions. So for instance, real time database lets you trigger a function when a write occurs at a particular path in the database. The Firebase authentication integration lets you trigger a function whenever a new user is created or whenever a new user is deleted. The Firebase analytics integration lets you trigger a function whenever a new conversion event is [? logged. ?] Cloud Storage for Firebase lets you trigger a function when a storage object changes within a bucket.
But we really love this demo. It's so simple, we had to add a space filler and add a new graphic showing you that it works. But screenshots aren't as fun, so let's actually go into production. Can we switch to the laptop? So, Cloud Functions integrates with the Firebase command line tools and it's is easy to use as ever. All you need to do is type Firebase deploy. This is because our SDK and our CLI work seamlessly together. We can load your code and understand which Cloud Functions are in your app. Once we finish deploying that code, any HTTPS functions' URL will be printed here. We can click and in that time, Cloud Functions is able to find or create an available instance, spin up your code, and serve the request. So now we can jump to the Firebase console and check out all of our Cloud Functions with a bird's eye view. This console lets us see how many functions have been deployed, what will trigger those functions, how many times they've been fired, and how quickly they're running.
Each message has a unique ID and there's a standard field for the text. You can find out how to write this app and much more for iOS, Android, and the open web on our YouTube video Zero to App. But what if we made our app a little bit more complex? What if the database already had translations in it? Well now we can see that can very trivially update the UI so that only renders the message that's in the user's preferred language. But of course, the big question then is how do we get the database in this state? Well, Google has two great products that Frank can use. There's the Firebase real-time database that he's already using and Google Translate. Now Translate does have an API, but it's meant for server side use. So how can Frank use this API without including a server key inside his mobile app? Well we're here at this talk today, so I'm assuming you can guess that it's Cloud Functions. He'll write a Cloud Function that listens to the database at messages/ID/message.
Now notice the ID here is in curly brackets. This is one of my favorite features of our integration with the real-time database because that's a wildcard. That means that we will match on both the left and the right side of that wildcard and we'll capture the actual value as an event parameter. This means that a single Cloud Function has the power to listen to events that would have taken thousands and thousands of listeners before today. Once our Cloud Function is started, we're going to make a few requests to the Google Translate API. First we're going to ask for the list of currently supported languages and then we're going to ask for that message be translated in each of those languages. As we get results back, we'll stream them back to the Firebase real-time database. So let's code it up and see it in action. Can we switch to the laptop please? Cool. So because Cloud Functions is a Vanilla Node mod– or Node client, we can use Node modules. You can benefit from the community of Node developers out there.
A delta snapshot is everything a data snapshot is and more. So next, let's go ahead and get the set of translations or the set of languages available from Google Translate. This function can either take a callback or return a promise. And I'm going to return a promise here. I can either say then and continue that way. But since I'm using TypeScript, I can just say await. Now code will continue after that's completed. The Google Translate libraries return an array of two values. The first is a simplified value and the second is the raw values from the REST API. Since I only want the simple values, I'll do this to extract that. Cool. Now that we have our list of languages, which are over 100 supported languages, I want to fire than more than 100 network requests off at the same time. I'm going to need to eventually keep track of that work so let's create a temporary. For each language, I want to do something. And because it has that array, I will extract the first volume.
So now we have over 100 requests running at the same time and I will take that value and save it back to the database. I'm going to need a reference to the database, which comes as part of every snapshot. There's a dot ref that is where that snapshot came from. Now this reference here is to this message node. If I want to make a peer, I'm going to go up one level and then back down to the language code. And set that to the translation. Now with an async function, I can either await the result or just return it. Now all my work has been complete. I just want to make sure that my Cloud Function doesn't terminate until all the requests are done. So I can create a promise with promise dot all, and that will wrap up everything that's outstanding. By returning that promise, Cloud Functions knows that I have background work and it will keep the Cloud Function alive until that work completes. So let's try this out in production. It's the moment of truth. So I needed to have a write that matches messages and some value.
This one can take a little bit like I said, there is over 200 requests in here. 100 languages, 100 writes back to the Firebase database, but there we go. [APPLAUSE] So let's switch back to the slides and find out what's on Frank's list. So, Franks loves his users and wants to make them feel welcome in Hipster Chat. He hears that bots are so hot right now. And so he decides to write his own, Mr. Mustachio. Mr. Mustachio's first task is going to greet new users in the general chat room. Well luckily, Firebase authentication also works with Cloud Functions. It supports two kinds of events, the creation of a user or deletion of a user. Deletion events are great for things like clearing out the profile information of a user when they leave your app. But today we're going to use a user creation event to give our bot some life. So let's switch back to the [INAUDIBLE]. There we go. So in this demo, I'm going to use the Firebase Admin SDK. This is the SDK that we've written to help you build a server side app.
And of course we've been thinking about Cloud Functions the entire time. To initialize the SDK, we need to call initialize app. And to do that, we're going to use a feature called functions.config. Functions.config is a snapshot of Google runtime config from the time that your app was deployed. This is a great way to make sure that your code stays– or and your config stay cleanly separated. This is a great way to make sure that your apps stay testable. And we've added a special variableness config called Firebase. This is automatically populated and has everything you need to initialize a Firebase app. So we're going to create a new Cloud Function, this time integrating with Firebase Auth. We're going to listen to a user event, specifically the user creation event. Now this time, the event data is a user record, which makes sense because a user record is what is returned when you call create user. Now in order to write a message, we're going to need to push a new value into our database.
Here, we just have the text of the most interesting part. We're using the display name from that user record to make sure we greet the user. The rest of this here is part of our– how we actually inform our UX to make sure Mr. Mustachio is visible as a bot. So let's see it in production. And watch how fast it was, too. Say let's go back to slides. So some time has passed. Hipster Chat has been growing. It has so many users in so many rooms that Frank now needs to add a feature to let people get others' attention if they're subscribed to a room but not currently reading it. So he's going to add @here mentions. Frank does a little bit of research and he knows about Firebase Cloud Messaging. It's a cross-platform product that lets you send notifications across iOS, Android, and the open web. But there's only one problem. He looks at the quickstart sample and sees that there's a stubbed out message called send token to server. That's because until today, you've needed a custom server in order to be able to programmatically send notifications.
But not anymore. See, Frank is clever. He knows that the Firebase database has very flexible security rules. He can create private areas in the database that are restricted to each user. And so he's going to implement his send token to server method so that it pushes a device token in an area that is based off of the user ID. Now he has secure storage for all his device tokens and he can let Cloud Functions do some magic. Now we're going to break our push back end into two parts. Rather than looking up every device token for every user that's in the topic– or in the room whenever you get an @here, we're going to have a subscription management piece in the part that actually does the sending. This is the first part. We're going to listen to the change of all users in all rooms. Whenever we notice that a user has joined or left a room, we're going to subscribe or unsubscribe from an FCM topic respectively. This will dramatically simplify our push code because now we can just scan messages.
If they contain an app mention, we can send a push notification based on a topic corresponding to the target room. So, let's jump back to some code. To bump the difficulty one more time, this demo is actually going to use raw HTTP requests. So I'm going to add yet another library. So, that first function was a database function. I said for every room wildcard, every user wildcard, we're going to listen to any write. Now that could have been a user insertion or deletion, so we're going to find out which and map it to the actions that Cloud Messaging supports, either a batch add or a batch remove. Next, we're going to need the list of devices that are associated with this user account. So we're going to use the Admin SDK again. We're going to look up the values in that private storage. Now it's possible a user doesn't actually have any tokens. For example on iOS, the user might have disabled notifications altogether. So let's check for that first.
If the snapshot does not exist, the user has no tokens, we'll log a debug message and exit. Otherwise, we'll log a different debug message about how we're adding or removing tokens. Oops, jumped ahead of myself. So since we're making HTTP requests, we're going to need to authenticate it. For this, we're going to look at that Firebase config again. See, part of that Firebase variable is the credential that the SDK itself is using to authenticate. And that credential serves [INAUDIBLE] tokens. So you can get the same cacheable token that we use if you're making any requests to another Google service. Now all we have to do is make our HTTP request. We're going to send a post to this address using the action we decided earlier, either batch add or batch remove. To authenticate, we'll add some headers. And then our body will be the topic that we want to modify and the list of tokens we want to use. So this could be a full subscription service. As an exercise for the reader, there's some other stuff you can do.
For example, this method has return value and contains an array of a list of objects that correspond to either success or an error if that token was expired or invalidated. But now with our subscription service in hand, we can try push notifications. We'll write another database event handler where we listen to the text field of every message in every room. Now if there was no @ mention, which is fairly common, we can just early exit. This is a small– or a simpler version of what we did before where we console logged and then returned because the return value of every function is logged in the Google Cloud logging console. So next, we have the room ID from this event. That's a stable identifier but it's not human readable. We actually have a title for our various rooms. So we'll use the admin SDK one more time to look up that room's title based on its ID. Now we'll construct our payload. We're going to send the message to a topic based on the room ID and a message that includes the friendly room name.
And then we use the messaging features inside the admin SDK to send that message. So, let's go ahead and see it in production. [INAUDIBLE] I missed it. There we go. Serverless push notifications. [APPLAUSE] And let's go back to slides for one last scenario. So, Hipster Chat has been growing and Frank has his eye on quality. He's hungry for insight so he uses Firebase Analytics to learn how people use his app. He's so hungry for feedback that he added a feature where his users can fill out a survey. He's hungrier still, so he even has an analytics event to track when people fill out the survey. And maybe Frank is just hungry. Frank was in his coffee shop munching when he had an idea. He wants to incentivize people to fill out this survey, so he's going to have a giveaway. His favorite treat of vegan gluten free kale muffin to the next 12 people who fill out this survey. There's a number of reasons why Frank has already marked the feedback sent event as a conversion event.
For one, it lets him create a user funnel so you can see what actions lead people to actually fill out surveys. Next, he can use this to create an audience which lets him understand whether the people who fill out his survey are actually representative of his normal demographic. And starting today, Frank can listen to this conversion event with a Cloud Function. So let's jump back to the laptop again. So for our last function, we're going to create an analytics event or analytics function. So we're listening to the analytics service and for the conversion event feedback sent. This is not a built in conversion event. This is one that Frank has created on his own and marked as conversion. Whenever that event is logged, this code will run. So in this case, the event.data is the full analytics event. Because Frank had used Firebase Analytics.SetUserID, this analytic event has the actual Firebase user ID of the person who sent feedback. This is really important because now he can do things like look up profile information or in this case, give the user a gift.
Since Frank only has 12 muffin's to give away, we're going to add people to the muffin club in a transaction. Now, first he needs to check whether or not he's already given away all his muffins or if he's already given this user a muffin. So if he's given away 12 muffins or he's already given this user a muffin, just exit the transaction early. No harm, no foul. Otherwise, we'll log that we're going to try to attempt to give away him often and add this user to the muffin club in our transaction. If it succeeds, we'll get a result that says committed. Otherwise it will retry and will either try to modify again or find out if the last muffin was given away and early exit. To figure out which is which, we're just going to have a debug statement. So once again, let's see it in action. So let's get feedback. I'm being soft on myself. I may not have put this one in debug mode so it might take a little bit for the conversion event to come through.
Let's watch. There we go, muffin club. So now I have decided to give myself a gluten free kale muffin. So thanks. I think Frank is pretty set, so let's hand it back to Brendan. [APPLAUSE] Can we switch back to the slides? Thank you. Thank you so much, Thomas. That was great. I'm kind of hungry now, too. So to recap, Cloud Functions for Firebase is our programmatic glue. You've seen how it lets you stitch together Firebase and Cloud products to create your own serverless mobile back end. So before Cloud Functions for Firebase, Firebase developers would have to set up their own custom back end solutions to do many of the things that Thomas went over today. So your mobile app would have to connect your own API, not allowing you to take advantage of all the things that the Firebase SDKs have to offer. As a result, this would increase complexity and time to implement the core features that are already available for you. So with Cloud Functions for Firebase, this is no longer the case.
You get to tie together the best parts of Firebase and Google Cloud to create a completely serverless mobile back end and you still get to use the Firebase SDKs in your mobile app. There's no need to manage or set up your own servers. There's no need to worry about scaling up or down. There's also no need to pay for the resources that you aren't utilizing. So we've seen a couple examples of how you can stitch together Firebase and Cloud products to easily create powerful Cloud Functions. You've seen how to reengage customers through analytics using conversion events, send notifications using the real-time database and Cloud messaging, and how to automatically translate messages written to the real-time database. So Firebase developers now have a completely serverless back end solution. Companies like Sony are building amazing things with Cloud Functions for Firebase and we can't wait to see what you build. You could even start using it right now for free on the Firebase free tier.
To learn more you can go to g.co/firebase/functions. [MUSIC PLAYING]
Firebase’s SDKs make it easier to build successful mobile and web apps, and Firebase and Google Cloud Platform (GCP) work closely together to offer a streamlined mobile developer experience. Learn about our latest collaboration and how to extend Firebase backend services with your own code using Google Cloud Functions.
Missed the conference? Watch all the talks here: https://goo.gl/c1Vs3h
Watch more talks about Application Development here: https://goo.gl/YFgZpl