In the previous exercise,
we had already configured our Firebase backend as
a service with the new project and also set up a lot of
the data into our database and then set up our storage and
configured our Firebase Server to act as the backend for our Angular application.
In this exercise, we're going to look at a modified version of
our Angular application which makes use of the Firebase backend as
a service in order to obtain the data and
also store information for users on the servers.
Also, we will take advantage of
the authentication support that Firebase provides to authenticate users
both using an email and password approach and also using a Google account.
To get started on this exercise,
go to a convenient location on your computer and
then clone the given Git repository where I
have provided you with the Angular Firebase version of our Angular application.
So type, git clone
https://github.com/jmuppala/confusion-Angular6-Firebase.git
and then clone
the Git repository and once the Git repository is cloned to your computer,
then move into the confusion Angular Firebase
folder that will get created at this point and
then you would notice that a bunch of files are already installed there.
Let's go ahead and do an npm install to install
all the node modules on which this Angular application is dependent upon.
This version will also install
two additional node modules called Firebase and then Angular fire two.
I will explain a bit more about these two node modules later on in this exercise.
Once the project installation is complete,
open the project in an editor and then in the project,
go into the source environments folder and
then open environment.ts file and in the environment.ts file,
you will see a set of Firebase configuration that you
need to set up with your own Firebase server configuration.
As we have seen in the previous exercise,
we can obtain all this information when we click on
this button here called "Add Firebase to your web app" and then
copy this information and then paste this information
into your environment.ts file to replace
these with your specific Firebase servers configuration
for all this piece of information and once that is completed,
then you can start up your Angular application by typing "ng serve" at the prompt.
Once your Angular application is compiled with "ng serve",
then go to a browser and then type localhost:4200 to load in
your Angular application and you will notice that your Angular application is compiled
and then loaded into your browser just like before.
So, once your Angular application is up and running,
you will notice that this version of Angular application is going to be making use of
the Firebase server that you have set up in
the previous exercise and so here you would see the "Home" page,
the "About" page as we see here and the
"Menu" and the "Contact" page and obviously since we are not currently logged in,
the "My Favorites" page will display an error saying no user is logged in.
So, let's login ourselves.
Let me go back to the "Homepage" and then we'll login ourselves.
So, when you click on the login button,
you will see the typical form here with the email and the password information.
You will also see an additional button here called "Login with Google".
So let me log in with my Google account.
So, when you click on the "Login with Google",
then it will open another browser window where you will be asked to
authorize for using your Google account by this Firebase server.
So, let me go ahead and authorize
this application and then once the authorization is completed,
then you will see that your Firebase
based Angular application will start up and on the right hand corner,
you will immediately see your name being
displayed here and with the "Login" button now turned into a "Logout" button.
So, at this point,
you should be able to see your favorites
and in this case since we don't have any favorites,
so it'll be empty at this point.
Let me go back to the "Menu" and then add a couple of items into "My Favorites".
So, I'll add this dish to my favorites.
So, when I click on this dish,
you will immediately see the icon turn into a filled heart and let me also select
one more dish and add it into "My
Favorites" and then now when you go to the "My Favorites",
you will see the couple of dishes added into
your favorites as you would expect and again,
you can delete the dishes by clicking on the "Delete" toggle up here and then click on
the cross to remove the item from your list of favorites as shown here.
Now, we can also add as you realized,
we can go to any dish and then add comments about that dish.
So, let me add in a comment
here and the moment you submit the comment,
you will immediately see that your comments will be displayed here with
the comment author's name also included in here and with the date as shown here.
So, you can see that the user's submission
of comments will be supported for any specific dish.
Let me add in one more favorite and so this user will have a couple of favorites.
Let me "Logout" this user.
Go back to the "Homepage" and then "Logout" this user.
Now we will login using the other account.
So, I would- I had set up
this email password account earlier and so we will
login as this other user and once the other user is logged in,
let me again go to the "Menu" and add a couple of items into
the favorites for this particular user
and so when you go back to "My Favorites",
you will see these items listed for the second user.
Now, similarly for this user,
let me again submit another comment by this user.
So-
and you would
see that the comments submitted by the second user is also added into the application.
So, this is how your Angular application works
with the Firebase as the backend as a service.
Now of course you must be wondering,
how do we redesign our Angular application to make use of Firebase instead
of using the Standard Express plus MongoDB server that we have built earlier?
In order to configure your Angular application to communicate with the Firebase Server,
there are two node modules that you need to install into
your Angular application and one of them is the Firebase module.
The Firebase module as you see here,
provides the tools and infrastructure that enables you to communicate
with the Firebase server and to install this into your application,
you type, npm install minus minus save Firebase.
Now along with this,
there is another module called the Angular Fire 2.
So the Angular Fire 2.
Also, again I have provided the links to these two modules in the additional resources.
The AngularFire 2 is the official library
for Firebase and Angular support and as you can see,
it's an observable based support for Angular files.
So, this works to add to the Firebase npm module and then
gives you observable based interface that we can use in your Angular application.
So, we would be leveraging the AngularFire 2.
So, to make use of AngularFire2,
you need to install both Firebase as well as AngularFire 2.
So, in one shot,
install both these into your Angular application.
Now, the version of the Angular application that I have provided for you automatically
installs both these as you will see when you examine the package.json file.
Now, how to make use of these two,
I will illustrate that by quickly running you through
the modified code for the services and a couple of components where we
make use of Firebase and AngularFire2
to modify the Angular application that we have developed
earlier to make use of the Firebase server as the backend as a service.
In order to understand more about how we
leverage Firebase and AngularFire 2 within our Angular application,
our first stop is at the package.json file.
So in the package.json file,
you will notice that I have installed AngularFire2 here and also we have installed
Firebase to use in this version of the Angular application that I supply for you.
So, note that these two will automatically be installed when you type "npm
install" after cloning this git repository that I have provided for you.
If you were starting with a new Angular application,
then you should be installing both AngularFire 2 as well as Firebase in
order to leverage the use of Firebase as the backend as a service.
Now having installed these two,
let's learn how we make use of these within our services.
So, the best way to learn how to make use of both of
these is to visit some of the services that we have
configured in our application and understand how we
leverage the use of AngularFire2 and Firebase.
So, we'll start with dish.service.ts file.
So, if you go to dish.service.ts file,
you will notice that here,
in this dish service,
you will see me importing this AngularFireStore, AngularFireStoreDocument,
and AngularFireStoreCollection from AngularFire to Firestore here.
So, that brings in whatever I need from my AngularFireStore npm module,
also you will notice that I am importing everything from
Firebase/app as Firebase into my dish service here.
So, once we have imported these two,
let's take a quick look at how we reconfigure our dish service here.
So, if you go into the dish service,
you will notice that I am no longer using HTTP client.
Instead, I am injecting AFS which is the AngularFireStore into the constructor here.
The AngularFireStore is the one that gives me
access to the Firebase backend as a service.
Now, also recall that we have already configured all the details of
our server and also the filestore project in the environment.ts file earlier.
So, you should have configured this information already there
on how your Angular application should be leveraging
your Firestore based project on
your Firestore server to access the data that you have configured there.
So, this will give me access to my cloud
Firestore within my Firebase project that I have set up.
Now, the AuthService is of course the same Authservice that we have used before,
but it has modified to make use of Angular support for Firebase.
We'll visit the AuthService to learn how it has been updated.
Now, the AuthService will give us access to
this method called getAuthState which will return in an observable.
This observable, when we subscribe to it,
will give us the information as a user which contains the user's information.
So, I will obtain that and then set up the currentUser in my application
as the user returned by this observable here.
So, when we visit AuthService,
we will learn what this getAuthState will return for
us and so the currentUser's information can
be obtained from any of
the other services because we are already injecting AuthService in here.
Now, let's take a look at how getDishes method is implemented here.
Now, earlier in the getDishes method,
we were using the HTTP client to access the server at base URL+/dishes.
Now in this case,
to access a collection in my Firebase server, we'll say this.afs.
So, this is what AngularFire2 provides for us.
AFS as you see is the AngularFireStore that we have injected here and so we say
this.afs.collection and here we
will specify the specific collection that we are accessing here.
Recall that we had set up the dishes, the promotions,
and the leaders collections on my Firebase server.
So, this directly gives me access
to my dishes collection here and from the dishes collection,
I can either do.valueChanges which
will return all the information in the business collection for me,
or I can do.snapshotChanges which will
return additional information including the ID of the dishes.
So, if instead of doing snapshotChanges,
if I say valueChanges,
it will return only the dish information but it will not return
the IDs of the dishes but since I will need the IDs of my dishes,
so that's why I'm using the.snapshotChanges in this case.
So, when.snapshotChanges is called,
this will return as you see an observable which
I map and so the return value which is called as actions and these actions,
again, will be an observable which I will map each action in
this actions and then extract the data from the action that is returned here.
So the action is a value that is returned from for each of the actions
and this action contains a payload and contains inside that a dark field here.
Now, this is something that I have figured out by reading
the documentation for AngularFire2 and
so when we call this data function on this action.payload.doc,
this will give me the data.
The data for that specific dish that is
obtained from my dishes collection on the server side.
So each document in there will be returned here and
then I obtain the ID for that by saying action.payload.doc.id.
So that's where the ID of that will be
carried and then I will join the two together and return
this as a dish document back to my various components from there,
I will call this getDishes method.
So, as you recall,
from the menu component,
I am calling the getDishes method in order to obtain
the information about all the dishes in my collection.
Collection. So, each of these dish that is returned as a doc will be reconstructed into
a JavaScript object with the ID inserted here and also
the data that is extracted from this action payload.doc.data.
Now this is something that you learn by reading the documentation of AngularFire2.
Now, since I have already done that part,
I'm showing you the exact code that you are supposed to
use in order to extract the data and then supply
this data back to your component that is going to call the getDishes method here.
So, by doing this for each one of the documents there,
this document will be reconstructed to
the dish object that we
use in our Angular application and so we are able to even get access to the ID.
If you just do value changes,
it'll simply return all the documents themselves but without the IDs of the documents.
So, this additional work needs to be done within your service in order to
return the information in the right way so
that myComponents can make use of this information.
Similarly, for a getDish method,
so notice how I am accessing the information for a specific dish.
Again, we'll say this.afs and then you'll notice that I'm
saying.doc and then in here for the.doc method,
I supply dishes slash and then the ID of the specific dish.
Now, the reason why I had supplied ID,
the ID here is coming in as the parameter for the getDish method here.
Now, in order for this ID to be supplied,
I need to be able to supply that ID in
the getDishes method so when my menu is constructed,
every dish will have its ID attached to it there.
That ID is passed in here and so I will be accessing the document at this point.
So, the AngularFire2 allows you to access
a specific document which is inside a collection by saying the collection name slash,
plus the document ID or you can say this.afs.collection dishes just like you did hear,
collection dishes and then.doc and then supply doc and ID inside brackets there.
So, that's another way of addressing a specific dish.
Again, I am subscribing to snapshotChanges and this will return an action which is then
mapped again in the same format to
construct the dish object here together with the ID here.
Now, Firebase keeps the ID separate from the document
itself and so that's why I have to explicitly do
this reconstruction in order to obtain
the dish document in a way that is usable by myComponents.
Then I constructed my own server using Express and MongoDB,
the ID automatically was there in the document itself and so it was very
easy to retrieve that and supply it back to the client side.
Now, for the getFeaturedDish,
recall that for the getFeaturedDish,
we are looking for those dishes where the feature is set to true.
Now, this is where the AngularFire2 allows us to
construct a query and supply that query here for that collection.
Here I am saying this.afs collection dishes here,
so I'm still using the collection but then look at
the second parameter for this call here.
This says ref where the ref refers to each document that is in this collection.
This ref says the ref and this is where I can
use this query set up hears so which says.where.
So, meaning that each one of the documents where the featured,
as you can see, the syntax is fairly easy to follow here which says where featured.
Now, notice that feature is supplied as a string here,
and then the next one,
the operator is equal to so you can even say greater than, less than,
greater than or equal to less than or equal to any one of these things,
but notice that that should be inside quotations here and then you will say true.
So, wherever the featured property of the document is set to true,
extract all of those.
So, this query will extract only those documents
from the dishes collection where feature is set to true,
and then return only those documents from that collection here,
and from there I'm going snapshot changes and this will
return an array of documents and from there I will map them
into individual dish documents and then since I have
ensured that only one of those documents will have the feature set to true.
So, it'll return only one of them but it'll return it as an array.
So, that's why I'm constructing this
with square bracket zero the first element of the array,
and indeed it will contain only one element because only one element in my collection
will match this particular query that I have set up here with the wave here.
There are other query setups here you can also use something called order by.
So, you can order the collection by a certain property,
and some other set of querying options that are available.
Now, this is supported by Firebase on its cloud Firestore,
and that is what we can leverage using AngularFire2 to design
the code in your Angular application to do the query from the client side itself.
So, this is going to return the specific feature dish.
Now, again getDishId is going to be similar to what we have done earlier.
So, no modification there.
Now, for the postComment again
because Firebase with the cloud Firestore beta,
doesn't have the concept of population,
and so on that we have seen earlier.
So, what I'm going to do for the comments is that I'm going to post these comments as
a collection for which is enclosed inside each dish itself.
So, each dish will have its own collection of comments about that specific dish.
When I post the comment I'm going to use the dishId,
and then the comment information.
So, what I do here is that I'm going to first
query the dishes and then obtain that particular dish.
So, you can see that I am using the other way of querying for a specific document.
So, here I'm saying this afs.collection('dishes').doc dishId.
So, I can use this way of accessing a specific document if I want to.
The other way of course you have seen already with
the getDish method where I say doc dishes slash plus ID.
So, two different ways of addressing a specific document inside
a collection here and then dishId and then collection and comments.
So, this this way it's saying in
this collection for this specific document with that dishId,
there is a collection that is included in
this document and that collection has the name comments.
So, this is a nesting of a collection
inside a document which is in another higher level connection.
So, this kind of nesting of collections is allowed by
Firebase Cloud Store Beta up to 100 levels deep if you so wish to choose.
So, inside this collection,
I'm going to add.
So, how do you add a document to a collection?
To add a document to your collection,
you use the add method on a collection here.
So, you can see that on the collection comments,
I'm doing an add here and then
this is the actual document that is going to be added in here.
So, in the document itself,
you'll see that I have the author property here where I have set up the current ID,
and also I set up the first name for the author here,
I only serve the first time here so here I say this current user display name.
If the display name is true then I will set it to this current user display name.
If the user's account doesn't have a display name as attached to it then I will simply
use this current user email as the first name property here.
So, this document which contains the comment,
automatically also carries this first name field
and that is what I'm going to be using to render
the information when I render the comments in my dishDetail component.
So, notice that I am actually duplicating information here in each of the comments.
But that's okay, since these are stored as
Json documents on Firebase it's okay to
duplicate some of the information in the comments here.
But if you want further details of the current user,
you already have a reference to the user's id here so you can actually go and fetch
the document for the particular user and then
obtain further information of the user should you choose to.
Now, when I used Mongo DB plus Mongo's,
you saw that I will just use the current user's ID for
the author and then I will use the populate to populate this information.
Now Cloud Firestore beta at this moment doesn't have
any concept of this populate as far as I can see from the documentation,
maybe a future version might support a way of pulling in
information from another document and
automatically populating it into the current document.
When that happens, then this code will have to be modified to take advantage of that.
But right now as I see it,
Firestore beta doesn't have the ability to
populate information from another document into the current document.
So that's why I'm just replicating only that piece of
information that I really need when I render the comment in
my dishdetail component here and then down below
here you can see that I have the rating and the comment here and then also,
notice that I am creating
these two additional fields in my comment here called "createdAt" and "updatedAt".
Notice how I am putting the timestamp for the "createdAt".
The Firebase, now what is this Firebase I'm using here,
this Firebase is exactly what I imported here as from Firebase app.
So that provides me as you see here down below here,
that provides me with this same Firestore field value.
So this call to the firestorm field values server timestamp,
will return the current timestamp for
me and that is the information that I'm going to be storing in the "createdAt".
Now, when I inserted all the documents here,
you saw that I manually created this "createdAt" field for each of the documents.
Now this is a way of doing the same from within
our Angular code in
our client side and the same thing for the "updatedAt" field that you'll see here.
So, when you post a new comment,
you see that this is how you will add a new comment into that server.
Now, this returns a promise and so that is the information
that I'm using here to construct this promise here.
Then this other method here saying "getComments",
this "getComments as you can see it is accessing AFS collection dishes,
doc dishID and then collection comments and the notice that here,
I am not going to be requiring each comments ID
itself which I will not be using in my Angular petition anyway,
so instead of using snapshot changes,
I'm just using value changes and this will return
all the documents in this comments collection for this particular document
the dishID from the dish collection here and that will be returned
and these comments I will be rendering in my dishdetail component.
Now, in Mongos, you saw that the fact that I included the userID means
that I could do copulating of this information now with Firebase,
there is no way of populating the common information here,
so that is why I am explicitly going and then populating the comments in
my dishdetail component to fetch all the comments about
this particular dish when I render them in the dishdetail component.
So you see, that I had to adjust
the Angular code a little bit in order to deal with the fact that
Firebase doesn't support certain things that mongos supports
at least at the moment Cloud Firestore beta doesn't support these things,
and so I had to work around to deal with what Firebase allows me
to store and retrieve from the Firebase server site.
Now, it is also interesting for us to pay a quick visit to the Auth service here.
The Auth service here again,
notice that in the Auth service here I am importing this AngularFireAuth from
the AngularFire to npm submodule here.
So, here you can see that I'm importing AngularFireAuth and this
gives me access to the authentication aspect of Firebase.
Now, let's see how Firebase authentication actually works from our Angular application.
Now we will start that by looking at how login is implemented.
So, this is where I implement the login,
where I am using the email and the password.
So, this part when I import the AngularFireAuth here,
notice that the constructor I am injecting the AngularFireAuth into my constructor.
So this will inject the AngularFireAuth service
into my constructor and this gives me access to
the Firebase authentication on the server site so that I can authenticate users.
So, if I want to authenticate a user who is signing in with the email and the password.
This login function is the one that is going to be called
when I type in my email and password in
the login dialog that I pop up and then
click on the submit button or the login button here,
this login function is going to be called and
the user information but I retrieve from the login component is passed in here.
So when it comes here,
I'm going to use this afAuth as you see I just injected it into the constructor,
and this supplies this Auth object here,
which supplies this method called "sign-in with email and password".
So this signing in with email and password takes two parameters here as you would
expect the user's username or the email and the password here.
So these two piece of information I am supplying
it as the two parameters to this sign-in with email and password.
So, when you click on that you'll see that it
says the first one should be email and the second one should be password.
Now the way I have set it up,
this user object that is coming in contains the email in the
user.username here and the password in the password property of the user object.
So, when that is obtained,
then I will post this information and then so when this is completed successfully,
that means that the user is logged in properly,
if there is an error,
then you catch the error here right now I am
not doing anything specifically with the error you may
wish to print out this error message to indicate that the user cannot log in and so on.
So, I haven't implemented that part of the deal here,
I'm just leaving it right there if you want to console log
this information you can do that when errors occur.
Now for sign out, in Firebase.
Again we take the help of the afAuth which we have injected and Auth on it,
and this provides this method called "sign out",
which when called will sign out the currently logged in
user and so that is one way of handling this.
Now, you must be wondering how I handle the Google login part.
Now this is also handled with the afAuth so the AngularFire2 module that I'm using,
supplies this information for this methods for us through
the Firebase module which is also used in AngularFire2,
and so this supplies this method called sign-in with pop and when
we do sign-in with pop-up here notice what I am specifying here.
So, I am saying "new firebase.auth.GoogleAuthProvider".
Now, you can also do firebase.auth.FacebookAuthProvider and other ones.
So, as you saw from the previous exercise,
Firebase allows you to do third-party login using either Google,
Facebook, GitHub and Twitter.
So you can configure these appropriately,
since I have turned on only Google authorization.
So this is how I will set it up to use
my Google authorization here and this single line of code that I enclosed here,
is the one that causes the pop-up of the browser which suggests to me to authorize
my Firebase to use Google authorization using my Google account here.
So that's the second part that I've set up here.
So notice that the Auth service has significantly
simplified compared to what we did with the previous version of this application.
So you can compare the two versions to see how this is different from the other one.
Now, not only that this afAuth that we have injected here,
AngularFireAuth part that we have injected here,
also provides this observable called "AuthState".
This AuthState observable, can be subscribed to and this "AuthState" observable,
as you see here,
which I have declared here as an observable Firebase.user.
So that is the information that is applied here and also we can setup
another variable here called current user which is of the type Firebase user here.
So, this afAuthState is an observable which
I can subscribe to and whenever this AuthState changes,
the AuthState keeps track of the authentication state of the user
whether the user is logged in or logged out and if the user is logged in,
then this will then subscribe will return me the user information and from
the user information we can retrieve a lot of information including the display name,
the email, the profile ID and then the
avatar image for the user if it has been set up for the specific accounts.
All these will be supplied to us automatically by the user.
So, when you click on "user" and then dot,
you will see that it provides all these information for us.
So it's a display name email,
whether the email is verified or not and so on.
So some of the things that are specific interest to us.
Photo URL which can be used to retrieve the avatar information for the user,
provider ID which specifies who is
providing this information for you this would be either Facebook ID,
Google ID and GitHub ID and so on and additional information even the refresh token.
So you see a bunch of information being
made available to you through the user object that is
returned by this Authstate when you subscribe to it
and also let me draw your attention to the UID the user ID,
and this is what can be used to index the user in our application.
So that is the authentication service the way I have set
it up to use Firebase authentication in this application.
So, two changes that I have reflected to you to show
how my services are modified to use Firebase.
Much of the updates that I have done to my Angular application are all
in the services in order to make use of Firebase installed.
So, because of the baby structured of Angular application,
the components were simply depending on the services and
the services were the ones that we're talking to the back-end.
So, much of the updates that I have done to
my Angular application involve just updating these services to
use Google's Firebase back-end as a service with the two npm modules,
Firebase and AngularFireAuth here.
So, you would see that much of the updates is restricted to
all these services that I have in the services folder of my Angular application.
Of course, I needed to do a little bit of
minimal adjustments into the dishdetail component
and the header component in order to make it work with Firebase.
You can pay a quick visit to the headercomponent.ts,
the headercomponent.html and the dishdetailcomponent.tsfile to see how the code
has changed between the previous version
and the current version of the Angular application,
the previous version, I mean the version that we used for
communicating with our X plus plus
Mongo DB server which we used in the previous exercise.
Now, one more place where you would see me making modifications,
Interestingly, is in the favorite service.
In the favorite service,
the way I stored the favorites of the user,
is that the favorites is a collection on
my server site and the favorite itself contains documents.
Each document contains the user ID and the dish ID.
So, a particular user could have
multiple documents each of them storing the user ID and the dish ID.
So, a collection of them together will define all the favorites for a particular user.
I found that this is a better way of organizing this data in Firebase.
In our MongoDB plus mongos,
you saw that I had embedded in array of dish IDs into
the favorites document and then define the favorite schema that way.
Here, I am using
one separate document for tracking each of the favorites for each of the users.
Now, because Firebase supports querying, so,
I can query my Firebase and extract all the documents that have the same user IDs,
which matches the user that is currently logged in and then
extract the corresponding dish IDs from the favorites.
Then I will go and then query my server
and obtain the dish information for each of those dishes.
So, it involves multiple trips to the server in order to obtain
all my favorite dishes information before I can render my list of favorites.
But, that is the best way that I could get Firebase to work with my Angular application.
Maybe, at a future date,
Firebase Cloud Firestone might extend to
allow something like populate that we did with mongos.
In which case, I will be updating the code to use that way
of obtaining all the dish information automatically.
So, the burden of constructing this compound document will be shifted to the server site.
Right now, my client is doing much of the work here.
Now, when you go in here,
you will see that in the GetFavorites method,
you will see how I am accessing my favorites here.
So, when I do "Getfavorites" I am querying
this collection of favorites but notice that here,
I say "ref where is this user ID".
This user ID I obtain here.
So, in the constructor of my favorite server,
I am subscribing to this Auth service the Get Auth state in the Auth service.
So, in the Auth service if you go in,
you will see this method called Get Auth state here.
The Get Auth state returns the this.AuthState,
which I have defined right there.
So, this will be an observable as you see me declaring here.
So, that observable is the one that I'm going
to use within my favorite service and then subscribe to that.
So, anytime the user information changes this will be automatically reflected in here.
So, you saw that even in the earlier application I had used an observable,
in order to reflect the user information into my header component.
Similar kind of approach,
that I'm using in my favorites component here,
to get hold of the user ID for the currently logged in user.
So, when I query My Favorites collection,
I will query and extract only those documents where the user matches this.
Then I'm only using the value changes here.
So, I'm only extracting all the documents,
that I don't care about the ID of the favorites document itself at this moment.
So, I'm just extracting all of them and using them.
If the user is not logged in and as you can see
I'm throwing an error here with the observable saying,
"no user logged in" that is what is displayed in my favorite speech there.
Now, the isFavorites is also updated here
but in the isFavorites what I'm doing is I'm going to the DB.
Now here, I will access the database by saying,
"DB is equal to firebase.firestore".
Recall that I am importing Firebase here,
import star as Firebase here.
The Angular Firestore itself doesn't provide me with a method of
doing multiple compound queries here.
The Angular Firestore or the Angular fire to doesn't provide me with doing that.
So, that is why I have to resort to using Firebase Firestore.
So, when I when I say Firebase Firestore,
this gives me a reference to the Firestore database and then I can go into this database
and then say "DB collection favorites" and then I can do multiple queries here.
So,I am saying,.where user is this.wheredish is the dish ID.
So, if I want to obtain a specific favorite.
To check if a specific dish is the favorite of a user I obtain
that particular document where the user and the dish match these two,
if they don't match then it'll return with an empty.
So, that I extract and then return this value here.
Now, then I post favorites,
you see how I'm doing this I'm saying this AFS collection favorites and I'll say "add".
Look at the document that I am storing in my favorites.
The document itself contains the user ID and the dish ID.
So, these two pieces of information enclosed in here and if
not then it will reject the promise with no user logged in here.
Similarly, for the delete favorite that I've implemented here.
Spend some time again going through this code to understand how I have
leveraged Firebase and Angular fire to npm modules in
order to communicate with my Firebase server that I have set up in the previous exercise.
With this, I have given you a quick overview of
how you can set up your Angular application to interact with
Firebase back-end as a service and then be able
to support various operations that you have within your Angular application.
As I've demonstrated earlier,
this Angular application looks exactly like
the previous version of the Angular application where we were
using our own version of our Express MongoDB server.
Now, with this I complete this particular exercise where I have illustrated in
this lesson about back-end as a service and also demonstrated
Firebase as an example of a back-end as a service.