In Record Time: How we Quickly Built a Serverless app with Firebase and Flutter (GDD Europe '17)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[MUSIC PLAYING] [APPLAUSE] DAVID DEREMER: How's everybody doing? SETH LADD: Hello. DAVID DEREMER: Good. All right. All right. We made it work. That's right. I'm David. I am a partner at a New York City-based digital agency called Posse. We work with large brands and large companies to launch mobile apps. SETH LADD: Hi, everyone. My name is Seth Ladd. I'm a product manager at Google and I work on Flutter. DAVID DEREMER: So we're really excited about today. We're here to tell you about how we've used some of Google's latest developer technologies to launch a successful app in the United States in record time. As an agency, at Posse, we always face incredibly tight deadlines. Our clients are always pushing us to do more, faster and cheaper. So we're always looking for cross-platform technologies, special architectures-- like server-less architectures, like you've been seeing a lot of today-- to help us do things quicker. Our clients want us to deliver value, not lines of code or overhead. They don't want us to reinvent the wheel. So we've been looking at these technologies, but we always had a bit of skepticism, a little bit of lack of confidence in these solutions relative to the alternatives-- until recently, when we started working with Flutter and Firebase. SETH LADD: And we're very glad you found Flutter. At Flutter, our mission is to help teams build quality apps faster and easier. That's what we're all about. In fact, at Google for a while now, we've been helping teams build successful and business-critical apps. So then the question we asked ourselves is, could we replicate the success of Flutter outside of Google? So to help us answer that, we started working with the Google Developer Agency Program, which is how we met David and Posse. We thought Flutter was a great fit for agencies, and any team that wanted to move fast without sacrificing quality, and needing to reach all users across all of mobile. DAVID DEREMER: When we dug into Flutter, we finally found a platform we thought we could really use-- a cross-platform framework that worked for both iOS and Android to create apps that felt indistinguishable from native apps, a reactive coding style that felt really modern and highly productive, a strongly typed language, which was very important to our developer team, and a hot reload feature that, once we saw it, and once we started using it, drastically increased the efficiency of our developer team. We were ready to dive into this technology. But, as an agency, we needed a client as excited about it as we were. And then it happened-- "Hamilton," the hit Broadway musical based in New York City, called us up to do an app. And when we told them about Firebase and Flutter, they were as excited about this as we were. SETH LADD: Now, for those of you who don't know, "Hamilton-- The Musical," is a huge deal in the US. They have a very large and very passionate fan base. The musical is constantly sold out. It's nearly impossible to get tickets to across the US. It's won 11 Grammys, a Pulitzer Prize, an Emmy, and more. DAVID DEREMER: When the "Hamilton" team came to us, all they cared about was creating great experiences for their fans. They just wanted to give the fans as much as they could. And they had no internal tech team. So when we talked to them about how we could do it, the idea of maintaining two separate code bases for iOS and Android, or maintaining a fleet of servers-- even on Google Cloud or something easy like cloud infrastructure-- was really daunting to them. This is a lot of technology for, basically, a bunch of theater people, who have no technology experience, to own. So the promise of cross-platform frameworks and server-less architectures was really interesting to them. And, most importantly, they had an incredibly tight deadline. For all the features they wanted to do, we only had three months. And this deadline could not be moved. SETH LADD: So, at that point, the Flutter team was very excited, and, honestly, a little nervous. Remember, at that time, it was still early for Flutter. And it hadn't yet been used for such a prominent, five-star, consumer-facing app. The "Hamilton" team had a long list of really important features and an immovable deadline. So could it work? DAVID DEREMER: And, as if that pressure wasn't high enough, we got a phone call from the CEO of "Hamilton," who said, "Hamilton" is really big. The fans love it. We've never failed at anything. And this app will not be the first time. SETH LADD: So this is exactly the kind of challenge that our team is looking for. So, of course, we said, yes, let's do it. The Posse team, the "Hamilton" team, and the Flutter team devised a plan to execute. Posse would build the app and design the app to the specifications requirements of "Hamilton." And the Flutter team would fix critical bugs and add crucial features to meet all the use cases and requirements for the app. DAVID DEREMER: So to give you an idea of what's in this app and how complicated it was, there's a whole lot of features in here-- and, again, three short months. And so there's a lottery. The tickets are really hard to get. You have to buy them a year out and after-market they're like $1,000 apiece. So they have this lottery where you can enter to win $10 tickets. Tens of thousands of people enter these lotteries every single day. It was the most important feature of the app. We also built a fully fleshed out e-commerce experience for you to buy "Hamilton" merchandise. And, of course, for that, you need something like an integration with Magento and some Stripe integrations for process payment-- all done on Firebase and Cloud Functions. We had a news feed and even this fun Ham Cam feature, which is basically a custom camera with overlays, even location-based overlays that you unlock at the theaters and other places. A ton of features-- and that's just the tip of the iceberg. And, again, we had almost no time to do this. So being able to do this really quickly and really effectively and beautifully, via custom-branded design was absolutely essential. But the real question for this was, could we build an app with Flutter and with Firebase on this timeline with all of these features, in a way that the fans would love it and they would feel that it was indistinguishable from a native app? SETH LADD: And, yes, the fans loved it. The media loved it. And both the App Store and the Play Store both featured the app. DAVID DEREMER: And its uptake surprised even the "Hamilton" team. Since we launched, we've had almost a million installs, nearly half a million active users. We've already taken two million lottery entries. And we are already one of the fastest-growing apps on the Google Cloud Function platform. And we show this to you say Flutter and Firebase and a lot of these tools you're seeing here today, they're not just toys. These are real things that work in production at tremendously high scale. So Flutter and Firebase are a huge reason that we got this app to so many fans so quickly. The speed of development and the features that are given to us by these tools just really couldn't be matched for our timeline. So what we want to do now is, we're going to share some patterns and some code to show you that you, too, can use these tools, that you can accelerate your process and benefit from them just like we did. And we're going to start first with Firebase. So Firebase offers a ton of tools. You may have been to some talks already today where they're talking about all the cool ways that you can use Firebase. The really fun thing about Firebase is that you can use as many of these things or as few of these things as you want. If you just when you use Google Analytics, no problem. It's really easy. Just add the SDK, add some events, you've got analytics. We leaned on it heavily. We used Firebase for basically everything. So this is new to us. Typically, we built web servers and complicated web APIs. We only used Firebase in this application. The authentication product was one that saved us a tremendous amount of time. You add the SDK. Your authentication strategy's already pre-baked for you, pretty much-- want to do email, phone number, Google log-in, anything you want to do-- it's right there. It's interoperability with other Google Cloud Services, like Google Cloud Storage, or Pub/Sub, or all of these other tools that you have access to with Google Cloud is really seamless. And it's really easy to use them. So getting images served out of Google Cloud Storage was almost trivial with Firebase. And then there's the real-time database. You know, it's a different type of database than probably a lot of you are used to. But it's real time. And that's something that our team hadn't really experienced before. We were used to apps where you make a request, you get a response. The real-time database-- once you add the Firebase SDK-- it's right there. Your data is live. We're really proud of the fact that our application doesn't have a single pull-to-refresh anywhere in the app. What you see is what you get, live, in real time. But, for us, the real star of this story was Cloud Functions, which is relatively new. Before this, we used Firebase for other pieces, but not really as a full, complete server. Cloud Functions gives us the tools we need for this to be a first-class backend for an app as big as this one. We used it to integrate with Magento and Stripe APIs and all kinds of third-party services. We used it to fan out our data across Firebase. We used it as an API, which I'll show you in a second. So we have all these tools with Firebase-- we had the real-time database, Cloud Functions. And one of the things, when we were getting started, was, we had to figure out, how do we make an API out of these tools? We're used to building out express or rail servers, where the app makes a request, does some work, you get your response. You probably all have built APIs like that before for your apps. We were struggling with how do we do this. You know, we didn't want to build a web server, because, you know, what's the point of a server-less architecture if you're maintaining servers. And then it hit us. We have this connection already to our real-time database, the ability to read and write data in like incredibly fast speeds. And we have Cloud Functions. So we devised this asynchronous approach, where we use the database as a connectivity mechanism and Cloud Functions as our logic, to do the same work that we'd typically do with a web service. So, as an example, let's say the app wants to do something, for instance, enter the lottery. What we do is we drop a request-- we write a request-- to the Firebase real-time database. We triggered a cloud function based on that write. The cloud function does what we need to do, you know-- checks the user-- we'll show you some of this in a minute-- but does the work that we don't want the client to do. We want it to be controlled and protected on our server. When it's done, it writes a response back to the real-time database. The database is-- or the app is listening to this node on the database. And since it's real time, as soon as we make that response, the app gets it, just as if your web API responded with some JSON. And there we have it. We have an API. It was incredibly powerful for us. Once we saw this pattern, not only was it high-performance, it saved us a ton of time. This app has zero networking code. We hit zero HTTPS web APIs at all. Everything is done through the database. So this was like mind-blowing to us and saved us a tremendous amount of time. So to show you that this is real, and to show you how easy it is to build an API using the real-time database and Cloud Functions, we're going to demo this pattern. This pattern is basically the same exact pattern we're using in this app, that tens of thousands and upwards-- we're getting into the hundreds of thousands-- of users are using every single day. The first thing I wanted to show you was our package of JSON. The reason I wanted to show you this is that, on my team, we're always looking to eliminate as many dependencies as we can. We really only need two to get this started. We need the Firebase admin module to talk to the real-time database-- and do other things-- but pretty much to read and write to Firebase from our server. And we need our Firebase functions library to register our functions and to find our triggers. You may notice that we actually are doing a few things in our dev dependencies here. We're using TypeScript, which you'll see, and Webpack. This was a personal choice of our team, but one that really improved our efficiency during the process. So how do we create a function? It's incredibly easy. This is just JavaScript-- well, in this case, it's TypeScript. But, you know, at the end of the day, you write it just like you would write any other JavaScript function. You'll notice, again, there's no node here. There's no express. There's no middleware. There's no body parsers, nothing like that. All we do is we define a trigger path-- how we want our function to be invoked. In this particular case, since we're doing our request-response API, we want to on create. When someone adds new data to our database, at a particular path that we've defined-- in this case, requests lottery entry, user ID, push key. When new data is written to that path in the database, it's going to wake up our function and do the work we need it to do. So we've defined this here in this enter lottery function. So the key thing here is, why are we doing this? Why do we care? Historically, you might put a lot of this work in the client side. Or Firebase gives you direct read-write access from your app into Firebase. But we don't want people to just be able to drop a lottery entry into the database. That's something that could be abused. So we want this to be protected behind our API. When the event fires and is triggered, it passes this event into our function. The event has a bunch of params and data that we can access from that event. So this is where we can get from our database path-- we can get the user ID, we can get the actual data that the app passes to us in the request when it saves it in the database. So it behaves kind of like a web API. But it's just a database write. The next thing we do is we do some sensitive business logic. These are just kind of stubbed out for the purposes of the demo. But, you know, maybe we want to check if the user's eligible, or make sure the lottery is still open, or do something else that's private, that we don't want the world to know about. We can do those all here. They're just normal JavaScript. They can be calls to third party APIs, they can be asynchronous things, we can send push notifications, save files, whatever we want to do. But, assuming everything's OK, we define our entry data object. And then we can save it out to the database. Now this particular area of the database-- like our lottery entries right here-- this is something that is protected by database rules. Nobody can read or write to this. It's read-write false. And this is really important because we only want our systems to be able to allow people to create a lottery entry. By doing it in this pattern, we can make sure that our API's safe. Once we're done with that, and the user has successfully saved their lottery entry, now we just need to write the response back to our response node in the database. We have a little helper function here called respond. We'll, maybe, post some of this code afterwards, if anyone's interested. But this just basically writes our response object with some data-- like here's your chance ID that was generated through this, and maybe a message like, hooray, you won the lottery. We write that back to the response node. And since the app, after it made the request, has an active listener on the response node-- as soon as we make that write, the app gets the update and the spinner stops spinning and the app is done. You've entered the lottery. But there's a key point we want to make here. Unlike a normal web request, where the connection's open, and until you close that connection, it's just kind of-- you're hanging out there, you're waiting for the response to finish. This is asynchronous. Once we make that request to the database, the Cloud Function's running in the background. It's almost totally detached from the app. So even though we respond to the app here and we say, hey, you know, hey, you're done. Congrats. We can keep going. Our Cloud Function doesn't have to stop there. We can do some other background tasks. Maybe we want to fan out the data to other areas of the database, or send a push notification, or do something else. And when we're finally done, we just return and tell our function we're done. So it's really cool. Again, it saved us a tremendous amount of time. And there's a few key points I wanted to highlight here. We called this asynchronous, database-driven API-- no networking code at all. On our team, we always end up spending more time than we expect writing code to interface with some sort of web server-- networking code-- that we don't like writing, that we have to rewrite all the time, and it takes a lot of extra time, and our clients don't care about it. No networking. It was all handled by the Firebase SDK the second we were able to interact with our database. The other thing is that there's no authentication or error handling. Again, all baked in to the Firebase SDK. It's incredibly high-scale as well. The Firebase database scales really nicely. And it has this amazing real-time performance that we were worried about, how's this going to work performance-wise? But because it's such a blazing fast database, the performance has been really, really amazing. And, perhaps, most importantly for our client and for us, no servers to maintain. We didn't have to worry about the type of web server we're using, who's going to patch the libraries, and all of the operating systems that our servers are running, and how we're going to provision this, how are we going to handle the scale, and how are we going to auto-scale whenever a lottery opens. Cloud Functions and Firebase just did it all for us. So Firebase really worked for us. It was a tremendous win for the project. But it was only half the story. We also had to craft a beautiful, custom design for "Hamilton," to really showcase their brand in an app. And for that, we turned to Flutter. And I'm going to turn it over to Seth now, who's going to tell you a little bit more about how Flutter helped us out. SETH LADD: Great. Thanks, David. So, as we heard in the beginning, Flutter is a new mobile app SDK that makes it easier and faster to deliver high-quality apps. At its technical core, Flutter is a portable renderer and UI toolkit. Now all of these layers you see here are compiled to native ARM code for fast startup and predictable performance. But, even more importantly, this portable renderer is shipped inside of your app. When you deploy your app via APKs or IPAs, the renderer, toolkit, and your code are all bundled together and shipped out. This means that the beautiful pixels your designers worked so hard on, and the beautiful UI that your developers built, is the same beautiful experience your users will get, no matter what OEM version or OS version they happen to be running. Now, of course, I could keep telling you about it, but it's much cooler to show you about Flutter. So let's go to the demo setup here. OK. We're going to show three important parts of Flutter, which David and Posse took advantage of when they built the "Hamilton" app. The first is our reactive widget library. The second is hot reload. And the third is Flutter Fire. Let's start by looking at the lottery screen here on these phones. This is an iOS phone. And this is an Android phone. You can see that it's a beautiful brand-first design. And the colors look similar down here. So they could deliver a consistent UI experience across all their users, across all of mobile. But just because these look identical doesn't mean that they have to act identical. Flutter and Posse know that users on iOS have a particular muscle memory when they scroll and a particular scrolling friction on Android that people are used to. And so let's look at a demo of that. On iOS-- I'm sorry, on Android-- you can see the over-scroll glow. And on iOS, you get the bounce. So the "Hamilton" app is beautiful and a consistent brand experience and still feels very natural to users on both platforms. OK. So let's pick a piece of this UI and show you how we built this. We're going to pick the little blue badge here, the active badge here, to play with and show you how it works. So let's go to the code here. This is the code for that active badge. And the first thing I want you to notice is that it's all code. There's no markup, there's no XML, there's no other language you have to learn or build tools for. It's a single language and a single set of libraries for you to build your UI, manipulate your UI, and build your business logic. This means you get the power of code and the power of IDEs like refactoring, jump to definition, et cetera, when you build all aspects of that front end. The other thing I want you to see is that this Lottery State badge, this active blue box right here, is itself a widget. Widgets and Flutter are the core basic building blocks of all UI. In fact, widgets themselves are made out of more widgets. This composition mental model, this composition architecture, is very powerful. You can recompose the core widgets that we ship in our toolkit-- things like padding, things like text-- into more beautiful, higher-level widgets, which themselves can be composed. So it's a really good model. Now let's look at what it's like to actually code this UI. Let's say that we did some user studies and this blue here may be not working and maybe the badge is a little too small. So we sit down next to our designer and they say, what other colors you got? Well, of course-- well, we have all the colors-- but, of course, we have code completion, so you can see what the options are. And let's say we want to try green. So I'm going to save it here in the code and jump over to a console here that's driving these two apps. I'm going to hit r. And-- as it's initializing the system here. OK, great. It has changed live, hot reloaded, these UIs to change from blue to green. [APPLAUSE] Thank you. [APPLAUSE] This hot reload system really enabled Posse and others to iterate very quickly in their development cycle. But we can do more than just change colors. Let's change some math here. Let's say we want to change the size of this button here live. So we're going to go over and reload here. And-- oh-- oh, no. So what just happened? Well, most of the UI rendered just fine. But the widget here-- this active widget-- had a syntax error. And, luckily, the framework said, I can render everything except that one widget that you had. And I'm going to show you what that error is. And it even tells me what the syntax error is, here in the red little box. So, yep, sure enough. It's a syntax error-- forgot to finish. So let's go back here, type r. And in the time it takes me look back here, we have not only recovered from a syntax error live, without restarting the app, but we fixed it, and now it's a lot bigger for you to see. So, again, this hot reload dev cycle is really fast. But there's one more aspect of it that I want to show. Let's tap on this button a couple of times. And let's add some state to our app. OK. Hopefully, you can see, I've tapped each button seven times. State in your app is like, is a user logged in? Or do I have any items in the cart? In this case, how many times have I tapped the button? So we're going to make another change here. Let's say active-- OK, save-- go back to the console, hit r for reload. And, boom, right there-- not only will you get that about a second hot reload experience, but the state of my app remained live. So it's a stateful hot reload. This is really powerful when you want to work in that one esoteric screen seven levels down in your app after you log in and add two items to your cart, et cetera. And you're all the way down here in your app-- now you can paint your app to life. You don't have to restart that flow every time you want to make these changes. Stateful hot reload. Now the next thing I want to show you is, right now we're just adding numbers here when I tap the button. But let's make it real. Let's make it connect to Firebase and those cool Cloud Functions that David showed us earlier. So Flutter has an awesome package manager, where you can just declare your dependencies, get your plug-ins, get your third-party libraries. And, of course, Firebase through the Flutter Fire package is a first-class citizen here in this ecosystem. So it's very easy to declare this dependency. Now let's go over to the code that handles this button press. And instead of just incrementing a counter, we're going to enter the lottery. Now let's look at the code for entering the lottery. There's two things I want to point out. One is these calls to set state. This is a framework feature of Flutter, where you can easily identify where the state of your application is changed. It makes it very easy to look around your code and say, this is where we update the state or your domain model. Second, it tells Flutter Framework, rebuild your UI. So this is that reactive part of the Flutter framework that we're talking about. The second thing I want to show is post-action, a very cool function that Dave and his team wrote to encapsulate that async request-response pattern that we saw earlier, which triggers Cloud Functions, et cetera. Let's just jump in here real quick. I just want to show here a couple of lines of Firebase code. This is normal Firebase code. If you're used to Firebase, these APIs are going to feel very familiar. It's all brought up into Flutter for you to access. All right. So we've made a significant change to our application here. We've added a huge swath of business logic and code to our app. Now let's do a final hot reload. In about one second, again, our app is updated. And when I tap this button, we're now really talking to real-time database, which really listens for Cloud Functions and really waits for a response-- all hot-reloaded and live for you. Come on-- I was-- yes, OK. OK, good. So there's obviously a lot more cool features to Flutter and Firebase. But, hopefully, you've got a sense of how fast, fun, and easy it is to build beautiful UIs and connect it to Firebase. So the question is-- if we can go back to the slides-- is how did this actually work for David and his team? DAVID DEREMER: So Flutter was really, really important. Again, we had a really tight timeline. And we had a client with really high demands, both in terms of the features and the experience we had to deliver. And we wanted to deliver this beautiful, branded experience across both platforms-- iOS and Android. And we didn't have time to make sure that every little pixel was perfect on both platforms. So Flutter really helped us there-- coding once, seeing the designs, live on both-- but yet still feeling very natural and feeling very native. The other thing is that it allowed us to move really fast and experiment. Our designers were constantly tweaking things. The client always had new input, or once they'd get a build, they'd want to change something. So the ability to move fast and use tools like hot reload to modify that design in real time saved us a ton of time. Also, in the long run, Flutter provides an amazing ability to reduce our maintenance costs and, also, decrease the cost of adding new features. Because every single time we need to fix a bug or change a design or add a new feature, we just have to do it one place. And our developers say that laying out UI with Flutter is significantly faster than on iOS or Android. And the hot reload, you know-- if you are all mobile developers here, or if any of you are-- waiting for your application to recompile and navigate down to where you need to go-- I mean, this is real money, this is real time. Our clients are paying for us to develop these apps. So every second our developers are not waiting for X-code to reload the application, that's more time we're working on features. And also, because of things like Flutter Fire and Flutter's plug-in system, and using tools like Firebase and all of the great resources we have at our disposal, we spent less time building plumbing in the technical overhead in order to make this app work, and more time working on features. So I'm wondering, you know, has anyone here faced an incredibly tough deadline in the work that you do? Have you ever felt pressure from your bosses or your senior leaders to ship more features faster? Have you ever had a design team that wants you to react faster, iterate a design quicker-- I have a new design, can I see what it looks like on screen? Or perhaps you have stakeholders in your business that don't want to hear it about your cool infrastructure solution, or about the code you've written to optimize this, that, or the other thing-- they just want to see new features, you know. What have you done for me lately? What kind of value are you adding to our business and to our application? So Flutter and Firebase, for us, was a tremendous toolkit to deliver on those needs-- you know, tough time line, branded design, beautiful experience, complicated features, protected operations and logic in the back end. And it's really easy to get started. SETH LADD: That's right. It's less than a minute to create a Firebase project. And Flutter is open source. You just get Clone or Repo. And we even include a command-- Flutter create-- to bootstrap your first project. We encourage you to visit our office hours up on the third floor. And we have instructor-led trainings for both Firebase and Flutter today and tomorrow. DAVID DEREMER: And we hope that our talk today inspires you all-- that these aren't just cool technologies. Real businesses at real scale are using these out there today to run production code. So we hope that you can embrace some of the learning you had here today and go out and try something amazing. Thank you very much. SETH LADD: Thank you so much. [APPLAUSE] [MUSIC PLAYING]
Info
Channel: Google Developers
Views: 121,664
Rating: undefined out of 5
Keywords: Google developer days, GDD, GDD europe, google developer days Europe, google developer days Europe 2017, developer days, Seth Ladd, David DeRemer, clud functions, flutter, serverless mobile app, Google developer days Krakow, GDD krakow, google developers, web developer, application developer, google, developers, developer news, google developer conference, developer conference, web developer conference, mobile developer conference, developer products, developer platforms, devops
Id: prlK_QL_qOA
Channel Id: undefined
Length: 28min 4sec (1684 seconds)
Published: Tue Sep 05 2017
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.