[MUSIC PLAYING] ANDREA WU: You know that feeling
when you have an amazing app idea and then you start
thinking about how to build it? Most apps follow a pretty
common app architecture. Apps need data, so
there's a database. Users want to access that
data, so there's some kind of authentication system. For big files, you'll need
some kind of media server. And then an API server combines
all of that into information a client app finds useful. But here's the thing. Your idea is a really good one. And once you build
this app, people will jump on to using it. That's great, but
that also means you'll need to think about what
happens when it starts to grow. Suddenly, this
architecture diagram brings up all
kinds of questions. What about new platforms? Is the server secure? Is the database fast enough? How do you scale the API server? Can the media server
store terabytes of data? With all of these
concerns, you might forget that the reason
you started going down the spiral of
worries is that you had a great idea that
will gain users quickly and you want to implement it. If only there were
something that would let you do
this more easily, something where
you can trust that will keep running smoothly
if the app goes viral and can scale from one user
to millions of users without having to adjust
any infrastructure. What might that be? Firebase. And so what is Firebase? Firebase is Google's client
side app development platform. It's based on Google
Cloud, and Firebase integrates with several
other Google tools such as Analytics and Ads. And as it's built on
Google infrastructure, it is designed to scale. Regardless of what platform
you want to build on, Firebase supports a lot of
different client app platforms. There are client side SDKs for
iOS, Swift, and Objective-C, Android, Java, and Kotlin, Web,
JavaScript, and TypeScript, as well as frameworks like
Angular, React, and Vue, C++ and Unity for game
developers, and Flutter. Firebase is a suite of
almost 20 different products and is intended to help
you through the lifecycle of developing apps,
which typically goes something like this. When you're first
starting out, well, you'll need to build the app. These are the products
that can help you do that. There's authentication
that enables you to know a user's identity
and to authenticate them to your app, Cloud Firestore
and Realtime Database, which are both NoSQL
databases, cloud storage to help you store big blobs
of data like photos, videos, and audio content, and hosting,
which helps you put your web app onto the internet. After your app is
built and deployed, you can monitor its performance
by using Crashlytics and Performance Monitoring. And you can fix bugs and use
Test Lab to test those fixes on all different
types of devices that you may not have
lying around at home. Once that's done, your app will
hopefully reach a stable state. And you may want to grow your
app to attract more users as well as retain the
users you already have. To do so, there
is Cloud Messaging and In-App Messaging
to send notifications if you want to remind users
about purchases or events, A/B testing to test any
change before rolling it out to all of your users,
and remote config for serving different
user experiences based on user properties
without needing to ask your users to download
a new version of your app. These products will help you
decide what your users like in hopes of making sure
they continue using your app and get more people
to use it, too. Firebase does have a
large variety of products. And the good part is
you can pick and choose which ones would help
you most in your app. To use any of
them, you just have to install the Firebase
SDK to whatever platform you're using to build your app. And most of these products
entail just a few lines of code to get the
feature up and running. All right, so now that
you know what Firebase is, let's talk about using
it to build out a new app, an expense tracker. As a person who
really cares about how I'm spending my
money, I really want to keep track of my expenses. What I actually do now is keep
a spreadsheet of those expenses. I look at my receipt
and manually enter the date, vendor, item bought,
and amount spent each time I spend money. And this is mostly fine
until this happens-- having tons of expenses because
I procrastinated and let my expenses pile up, or
I went on a business trip and have a ton of expenses
from all those taxis I took and each meal I had on top of
the flights and hotel expenses. It becomes quite painful and
tedious to manually enter all of this data. In large quantities,
it's just really not that great of an experience
to have to manually input the date, vendor, item
bought, and amount for all of those receipts. So how might an app
make this better? Instead of having
to manually type in the expense data for
all of those receipts that I'm keeping around anyway,
let's make an app to let users conveniently scan receipts,
and the app will automatically extract the relevant
information from those receipts. That way, the app
does all the work with just an uploaded
receipt image. And it can send
extracted information to the user for verification. The user no longer needs
to do any manual work other than taking a
picture of the receipt. So what will the
user experience? First, they'll upload images
either by taking a photo through their camera or by
choosing an image they already have on their phone. Then behind the scenes, the
app finds and extracts the text by scanning the receipt to
parse for information like date, vendor, item bought,
and amount spent. Finally, the app will relay
the extracted information back to the user who
needs to confirm it. Diving deeper, here are
the app requirements. Be able to securely
upload the receipt images, store these images
and extract the text, and do image processing
on the uploaded receipts. Sounds quite complicated,
but let's see how to do it. The first step
mentioned is to secure image upload, which means users
need to be able to sign in. I don't really want to spend
my precious time building an authentication system,
and it would probably be quite tricky to
get the security of it correct on the first try. Also, as a user of a
lot of apps myself, I know that I don't
really enjoy creating a new account for every
single app that I use. It gets repetitive to set up
an account with my first name, last name, email, birthday,
the name of the street I grew up on, and so on. Then I have to
remember my password, which I probably will not
be able to do since, well, everyone supposedly uses a
different password for all the millions of
accounts that we have. It would be really nice
to not need to create a new account to use this app. Well, there's Firebase
Authentication. Auth provides
identity-as-a-service, meaning it lets you
know who your user is. It also provides a rules system
that lets you grant or deny access to resources and
other Firebase products like Firestore and Storage. Auth also is ready to
use out of the box, and it gives some
advanced functionalities like email verification
and account linking. Regarding the concern
about not wanting to create a new
account, Firebase Auth works with many third-party
identity providers, including Google, Facebook,
Twitter, GitHub, and more. Once users sign in with
one of these services, the user gets assigned a record
within Firebase's system. This includes a unique user
ID and a signed web token so you get a consistent
representation of your users, and one that you can use
against both Firebase's services and your
own custom servers, no matter how they sign in. So let's see some code for
how to let a user create an account using
email and password, log in with that
account information, sign in with a third party
provider in case they don't want to create a new
account, and check whether the user is logged in. First, let's talk about enabling
our users to create accounts via email and password. To do so, you would
have to first make some pages for the user
to create an account, as shown here. Assuming the users fill in
both username and password, you can then write some Firebase
Auth code to create an account. Taking the email and password
from the previous screens, call createUserWithEmailAndPassword,
which will result in either
a successful creation of the account or it will error. If it errors, you can
handle the errors here. If it succeeds, you'll be able
to see the user's new account in Firebase Console,
which is a web portal to let you manage and
view Firebase usage for your project. In this case, you'll see all
users, what provider they used, the date the account was
created, and the unique user ID identifying this user
throughout your app. All right, so that was
how you implement code to let a user create an account. What if you need them to
sign in with that already created account? Let's say this is
the screen for it, and the user again types in
the necessary information. Upon pushing the
Submit button, call signInWithEmailAndPassword
and again pass in the email and
password from the screen. And this will again result in
either a success or an error. If it fails, you can
handle the errors here. So now let's say
your users do not want to create a new
account to use this app. So you'll let them sign in
with a third-party provider. You'd need to create an
instance of the Google provider object, which says to
use Google sign in. If you wanted to use Facebook,
Twitter GitHub, and so on, you would use those
respective providers here. Next, have the
user authenticate. There are two ways to do
this, either by opening a pop-up window or by
redirecting to a sign-in page. What's shown here is signing
in with pop-up and pass in the provider into
that function call. What this says is
use Firebase Auth to sign in with a pop-up
using the Google provider. Finally, handle the cases of a
user being successfully signed in versus not. So this is how you
could implement Auth using third-party providers
with just a few lines of code. You've seen up to hear about how
a user can create an account, sign in with said
account, and sign in with a third-party provider. Now you'll see how to
check whether a user is logged in already or not. Whenever
createUserWithEmailAndPassword and signInWithEmailAndPassword
get called without an error, the onAuthStateChanged
function gets triggered. If there is a user, then
the user is signed in. Otherwise, no user is
signed in, and the function got called because
the user logged out. This function will
return a user whenever createUserWithEmailAndPassword
and signInWithEmailAndPassword get called successfully, as well
as with third-party providers such as Google, Facebook,
Twitter, and so on. Once you have the user, you can
also get various information about the user like display
name, email, and their user ID, as shown here. Great. So you've seen how users can
create accounts and log in, as well as how to know whether
a user is already logged in or not. One last tidbit. Even though the code
is already not much, thanks to Firebase Auth
for all of these steps, it is still quite a bit
of work to actually make these sign-in screens,
sign-in screens with multiple third-party
sign-in buttons or a Create New User screen, or screens to
reset and change passwords. And if that's not where you want
to spend your development time, you can use the Firebase
UI library, which handles all of these cases for you. It's an open source library
so you can customize it as you would like to fit the
look and feel of your app. You've now enabled
user accounts. And the next thing a user
will want to do after logging in is uploading receipts. Let's say there's a screen to
let the user upload a receipt either by taking a photo
of it or by choosing a file that already exists. Once they do that
and upload it, it needs to be stored somewhere. What should the
storage system be like? Well, as users might be using
many different image types, the storage system
needs to handle that. It also needs to work well
even with spotty internet connections. And, lastly, as users
might upload many receipts, the storage system needs to
be able to store all of them. While these receipts are
added, hopefully, a team does not need to
keep an eye on usage to adjust that storage capacity. Cloud Storage was designed with
many of these concerns in mind. It lets you store
many image types. And on top of that, it
lets you store and serve user-generated content
like audio and video. It's generally used for storing
big blobs of unstructured data that you do not need
to change too often. To store a lot of receipts,
the amount of storage will scale automatically,
meaning that storage space will increase as you
have more content, and it will decrease
as you delete content. You will not need someone
sitting there manually managing the amount of space your
app is taking up in storage. Sometimes internet
connection isn't so great, and it's not ideal for
half-uploaded receipts to be dropped because
the internet was spotty. Storage takes care of this and
handles retrying and resuming uploads and syncs whenever
a user's phone gets back its internet. After the receipt
is uploaded, it can be shared with
other users instantly. So this means that if
the user's parents wanted to look at the receipts
for whatever reason, they can right after uploading. But a user probably doesn't
want to just let anyone be able to see the receipts. To protect the
user's assets, there are security rules you
can set to protect them. And these rules can say who
is allowed to read and write certain files in Cloud Storage. Now let's look at some
code to upload files. Firebase Storage supports
files from JavaScript file and Blob APIs, bytes,
and various string types. Where are we going to store it? Files are stored in a
Cloud Storage bucket. And the files in this
bucket are presented in a hierarchical
structure, just like the file system on
your local hard disk. By creating a
reference to a file, your app gains access to it. And a reference can either
point to a specific file or to a higher level
node in the hierarchy. A reference can be
thought of as a pointer to a file in the cloud. To create a reference,
call getStorage. Then call ref with the
former as an argument. This reference points to the
root of your Cloud Storage buckets. From there, you can
create a reference to a location lower in the tree. In this case, you've
created a file. Now with the reference, you can
then upload it to Cloud Storage by calling uploadBytes,
which uploads JavaScript files, blobs, or bytes. You'll pass it the file
reference and the information you want to store
there, the file itself. The file will then
get uploaded, and you can do any post-processing
needed after it does so. If you want to upload a string,
use the uploadString function and pass in the reference,
the string to store, and the string type. So now you've enabled
users to upload receipts and put those
receipts into storage. Next up is processing
the receipt and extracting the text. But processing on the client
side, which in this case will probably be a phone,
might not be the best idea. Why not? Well, once you write
your top secret code to process the receipts,
it would be pretty bad if anyone could take
it along with the data. Requests coming in
from users' devices might be trying to steal it. So something to help with
running code against your data securely would be ideal. Also, for both
Android and iOS users to be able to use
your app, you'll have to write code to
process the receipts twice. It would be much better if you
could write it once and have the code run instead of
writing it once for iOS and deploying to the App Store
and writing it once for Android to deploy to the Play Store. Also, if you deployed
the app separately, iOS users might get this
awesome feature first, and Android users might get mad. We definitely don't
want that to happen. And remember, you're looking to
process those receipts, which probably means running some text
recognition on those receipts. This might be CPU intensive, and
running highly intensive code off of users' devices might
drain a user's battery. Cloud Functions enables you to
run backend code in the cloud. It's in a secure environment,
and you can write it once for both Android and iOS. To run code, you
can trigger it based on platform events or an HTTP
request on both platforms. And since it's running on the
cloud off of the user's device, this will not drain
their battery. Best of all, you can
basically run backend code without managing any servers. Using Cloud Functions to
run the processing code, what are the functions
actually going to do? Well, some machine learning can
help extract the information from the receipt, also
known as Optical Character Recognition or OCR. This should get
automatically done, but machine learning, turns
out, is not a trivial task. And, usually, a team will need
a data scientist or a machine learning expert to
build and train models. To serve these
models dynamically, the team will need to build up
the infrastructure to do that. And that's before you
can even write the client code to interact with the
model and generate predictions. This sounds like a really
long and involved task. Instead of needing to
build out your own models, you can use Firebase
Machine Learning. What is Firebase
Machine Learning? It uses Google's
machine learning models to help with different
machine learning capabilities, depending on what
features they're looking at to add to your app. It can recognize text or
barcodes from an image, translate text to a
different language, or identify important
objects in a photo. No machine learning
experience is needed. You just need to call
these Google Cloud Vision and natural language
APIs in your app and you're basically
ready to go. While these libraries can be
useful in many situations, what if you have
some machine learning needs that do not fall into
one of these categories? Well, Firebase Machine Learning
provides convenient APIs that help you use your
custom TensorFlow Lite models in your mobile apps. To do OCR, we can
use text recognition. So now you've used machine
learning to extract text from the uploaded receipts. What's next? After you get the
text back, it needs to be put in a
secure environment. There will probably be
a lot of extracted text. And this text should be quickly
accessible from anywhere in the world. Where should you put it? Cloud Firestore
is a good option. As a reminder, earlier
I talked about Storage, which is used to store
the receipt images. Storage is usually used to
store big chunks of data like images, audio, and video. Cloud Firestore,
on the other hand, is a NoSQL database
where you can store data like strings,
numbers, and whatever else your app requires. Firestore is used more
for structured data that you might be
changing often. So while receipt images are
stored in Firebase Storage, the processed text returned
from Firebase Machine Learning will be stored in Firestore. Very similar to
Storage, Firestore has security rules so clients
can talk to the database directly, but you can
still make sure they only get access to the
documents they're supposed to see or modify. Let's dive a bit deeper on how
Cloud Firestore is structured and how to use it. It's a document
model database, which means that all of
your data is stored in documents and collections. You can think of a
document as something like a dictionary
or a hash table. It has a set of key value
pairs referred to as fields. And the values here
can be a number of different types,
anything from strings to numbers to binary values to
JSON-y looking objects called maps. So here is the
document containing the fields previously shown. Each document is
stored in a collection. Documents cannot
contain other documents, but they can point to
collections that contain other documents, which can then point
to subcollections and so on. In this example, each document
will contain information from one uploaded receipt. Here are some examples of
what that might look like. Each receipt document
contains some values, including the user as
identified by their user ID given in Firebase Auth, the
date, amount, vendor, item, whether the user has
verified these details yet. All of these will go into
one collection, a collection containing all receipts. With code, it will
look like this. First, add a document
using addDoc. And the first argument
is which collection to put the document in. In this case, put it in a
collection named receipts. What should get added to each
document in the collection? Well, you'll add the key value
pairs seen in this receipt. You'll also want to
say whose receipt it is by providing the user ID
provided by Firebase Auth earlier. When the document is
successfully added, you can do something with that. And when there's an error,
you can handle it as well. In the Firebase Console, this
is what Firestore looks like. As seen here, here's
the receipts collection and the document name is
a random string made up by Firestore, which
automatically gets generated when addDoc is called. Inside this document, you
can see all the fields put in when addDoc was called. Now that you've added
the extracted text into the database, how
do you get that data out of the database to send
it to the user to ask them to verify the information? Since you'll want to get
not all of the receipts that exist in the collection,
but instead only want a specific user's receipts, you
can write a query to do that. To do so, use Firestore's
query function, with the first argument again
being the reference, which is created using the
collection function with the Firestore service
and the collection name, just like for the addDoc
Firestore function. The other arguments
for the query function will be the queries. And you can use where,
which takes a field to filter on a comparison
operator and a value. In this case, you'll
get all of the receipts where the user ID equals the
function's UID parameter. You only want to
get the documents that the user has not verified. So you'll have another query
where you check for that. With that query, use
the getDocs function to get the documents
that satisfy that query from the receipts collection. With what you get
back, you can then loop through each
of the documents and send the information
to the user to verify. As a side note,
in Firebase, there are actually two
database products. One is Cloud Firestore,
which I just talked about. And another is
Realtime Database. The major differences
between these two is that Cloud Firestore is
faster at reading and has better querying capabilities,
and Realtime Database is faster at writing. The reason for
these differences is how data is stored in each one. Firestore stores data in
collections and documents, whereas Realtime Database
stores it as a giant JSON tree. If you want to find out
more about their differences and help figure out
which one you should use, there's a link to a doc
specifically talking about that. Now that you've extracted text
by deploying functions that run text recognition
and machine learning and finally stores the results
in Firestore, what's next? You'll need to notify users
that the app has the receipt information and ask
them to confirm it. How? Let's send a push notification
by using Firebase Cloud Messaging to tell users to
confirm their receipt amounts. Firebase Cloud Messaging,
or FCM for short, is a cross-platform
messaging solution that lets you reliably
send messages at no cost. And it can deliver hundreds of
billions of messages per day, with most of them delivered
in less than 200 milliseconds. Users uploading
receipts probably all use different types of phones. With FCM, you won't have to
invent your own notification system for each phone because
FCM delivers notifications to anyone using Android,
iOS, and the web. FCM does not need you to
track what kind of devices your users are using. And you also do not need to
set up different service calls to different devices. Firebase will automatically
do that for you. Lastly, you're not
only limited to using this to remind users to confirm
their receipt information. You can also use it to
announce new features that you're launching. For other apps that are not
this expense tracker app, you can notify users
for things like letting them know their last message
was responded to, sending out discount offers, and
reminders about events. So now you have notified
users to confirm their receipt information, and you'll
store this response back into Firestore. Now that you've built
the app, the next step is launching the first
version of the app. Yay! Before doing so, it's
important to make sure that the app is bug
free and stable so that you can make the best first
impression with your users. When it comes to catching
bugs, it's much better to find them and eliminate
them in development rather than after your app has
hit production. That means testing your
app on as many devices and as many
configurations as you can. You probably care about
providing a high quality experience, but you might
not have all of the resources to hire a full QA
department, nor all the potential devices
your users might be using. If you really want to test
on all the available devices out there, both
on iOS and Android and against all the
major operating system versions out there,
well, that can get time consuming and pricey. This is where Firebase
Test Lab can help. It does a lot of
the heavy lifting to find bugs before you
ship to the App Store. With Test Lab, Firebase provides
the infrastructure for you, as we have a massive collection
of real physical test devices hosted by Google
sitting in our data centers. These devices are for a variety
of screen sizes, OS versions, and manufacturers. We cover all the bases so
that you don't have to. As Test Lab runs
your tests, it will provide log files, screenshots,
and a video of the Test Lab interacting with
your app, making it easier to debug problems. Test Lab will tell
you if it runs into cases where the app
crashes, freezes, encounters warnings, has accessibility
issues, policy violations, and performance problems. It can even spot problems
with your user interface, like a button that does
not fit on the screen. Testing in this way
using different devices is a great start. But what if you don't
want to just use the machines to do the
testing of your app and want to know more--
more about your app that a machine just can't
give you feedback on? When you want feedback
from actual human testers, you can use App Distribution. With App Distribution, you
can distribute your app to a list of trusted
testers and even whole testing teams by sending
them email invitations that walk them through the onboarding
process to become a tester. You can then notify
testers within the app whenever you release a new
build for them to test. And in the Firebase
Console, you can see the status of each
tester for specific versions of your app. By this point, through using
Test Lab and App Distribution, you've hopefully caught a lot
of bugs and user experience issues. You'll fix those bugs. And long last, the
day has actually come. You decide that the app is
really ready to launch now. Right now, the app is just
sitting on your laptop or perhaps on GitHub. You built the app for
mobile like Android or iOS, which is the most
likely chosen platform for this particular app. So you'll have to figure out
how to put it on the Play Store or the App Store. If you built this
for the web, you can use Firebase Hosting
to get it off your laptop and actually deploy it onto
a website for people to use. So let's talk a bit
about Firebase Hosting. It's a way to host
your web apps. And all you have to do is
install the Firebase command line tool and write a single
command, firebase deploy. Firebase Hosting has a global
CDN, so accessing your web app will be faster because the
place to get the content from is physically
closer to the user. Sometimes you'll have to update
your web app after deploying it once before, whether
it's because you changed some content, added some
features, or whatever other reason. When you do this update and
redeploy to Firebase Hosting, it's atomic, meaning
all of the servers get updated with the new app
and all the caches get purged. This way, the user is guaranteed
to get the latest version. So now with your
app out in the wild, you'll want to ensure
that your users are having a smooth experience. Even though you did a
lot of testing before, I think we all know that
no amount of testing will catch every single
problem in your app, unless you're a magician. In which case, can you teach me? And in case you're
not a magician, you'll need to catch and
diagnose these problems. And Crashlytics is a
good way to do that. Crashlytics is a lightweight,
real-time crash reporter that helps you track,
prioritize, and fix issues. It groups crashes by root
cause, displays associated stack traces, and
highlights the circumstances that led up to the crash. You can also configure
velocity alerts that will let you know
when an issue suddenly increases in the number
of users impacted. So just by installing the
SDK on Android and iOS, Crashlytics logs crashes
that occur in your app and all of that information
in near real time to put into an
understandable dashboard that lets you see exactly how
your app is performing from a stability
standpoint and what issues you should focus on first. Here's an illustration of
what a typical dashboard might look like in the Firebase
Console for an app that has been using Crashlytics. But not every complaint
you're going to run into is due to a crash or
an exception error. Sometimes your app can just
be slow or unresponsive. And people are
generally impatient, especially when it comes to the
time it takes to load a page. They really don't
like to wait around for your app to start up or
load that initial data set. It does need to be fast. And you might think,
well, that's fine. I've tested my app,
and it performs great. But you've probably
been testing it at work or at home on a modern
machine with decent Wi-Fi. Your users, on the
other hand, might be all over the world with all
sorts of different devices, using all different
types of networks, with all different types
of connection speeds. You need insight into what your
users' actual experience is like when they use your app. And so to help you
with that, there's Performance Monitoring,
which reports on how your app behaves with
users out in the real world. Again, just by
installing the SDK, you'll get a ton of
important performance metrics reported automatically for
you, essentially telling you how long it takes to complete
certain tasks in your app, and collecting a lot of
metrics and attributes of the user along the way. More specifically,
it will automatically monitor the code launch time
of your app, HTTP transactions it performs, and how
long your users are spending on each screen. If you suspect that
some part of your app might be slower than you
expect for some users outside of these areas, you
can measure that for yourself. All of this information is
organized into a dashboard in the Firebase Console. And it will help you drill
down into the specific devices, regions, and mobile
connection speeds of your app that are the most problematic. This way, you can
spend time optimizing the experience for the
users who might be tempted to rate your app poorly. And you can find out if
your optimizations actually improve the experience
by comparing the metrics between app versions. By using tools like Crashlytics
and Performance Monitoring, you're able to not
only monitor your app, but also hopefully fix any
issues your users are facing. And then you can use Test Lab
and App Distribution to ensure those issues are indeed fixed. Afterward, hopefully your
app reaches a stable state and has a minimal number of
huge customer-impacting bugs. You then start thinking
about growing your user base and retaining the
users you already have. To do so, you might
think about adjusting various aspects of
your app, but you're worried about
continuously asking users to download new versions of
the app for each adjustment. You're also thinking about
adding new features in order to keep your users
engaged and keeping track of development
branches, and doing so is a bit complicated. To help you avoid
these problems, you may use Firebase
Remote Config. What is it? Well, as the name suggests,
it pretty much enables you to remotely
configure your app, whether you want to
change the functionality of your app, the user interface,
or some user experience. What this actually means is
that you can fine-tune your app behavior with
conditions that you predefine without asking
your users to download a new version. This sounds pretty useful
as a mobile developer. But if you're a web developer,
you might be thinking, well, I don't need to do that anyway. So what's in it for me? Remote Config also has
targeting capabilities so you can customize
and personalize your app with
analytics-based targeting, meaning you can choose types of
users to serve some experience. It works by storing key
value pairs in the cloud. And for every key,
you give it a value based on the type of user. The key is what you're going
to use in your app code. And after setting up
the corresponding values per user type, Remote Config
will serve the correct value automatically to the user. To learn in great
detail about how to use Remote Config to launch
new features with the help of feature flagging,
feel free to check out the video linked in the
description about precisely this. Other ways to use Remote Config
include adjusting the look and feel of your buttons,
the difficulty levels of your games, how you're
showing ads, or the way items are organized in your store. Basically, for
everything you've got stored in some constants
file somewhere, wire that up through a Remote
Config and you'll have the power to
change just about anything within the app directly
from the Firebase Console without having to republish
anything to the app stores. And so now you know how to
change your app seamlessly. But how do you know those
changes are optimal? Even if you saw an
uptick in app usage, how do you know that that was
due to the changes you made in your app instead
of random chance, other changes in the app,
or maybe a promotion that was running at the time? Well, instead of just relying
on hunches or confirmation bias, you can prove it with data. And this is one of
the other use cases of Remote Config with a special
feature called personalization. You set a few alternative
user experiences and choose what to optimize,
and personalization will automatically
provide users with one of the several alternative user
experiences, the alternative that optimizes for the
objective you choose. You can again find a link in the
description about Remote Config personalization. Another way to confirm
your app changes are good is to use Firebase
A/B Testing, which consists of creating experiments
within your app and letting A/B testing tell
you which option is best for your goal, which can
be to improve retention, increase in-app
purchase revenue, or have more users complete
your onboarding flow. With anything that can
be measured in analytics, you can make it a goal. You'll set up the experiment
in the Firebase Console. And then you can just sit back
and relax with your friends in the nearby hammock. Firebase will do the
rest of the work for you. When it comes back with which
one maximizes your primary goal the best, you can then roll
out that option to your users, confident that you'll
get the best results. Both Remote Config
personalization and A/B testing seem to have the
same goal, which is to choose an optimal user
experience based on data. Why are there both
of these in Firebase? And when should
you use each one? Linked in the description
is documentation and a video addressing this question. So there you have it. The app is built, tested,
launched, monitored, and has grown in users. First, you successfully
built an app from beginning to end
with full functionality. You let users log in
via authentication, upload receipt images, which
then get stored in Storage, trigger functions to do
OCR using Firebase Machine Learning to extract details
from the receipts, which then get stored in Firestore. Next, you run functions
based on values being written into Firestore
to automatically send a cloud message to a user to have them
confirm their receipt amount. You then use Test Lab
to test your whole app on various devices and
distributed the app for even more testing
using App Distribution. Afterward, you put it up on a
website using Firebase Hosting so people can start using it. Then not only kept an
eye on any crashes that might occur using Crashlytics,
but also monitored performance using Performance Monitoring. You thought of serving
different user experiences to various audiences
by using Remote Config. And you used Remote Config
personalization and/or A/B testing to ensure
that the data has proven you are indeed
serving the best user experience to your users. The best part of all
this is you did not have to write very much code
nor set up much infrastructure to accomplish it all. Yet here you are. If you're interested in actually
building the expense tracker app using Firebase
and React for Web, you can find a link
in the description for the series I
created that takes you through the entire process. You're given code to
follow and implement along with the videos, and
the videos deep dive into the implementation
and the products. I hope the information
covered here today is useful in your app development journey,
and we cannot wait to see what you build using Firebase. [MUSIC PLAYING]