See all Fireship transcripts on Youtube

youtube thumbnail

Firebase - Ultimate Beginner's Guide

21 minutes 44 seconds

🇬🇧 English

S1

Speaker 1

00:02

Today I want to do something I've never done on the channel, and that's a basic level video for Firebase. Over the past year I've created close to 100 videos covering intermediate to advanced level concepts, but I've never really talked about why I use Firebase and why I think it's an excellent platform for building apps. I'm going to take you through all of the main features using nothing but JavaScript, and you don't really need to have any coding experience to follow along with this video. If you're new here, make sure to like and subscribe, and follow along with the code on angularfirebase.com.

S1

Speaker 1

00:30

So I originally started in web development when Ruby on Rails was powering things like Twitter and Airbnb. At the time it seemed like magic because it made the backend so much easier to develop, but Firebase takes this to a whole new level by completely abstracting away the backend. Firebase doesn't pay me to say these things, I use it for my clients for 3 main reasons. The first 1 is the developer experience.

S1

Speaker 1

00:51

It's well documented, easy to use, and the team has a really good culture of listening to developer feedback. The second factor is minimization of cost. Firebase is free for all of your small experimental projects, and then scales up in a linear way based on your user growth and design choices. I really dislike platforms that get you in on a free tier and then start charging you $500 a month once you reach a certain threshold.

S1

Speaker 1

01:14

And the final factor is the maximization of time. I want to create the most amount of value in the least amount of time and I think Firebase facilitates that really well. And hopefully you'll agree with me there when we finish writing the code for this video. To follow along you just need an editor like VS Code and Node.js installed on your local system.

S1

Speaker 1

01:31

After that you can go to Firebase and create a new project. A project is just a container for resources on Google Cloud Platform, such as your database, file storage, web hosting, and things like that. You can manage all of your app resources from the Firebase Admin Console. And your project can span across multiple platforms.

S1

Speaker 1

01:50

Firebase provides software developer kits for the web, iOS, Android, Unity, and several others. Your project is identified by the credentials that you see here, and they can integrate seamlessly with other APIs on Google Cloud Platform. So if you want to implement something like Cloud Vision or Google Maps, you can do that with the click of a button. Now that we have our project created, we're going to install the Firebase command line tools by running npm install firebase-tools flag-g to install it globally.

S1

Speaker 1

02:19

Now I want to show you how quick and easy it is to create and deploy a project from the command line. So I've just opened up an empty folder in VS code and then I'm pulling up the terminal window and running Firebase init hosting. That's going to create a few files for us. The first 1 is Firebase JSON, which holds all of our hosting rules.

S1

Speaker 1

02:39

And then the Firebase RC file is just a script to identify our project. The public folder with index.html is our actual app. What it's doing is importing the Firebase Web SDK in the head of the document and you can import these 1 by 1 so if you only need the database you don't have to import all the other modules as well. So that can be a big help with your page load performance.

S1

Speaker 1

03:02

Then you'll notice all these script tags have defer on them. That just tells a web browser not to execute the script until the page is finished loading. From there, if we go down to the body of the document, we have another script tag which is going to have all the actual Firebase SDK resources initialized and available to us. We're going to replace this script with our own basic JavaScript app.

S1

Speaker 1

03:23

But for now, let's go ahead and serve our app locally by running Firebase serve. This is going to spin up a web server locally on port 5000. We can just paste that into a browser and start testing our app locally. You should see this default app, which is just the content directly in that index HTML file.

S1

Speaker 1

03:41

We can take this a step further and deploy our app to a live hosted URL that's accessible on the internet. All we have to do is run Firebase deploy. That'll give us back a URL and now we can view our app live on the internet. And this is actually a lot more powerful than it seems on the surface because the app is deployed with an SSL certificate so we immediately have support for HTTPS in the URL.

S1

Speaker 1

04:03

In addition, it uses Google's Content Delivery Network, which will cache and serve all of your static resources in a highly performant way. Now that we know how to deploy our app, let's go back into the index.html and delete all the boilerplate code, except for the main imports in the head of the document. Then down in the body I'm going to point our script tag to a new file called app.js. That's where we're going to write all of our actual code.

S1

Speaker 1

04:28

Then we can create that file from the command line by running in touch public slash app.js. The next thing I'm going to do is bring up the browser window side by side and run Firebase serve so we can check out the changes that we make. Now I want to show you how you can use Firebase to manage your user authentication. In the past, user auth was always a very difficult feature to implement, but with Firebase we can do it in a few lines of code.

S1

Speaker 1

04:52

I just have a simple HTML button here that will fire this Google login function when clicked. Then inside of App.js we want to make sure to run our code after the document content has loaded because Firebase won't be available until after that point. Once the content has loaded, we can access the Firebase resources under this Firebase namespace. For example, if we call Firebase app and then console log it, it should give us an object with all of our Firebase credentials and other things attached to that object.

S1

Speaker 1

05:21

You don't have to do that but if you want to make sure that Firebase is available that's 1 way to find out. Before we can actually log in we need to go into the Firebase console under authentication and enable the methods that we want to use. So in this case we want to use Google as the OAuth provider but we could also do things like email password, anonymous, Twitter, Facebook, GitHub, etc. From there let's write a function that will log the user in.

S1

Speaker 1

05:47

The first thing we need to do is define the provider that we want to use, which in this case would be the Firebase Auth Google Auth provider. From there we can reference the Firebase Auth library and call signInWithPopup passing it that provider as an argument. And that's literally all the code that it takes to log in the user with Google. This operation happens asynchronously, which means it returns a promise.

S1

Speaker 1

06:10

Whenever we have a promise, we can attach then to it, which will give us the user once that promise resolves. So we're saying sign in with popup, then when we have a user, let's set that user as a variable. Then we can write their display name to the DOM, and we'll also console log the user object. All of the user information will come from the actual Google account.

S1

Speaker 1

06:29

If we go ahead and click our login with Google button, it's going to bring up a pop-up window where the user will log into their actual Google account, then it's going to execute any code inside of that then block. Firebase uses JSON web tokens for authentication, which means there's an encrypted token on the browser now that identifies this user. If you want to see that token, you can just go into the browser and type in local storage. And you can see the current user session there.

S1

Speaker 1

06:56

JSON Web Tokens are much easier to work with compared to cookies, especially for JavaScript applications like Angular and React. I won't get into the details here but I do cover that in some of my more advanced videos. If we go back into the Firebase console now, you'll see that our user is created in the Firebase authentication tab. We can use this to disable accounts, update email templates if you're using email password auth, perform text message verification, and view some basic analytics.

S1

Speaker 1

07:23

So that wraps up user auth, now let's move into the cornerstone of Firebase, which is its database. As of October 2017, we have 2 different database options, both of them being NoSQL databases. We have Real-Time Database and Cloud Firestore. You can use both of them together, but more often than not, you're going to choose between 1 or the other.

S1

Speaker 1

07:42

And the best way to do that in my opinion is to analyze the pricing. For the real-time database, we're charged $5 per gigabyte stored and $1 per gigabyte downloaded. For Firestore on the other hand, we're charged $0.18 per gigabyte stored, but we're also charged for each individual document read and write operation. So what that boils down to is that if you have a really simple data set that is read frequently you would use the real-time database but for a larger more complex relational data set you'd want to use Cloud Firestore.

S1

Speaker 1

08:13

In the majority of cases I find that Cloud Firestore ends up being the better choice, so that's where we're going to start. Enable the database and start it in test mode, which is going to disable any security rules. Then the actual database itself is structured as collections of documents. It follows a pattern similar to MongoDB, which is the most widely adopted NoSQL database in the world.

S1

Speaker 1

08:36

And if you're interested in data modeling, check out episode 85. The first thing we'll do is create a collection, which is just a container for documents, and then we'll add our first document to it. Every document has a unique ID which you can create yourself or you can have it automatically generated. In this case I'm going to create it myself and call it first post.

S1

Speaker 1

08:57

Then the actual data that we consume from our app will be set as fields on this document. The structure is similar to a JavaScript object or an object in any other programming language. We can then use these fields to pull a subset of documents from a collection based on whatever condition we want to pass to it. That'll make a little more sense when we start building some queries in our front-end code.

S1

Speaker 1

09:21

1 of the coolest things about Firebase is that your user authentication system is directly tied to your database. Under the Rules tab, you can write expressive statements that define the backend security logic for your app. For example, if you had a certain set of documents that only a logged in user should see, you'd be able to do that here with a single line of code. It's beyond the scope of this video, but needless to say it's a very important part of building a fully secured app.

S1

Speaker 1

09:48

Then the last thing Firestore can do is build indices. By default you'll have an index for every field on a given document, but if you want to query by multiple fields you may need to create your own custom index. Now getting back to our front-end app, I'm going to replace the Firebase database import with Firestore. And the first thing I want to do is just retrieve and read that document that we created in the database console.

S1

Speaker 1

10:13

So first we make a reference to firestore as a variable named db. Then we make a reference to the collection by calling db collection posts. And then we reference the specific document ID, which I gave a custom ID of first post. So at this point we have a reference to the document and we could use that reference to retrieve it, listen to it in real time, or update and delete it.

S1

Speaker 1

10:35

What we want to do right now is just retrieve it and be done with it. So to retrieve it, we just call get, which is an asynchronous operation that returns a promise that resolves with the actual document data that we saved in Firestore. So I'll set the data as a variable, and I'll write the title and timestamp to the browser window. Now if we refresh the page, we should see that document information printed to the screen.

S1

Speaker 1

11:00

So that's pretty cool, but 1 of the major benefits of Firebase is that we can listen to data changes in real time. So if you have some data that's shared between multiple users and that data changes somewhere, all of your users are going to be notified at that exact moment of the change. That would be an extremely difficult feature to build from scratch, but we can do it with a few modifications to the code we just wrote. So instead of calling get, we're going to replace that with onSnapshot.

S1

Speaker 1

11:29

Instead of returning a promise, this is going to return a real-time stream that we can listen to with a callback function. So we can get rid of then and we'll just copy and paste all of our previous code inside of this callback function. Every time the document changes it's going to emit a new document to this function and we can handle it accordingly. In this case the browser should write another line every time a change occurs in Firestore.

S1

Speaker 1

11:56

So let's go ahead and change the title and you can see here on the right that it's automatically updated in the browser. If your app does anything that's real-time in nature, this is going to be 1 of the most powerful aspects of Firebase for you. In addition to reading documents, we can also update documents from our client-side code. What I'm going to do here is set up a form input and every time this input changes, it's going to run an update to Firestore.

S1

Speaker 1

12:23

So we'll set up a function called updatePost and then we'll make a reference to the document just like we did before. But this time we'll call update and pass it the information that the user had typed into the form. When data is updated from your app, Firestore does something really cool called optimistic updates or latency compensation. If you have a real-time listener on the data like we set up before.

S1

Speaker 1

12:46

It will update the view immediately so your user doesn't have to wait for a server to respond which might take a second or 2 and potentially hurt the user experience. In most cases though we're probably not going to be reading a single document but trying to query a collection of documents. To show you that, I'm creating a collection of products where every product has a price and a name. 1 of the major benefits of Firestore is that you can query multiple documents in a very expressive way.

S1

Speaker 1

13:13

Back in the code, we'll first make a reference to the product's collection. And then if we want to get a subset of the documents in that collection, we can call where. And where takes 3 different arguments. First it's the field that we want to sort by, which in this case is the price.

S1

Speaker 1

13:29

Then it takes an operator, which could be equal to, greater than, greater than or equal to, and so on. Then the third and final argument is the actual value. So in this case we want all the products whose price is greater than $10. Then just like we did with the document read, we can call get and instead of returning a single document, it's going to return an array of documents.

S1

Speaker 1

13:50

So really the only difference is that we need to loop over these documents to get the data for each 1. For each document in the array, I'm writing the name and price to the screen. So we have our wrench and our chainsaw, which are both over $10. If we change the operator to greater than or equal to $10, then the query will also include products that are equal to $10.

S1

Speaker 1

14:12

If we want to check for just equality, we can change the operator to equals, and then it's only going to return the hammer. In addition to the where method, we can also use order by to return documents in a specific order. If we want to retrieve all of our products ordered from highest price to lowest price, then we can say order by price descending, and we'll get our products back in that order. And we can also limit the number of documents that are returned, which is really important when you're working with a large collection.

S1

Speaker 1

14:43

Simply chain the limit method to any query, and that will cap the number of documents that come back in the array. That wraps up the database section. Now we're ready to get started with Firebase Storage. Storage is just a cloud storage bucket that is also tied to your Firebase project.

S1

Speaker 1

15:00

This is where you might put user generated content like uploaded images, videos, things like that. So the first thing we want to do is go into the rules section and currently it's set up to only allow authenticated users to upload files but we want to change that. For Now we're just going to let anybody upload files to our storage bucket. Back in the index.html in our frontend app, I'm setting up a form input that is set to type file.

S1

Speaker 1

15:25

Then on the change event, we're going to run a function called upload file and pass it this files as the argument. I am also going to display an image tag that currently doesn't have a source but will set its source asynchronously after the upload is complete. In the JavaScript we'll make a reference to the storage library. In a similar way that we did with the database, we will reference a path in that storage bucket.

S1

Speaker 1

15:50

But in the storage bucket, we do that by calling child, and then in this case we'll just pass it a static image name of horse.jpg. With this reference, we can either upload a file or download an existing file URL. Our form input is going to return a file list, so we'll just take the first item of that list with item 0. And then to upload the file, all we have to do is call the reference put file.

S1

Speaker 1

16:16

We can run code when the upload is complete by chaining then to it. It's going to return some data about the upload itself including the snapshot download URL. What we want to do in this case is take that URL and then apply it to the source of that image tag that we set in the HTML. If we go ahead and choose a file it's going to start the upload and then you'll see it updated in the document after a couple seconds.

S1

Speaker 1

16:42

If we jump back to the Firebase console we can also see the image in the storage bucket there as well. That was super easy. And now we can get on to my favorite part of Firebase, which is Cloud Functions. We're going to do something very simple.

S1

Speaker 1

16:55

But if you want to see Cloud Functions do things like hit machine learning APIs, handle payments, send emails, and things like that, check out the functions tag on the main website. Functions can be thought of as your own Node.js server that runs on demand. So instead of having 1 giant monolithic framework that handles all of your backend code, You write microservices that perform a specific function. And anything that you can do in Node.js, you can do in a function.

S1

Speaker 1

17:22

You can install any npm packages you want into your functions environment. And the Node.js ecosystem is huge, so that opens the door for a lot of creativity. We can initialize functions in our project by running Firebase init functions. That's going to create a new directory called functions, which isolates all of our back end code.

S1

Speaker 1

17:41

You can trigger functions in a variety of ways, but the way we're going to do it is with a Firestore database trigger. What that means is we're going to listen to a specific document path, and when a new document is created there, it's going to trigger that function code to run on the backend. What we're going to do in this case is just send a message from the function back to the database. The idea here is to show you how information can be shared between your backend code and your database.

S1

Speaker 1

18:07

Inside the functions directory we have a package JSON which defines all of our third-party npm dependencies. Then we can define our functions in the index.js file. And another unique thing we can do here is use the Firebase Admin SDK. The Admin SDK can only be used in a back-end environment like Cloud Functions, and it will bypass any security rules that you've defined in your Firebase app.

S1

Speaker 1

18:32

The first thing we want to do is say exports, followed by the name of our function, which in this case is sendMessage. Then we'll point this function to Firestore on documents in the products collection. The brackets make the product ID a wild card, so it's going to run this function every time a new document is created. Inside this onCreate trigger, we need to return a promise, and it's going to give us access to this event object that has some information about the incoming request.

S1

Speaker 1

19:00

In Firestore, we can get the document ID from the event params, and then we can get the data inside that document from the event data data. And in this demo, we're only interested in the name of the actual product. So now the Cloud Functions receive some data, and it wants to send that data back as an update to the same document. So to do that, we say admin firestore, and then reference that document path.

S1

Speaker 1

19:27

Then the last thing we'll do is return the actual update operation, which is a promise. In other words, we're returning the update operation from this function. And the function will terminate as soon as that promise resolves. The last thing we need to do is run Firebase deploy functions.

S1

Speaker 1

19:44

And that will send our code up to Firebase. You can verify that it was deployed by going to the functions tab and you should now see that function in there with some basic analytics. Then if you switch over to Firestore and add a document to the products collection, you should see the update run after a second or so of latency. So that wraps up the main development resources in a Firebase project.

S1

Speaker 1

20:08

Authentication, database, storage, hosting, and functions. But when it comes to native mobile apps there's still a huge number of features that we haven't even looked at. So let's quickly go over some of the highlights there. The first area is testing and stability.

S1

Speaker 1

20:23

If you're like most developers, you probably don't enjoy writing a lot of tests. But thankfully, Firebase has a robo-testing tool where you can just upload your app build and it will run a suite of tests that look for issues that commonly cause mobile apps to crash and you can review the screenshot results of every test. The next thing is analytics and there's a ton of analytic tools in Firebase, but the 1 that really stands out to me is StreamView. It gives you a global geographic representation of your entire user base in real time.

S1

Speaker 1

20:54

Then you might want to use trending data there to send push notifications to your users. Firebase makes it easy to send out push notifications based on a user segment, specific topic, or just to a single device. You can also set up A-B testing for your notifications and track the conversion rates of each 1 that you send. I'm going to Go ahead and wrap up my tour of Firebase there.

S1

Speaker 1

21:17

If this video helped you, please like and subscribe. And if you're serious about building apps with Firebase, check out Angular Firebase Pro where you get access to a whole bunch of exclusive resources designed to help you build and ship your app faster. Thanks for watching, and I'll see you soon.