100 Firebase Tips, Tricks, and Screw-ups

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
welcome to my top 10 firebase tips welcome to my top 25 firebase tips nope welcome to my top 100 firebase tips I've been working with firebase for several years now I've made plenty of mistakes along the way but I've also uncovered some secrets that you may not know about so hopefully this video makes your experience with firebase 100 times easier if you're new here like and subscribe and if you're serious about building an app with firebase consider becoming a pro member at fire ship item you'll get access to full project courses and a free t-shirt if you sign up for life or you can get a free t-shirt by leaving the best firebase tip in the comments below the first thing you'll need is a firebase project if you're building a serious app create two fire based projects one for development and one for production this gives you a sandbox for testing and experimenting and you can keep your customer data pristine in the production project in your production project link Google Analytics firebase can automatically set up analytics for iOS Android and the web if you're working with a team head over to the Settings tab and then go to users and permissions assign rules based on the principle of least privilege so team members only have access to the resources that they actually need from their head over to the data privacy tab and update your contact information to ensure you're in compliance with gdpr now click the button to add a new app to your firebase project when you do that it will give you an object with a bunch of credentials don't worry these are perfectly safe in your front-end code as long as you set up security rules which we'll look at later upgrade your firebase plan to blaze its pay-as-you-go but you still get all the free stuff that you would on the spark tier but you still want to stay on top of costs so head over to the GCP console and set up a budget alert for your project and monitor your monthly usage from the reports panel this will tell you exactly which services are costing you the most money make sure to install the firebase command line tools globally on your system and also the Google Cloud SDK a firebase project is actually just a layer on top of a Google cloud platform project once you've done this you should have access to the firebase command and the g-cloud command on your local system so now that we have a project set up let's look at how we can actually deploy our code to this project if you're building an iOS or Android app use firebase app distribution to distribute your app to testers this will bypass test flight and the Google Play Store making your life much easier now if you're building a web application you're likely using a package manager like NPM install firebase tools into the development environment for that project and now you can write NPM scripts that use the firebase CLI tools now if you followed my earlier advice to set up different projects for development of production you can use the project flag to set up different commands that specify the project so here we have a command to deploy to our development project and another for our production project now after you deployed your site head over to the firebase console and you can see it's deployed at a cool domain called your project web app or you can just connect your own custom domain and you're not limited to a single domain for example you might have an admin site and a customer facing site they can both share the same firebase project with multi site hosting then go into your firebase JSON file change the hosting value to an array and set up different targets that represent the different sites you want to deploy now you're not just limited to static files when deploying to hosting you can actually rewrite traffic to a cloud function or to a cloud run instance and that means you can do SSR was something like angular Universal or next j/s you can also set up firebase hosting rewrites for dynamic links this allows you to dynamically send the user to the app with the best possible experience so if the user goes to a link on their iPhone it will take them to a specific screen in the iPhone app you can also specify headers on these static files in your hosting account for example if we wanted to change the course settings for all the font files we could do it like this and firebase hosting will also cache our static files for better performance but we can change the caching behavior by setting different cache headers here as well and one cool thing you might do to extend firebase hosting is to set it up with Google cloud build so every get commits you make to your project it will deploy a new version of your site to your hosting account that's exactly what I do for a fire ship io firebase provides two different fully managed no SQL databases so how do you know which one to choose I default to cloud fire store because it has more powerful query capabilities it also cost less per gigabytes stored however real-time database does not charge for writes so it can be a great option if you have data that's updated frequently like an IOT sensor or something along those lines but when it comes to pricing you really shouldn't worry about it too much don't even trip dog firebase overall is very inexpensive and it will take a decent number of monthly active users before you even break out of the free tier unless you make a silly mistake you'll be paying much less than you would be with other cloud solutions a more important thing to work about is that you backup your data on a regular basis set up a dedicated cloud storage bucket for backups and then you can backup your entire database with a single command when you create your database for the first time set it in locked mode it's safer to start with a lockdown database then incrementally allow operations as they become necessary after you've created a firestorm go ahead and click the filter icon and you'll see that you can make queries directly from the firebase console and it even provides some code for your query that you can copy and paste to using your app source code in fact let's go ahead and switch gears and jump into the source code for a JavaScript application now the way you import firebase depends on the flavor of JavaScript that you're using you can see the import syntax here for a common j/s es6 and typescript but all of these are actually wrong because they're importing from firebase directly your code will work but it will create a huge JavaScript bundle that will slow down your app the correct way to use firebase is to import from the firebase app namespace and then import these services that you plan on using aka progressive enhancement in any case firebase is a pretty big dependency so if you're loading it with a script tag you'll want to use the defer keyword on that script to ensure it loads after the actual Dom or HTML has been parsed but if you're using a framework then you shouldn't have to worry about this angular app should use angular fire which integrates with change detection and the angular router if you use react on the front-end the react fire library was just under cated and it provides support for hooks and suspense you have rx fire to integrate with rxjs which works great in frameworks like spelt then outside of the web you have support for all kinds of different other frameworks in firebase extended like flutter Arduino and many others when you first add firebase to a project there's a couple of no-brainer services that you'll definitely want to use such as performance monitoring with a single line of code we can see how well our app performs out in the wild giving us metrics like first contentful paint across all devices using our app the next one is crashlytics which is only relevant to native mobile apps it's very easy to set up and it will give you error reporting and crash reporting throughout your entire application and automatically open issues so you can address those problems and lastly we have firebase analytics with a single line of code we'll get the default reporting from Google Analytics giving us insight about the behavior of our users now in your source code one of the first things you'll likely want to do is determine if a user is logged in or not there are two main ways to do this you can pull the current user at any time by calling off current user this is usually best for handling events like when the user clicks a button and then you want to grab their auth record and do something afterwards the other way to get the current user is to always be listening to the current off state in this case you provide a callback function to listen to changes to the off state like when the user signs in or signs out in either case I recommend getting good at asynchronous JavaScript to be successful with firebase understanding async await is very useful for the first approach in understanding callbacks and functional programming is very useful for the second approach when a user attempts to login something might go wrong it might be your fault as the developer or the users fault in any case you want to make sure that you catch these errors and then create a default handler that routes them to a visual UI element like a dialog a cool trick you can do with firebase auth is to register a user lazily for example you might first have a user sign in anonymously which will give you a user ID that you can tie to the database then later in the onboarding process you can collect their email or link social accounts like Twitter Facebook Google etc now certain authentication methods like email password may need to send emails to your users for things like email verification and resetting passwords sometimes you might want to control this process on your own which you can do with custom email action handlers and you can even bring your own custom SMTP email server now one of the most important aspects of any application is managing relational data let's check out a few common techniques for connecting our users to the firestore database we can create a one-to-one relationship where the user has one document and firestore by first retrieving their user ID then we'll make a reference to a collection and set the document ID as the user ID every user ID is unique so it guarantees that that user can only have one document in that collection now if it's possible that data already exists there you might want to use the merge true option this will ensure that any data that already exists there won't be overwritten the emerge true option just makes it a non-destructive update another common relationship is one-to-many a user might have many orders but an order belongs to one user the best way to handle this type of relationship is to use a sub collection in the last example we created a document with a use and we know that every subcollection under that document is owned by that user but sometimes you might run into a situation where you want to query orders across all the users in your database firebase provides a special method that allows you to group sub collections and query them together collection group will find all of the collections that share the name orders grouped them together allowing you to make a single query against all of them in another very common relationship is many to many in this case we have a single collection called chats and each chat document can be associated with multiple users we can associate multiple users to multiple chats by embedding their user IDs on the chat document using a map of key value pairs the key is the user ID and then I'm going to duplicate the display name in case we want to show that in the UI data duplication is perfectly OK and no SQL it can optimize for performance and costs but it works best with values that are immutable or that don't need to be updated very often and now that we have a map object on this document where each key in that map is a user ID we can query it by using dot notation in our queries like ordered by members dot user ID now that we've modeled some data and made some queries we need to decide if we want our data in real time format or not if you're trying to optimize pricing and don't think you'll need real-time updates for your data you can just call query get to retrieve the data once and then not listen to any future updates but if you are building a feature where the UI should react to changes in real time you'll want to use query on snapshot then run a callback function anytime the underlying data changes on a collection query when you listen to Doc's you'll get a new array anytime there's a change to the underlying data but you might want to know exactly which documents were added modified or removed doc changes provides an array of all the documents that changed their old index new index and the change type another awesome thing about firestore is that it's able to work offline if the internet goes out and the user is still trying to send writes to the database firestore will still update the UI and then send those rights to the actual database and commit them after the internet comes back online and you can even make this work across multiple browser tabs by setting the synchronized tabs option to true now one question I get a lot is how do I use emoji characters in my code well they're actually just utf-8 characters which means you can use them in a regular string and that also means that you can use them in your fire store documents and make queries against them another trick you might want to use is to match a wild-card string for example if we wanted to query all of the fast and the furious movie titles create a starting point and then make your ending point a tilde character this will match all the documents that start with the fast and the furious title and with that we have reached the halfway mark let's take a quick break welcome back sometimes you might have a compound query where you chain together multiple query conditions this query won't work by default because it requires an index but don't create the index manually let your app throw an error then click the link to the firestore console to create the index automatically one of the most powerful data types in fires store is a list we can add a list to a document by simply setting it with a JavaScript array but we might decide later that any good firebase recipe needs to include a pineapple we can use the firestore array union method to ensure that the array includes exactly one pineapple or we might decide later on that maybe squid wasn't such a good idea in this recipe so we can remove it by using the array removed method without having to know the actual index and now that we have an array on the document we can query it by using the array contains operator inside of where and that will give us all of the recipes that contain avocado now sometimes you might have an array that contains IDs of other documents in the database but how do you actually fetch the full documents in this array do it in JavaScript by mapping all of the ID strings to an array of promises that get the document then run them together with promise all one thing you should generally avoid doing is setting a timestamp from your friend code because the users clock might not be synchronized properly if you need to set a timestamp on a document use the firestore server timestamp that ensures that all users are sharing the same clock another thing you might want to do is increment a counter like the score of the game you can change the value of the counter atomically without knowing its current value by using the increment field value now firestore only supports one write per document per second although you can burst above that value so if you have a ton of writes happening on a single document you can set up a distributed counter which is now very easy to do because there is a firebase extension that's a and speaking of atomic sometimes you might have rights that need to succeed or fail together maybe the user completes the game you write the score and then you want to update the users lifetime score you can ensure that these operations happen together by setting up a batch right this will commit them together but roll back to the previous state if any of the writes fail now firestore is a great solution for the vast majority of use cases but sometimes you might need a full relational database if you need a full relational database check out my video on integrating MySQL into a firebase project or if you need full text search check out my algo Lea integration video now one of the most important things to do as a firebase developer is set rules before you deploy to production if you deploy an app without good security rules in place your customers data could be compromised and someone could make destructive writes to your database currently our databases in lock mode which means we're safe but now let's go ahead and open up some operations for our users the first thing you should do is get used to using the simulator it allows you to pass mock requests to the database to see how the rules will be evaluated but serious production apps should use the firestore emulator this allows you to simulate the firestore database in your local development environment so you can throw a whole bunch of different test cases at your rules to ensure that they're robust note that there are five different types of operations a user can make on a document they can get a single document a query of a list of documents and they can create update and delete documents you can provide fine-grained rules for each operation or you can combine them by using the read or write keywords if they share the same logic just separate them with a comma when a rule is evaluated there are two things that you look at the request and the resource the request contains the user's authentication state as well as the incoming data that they're trying to write to the database the resource on the other hand is the data that already exists at this path in the database but in some cases you might need to look elsewhere in the database to determine if a rule should be allowed use the get keyword and then point to a path in the database and you can use dollar sign parentheses to interpolate values like the request aunt user ID this gives you the value from this document but keep in mind that you're charged a read every time this rule is evaluated now you might notice that this is a very long line of code and if we were using this frequently throughout the rules we wouldn't want to have to repeat it all the time we can extract this logic into its own function call is admin and now we have a much cleaner way to check for admin users now let's switch gears to cloud storage a storage bucket is where you would put things like images videos and RAW files you have a default bucket which is where you would normally save your user-generated content but you can create additional buckets as well you might want an additional bucket for firestore backups which you can set to cold line which will save you some money now when you upload a file to a storage bucket there is a storage location in a download URL if the user needs to access this file again in the future I recommend saving both values to the firestore database you can use these storage locations to replace or delete the file in the future or the download URL to access the file in your app but don't worry too much if you forgot to save the file path in the database because you can use the storage ref from URL and point to either the full path in the storage bucket or to the download URL to access that file sometimes you might want to list out all the files in a directory in the bucket simply make a reference to the path to the directory and then use the list all method to get all the files at that location you can upload a file by simply making a reference to a file path and then putting the raw file that you want to upload you can calculate the progress of an upload by listening to the state changed event then divide the bytes transferred by the total bytes in the file if you have multiple files to upload feel free to upload them all at the same time firebase will automatically handle concurrency and upload them as efficiently as possible when you upload files you might also want to save your own custom metadata about that file you might want to know what kind of device the user upload the file from their user ID and stuff like that if your users can upload image files there's a good chance that you'll want to resize them to different resolutions for different devices you can now do that with a click of a button that using the firebase image resizer extension at this point we've been mostly looking at front-end code so now I want to switch gears to the backend you can create your own command line utility for firebase with three easy steps go to your project settings and download the service account for your project in a node project install firebase admin as a development dependency then create a J's file that imports it and calls initialize app firebase admin needs your service account but it contains sensitive information the safest way to use it locally is to keep it somewhere private on your system and then use an environment variable called Google application but if you include the service account directly in your source code make sure it's in your git ignore so it doesn't end up in a public repo somewhere one of my favorite things to do with an admin script is to seed the database with some dummy data install faker J s and then import it into your JavaScript file then create a loop and for each iteration add a new document to the collection using faker to automatically generate the dummy data now run the script from the command line with node you should now see a bunch of dummy documents seated in your database now you can do a lot with the firebase admin SDK but you can do even more with the REST API s check out the REST API documentation to find secret techniques that you didn't know about earlier I showed you how to backup firestore from the command-line but you can also do it with the REST API this would allow you to set up a cron job to backup your database on a daily basis if you do use the REST API you'll want to use the Google API NPM package this allows you to discover and interact with hundreds of different Google API s like Adwords YouTube and of course firebase creating an admin script can be useful but in most cases you'll be working with firebase admin in a cloud function you can add cloud functions to your project by running firebase and net functions when you do this I highly recommend using typescript because it does all the setup for you and will help you catch silly errors before they end up in production there's a few things we can do to improve the performance of a cold start on a cloud function and also reduce the CPU time that were actually billed for try to minimize the number of dependencies that you use in your functions more code to load and parse means a slower cold start time if you have values that can be shared between multiple function invocations you can set them up as global variables when a function instance spins up in the cloud it might be used multiple times so global variables can be used across multiple calls improving performance when you design your cloud functions they should always be item potent cloud functions are guaranteed to be invoked at least once but they can be retried multiple times so you want to make sure that multiple calls to the same function produces the same result and you can use the context event ID to help you achieve that if you need to add more horsepower to a function you can use run with to max out the memory at two gigabytes and the timeout seconds to 540 now one thing you want to be really careful not to do is to create an infinite loop you might accidentally do this in firestore by updating the same document that triggered the event in this example we have an on write function updates the same document that triggered the right so this will cause an infinite loop that will charge up your firebase bill until you hit the quota limits it's not a good thing to do however there are use cases when you might want the triggering function to update the same document you can avoid the infinite loop by checking if the after document is equal to the before document this will check for equality on the document path and its data and that will stop the loop assuming your function is idempotent background cloud functions must always return a promise you can ensure that always happens by using the async keyword in the function callback then you can use the await keyword for a much cleaner synchronous looking code sometimes you might need a cloud function that communicates with other cloud functions or other GCP services you could use an HTTP function to handle that but you would also need to implement some code to validate the request a better alternative would be to set up a pub sub function it allows you to pass messages between your internal services and that's easier and more secure than exposing an HTTP endpoint you might also have endpoints that should only be accessed by authenticated users in a regular HTTP function you would need to extract the authorization header that you set in your front-end code and then verify the ID token as an alternative you can simplify both your back-end and front-end code by using callable functions it includes the auth context for the user so you don't have to implement your own middleware to authenticate your functions a great use case is to delete an entire firestore collection which should always be done on the backend because there might be tons of documents in a collection we can first authorize the operation by looking at the user ID then we'll create a recursive function called batch delete it retrieves documents and batches of 100 and then deletes that this will ensure that we don't hit memory issues if we try to query millions of documents in a single go now when implementing the actual logic for your back-end code consider breaking it down into small JavaScript functions this allows you to reuse code across multiple deployed cloud functions and it's also just easier to test keep in mind that cloud functions provide a gateway to interact with other third party API s almost every good API also has a good nodejs library to go with it so basically anything you can build an ojs you can build in a cloud function when you're ready to go live you can deploy all of your functions from the command line with a single command but on larger projects with dozens of functions you may not want to deploy everything all once you can append the name of the function to the end of this command to deploy a single function despite your best efforts your functions will very likely have some bugs the best way to prevent bugs is to run the cloud functions shell locally you can invoke your functions with mock data to test their behavior and firebase even provides a unit testing library now your functions still might break in production so you can always look at the firebase logs to see what's going wrong or better yet head over to stackdriver where you can create your own custom dashboards and alerts for the things that you care about earlier in the video we set up analytics in our front-end code but to get the most out of it we'll want to track custom events and user properties try to pinpoint the events or user behaviors that you think are most important to turning that user into a paying customer then use firebase analytics to record those events firebase will aggregate some of the data automatically but you can create your own audiences based on the type of user that you want to target your marketing team will love audiences because you can target messaging to a specific type of user and also do things like a be testing and funnels and as a developer you can actually use audiences to customize the UI based on your underlying analytics data the service will send key value pairs down to your front-end application which you can use to conditionally show UI based on where that user is located what audience they belong to and so on you can also use the same data to send push notifications to your users using firebase Cloud messaging instead of sending a bulk notification out to all of your users segment it to the users who actually want it and will benefit from it and with that we have finally reached firebase tip number 100 leverage machine-learning within your app you can do this in multiple ways with firebase use predictions to guess when a user is going to buy your product use ml kit to implement a I driven features out-of-the-box things like object detection and smart reply or build your own image classification models with Auto ml and you can even export all of your analytics and fire store data to bigquery and use that raw data to train your own tensorflow models from scratch and that is all of the firebase tips that exists in the world if you have your own additional tips leave them in the comments below and I'll pick a couple of the best ones to win a t-shirt later this week I'm gonna go ahead and wrap things up there hopefully you found something useful here thanks for watching and I will talk to you soon [Music]
Info
Channel: Fireship
Views: 107,095
Rating: 4.9724474 out of 5
Keywords: webdev, app development, lesson, tutorial, top100, top 100, top 10, firebase tips, firebase basics, firebase overview, firebase pricing, firebase optimziation, firebase, firestore, firebase auth, realtimedb vs firestore, firestore tips, js, firebase js, firebase nodejs, firebase admin
Id: iWEgpdVSZyg
Channel Id: undefined
Length: 24min 31sec (1471 seconds)
Published: Mon Oct 14 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.