1
00:00:03,950 --> 00:00:06,525
In the previous exercise,

2
00:00:06,525 --> 00:00:09,990
we had already configured our Firebase backend as

3
00:00:09,990 --> 00:00:15,120
a service with the new project and also set up a lot of

4
00:00:15,120 --> 00:00:19,620
the data into our database and then set up our storage and

5
00:00:19,620 --> 00:00:25,120
configured our Firebase Server to act as the backend for our Angular application.

6
00:00:25,120 --> 00:00:29,160
In this exercise, we're going to look at a modified version of

7
00:00:29,160 --> 00:00:33,480
our Angular application which makes use of the Firebase backend as

8
00:00:33,480 --> 00:00:37,500
a service in order to obtain the data and

9
00:00:37,500 --> 00:00:41,915
also store information for users on the servers.

10
00:00:41,915 --> 00:00:44,480
Also, we will take advantage of

11
00:00:44,480 --> 00:00:48,455
the authentication support that Firebase provides to authenticate users

12
00:00:48,455 --> 00:00:56,295
both using an email and password approach and also using a Google account.

13
00:00:56,295 --> 00:00:59,775
To get started on this exercise,

14
00:00:59,775 --> 00:01:02,750
go to a convenient location on your computer and

15
00:01:02,750 --> 00:01:07,190
then clone the given Git repository where I

16
00:01:07,190 --> 00:01:14,775
have provided you with the Angular Firebase version of our Angular application.

17
00:01:14,775 --> 00:01:17,490
So type, git clone

18
00:01:17,490 --> 00:01:27,470
https://github.com/jmuppala/confusion-Angular6-Firebase.git

19
00:01:27,470 --> 00:01:28,670
and then clone

20
00:01:28,670 --> 00:01:34,835
the Git repository and once the Git repository is cloned to your computer,

21
00:01:34,835 --> 00:01:43,355
then move into the confusion Angular Firebase

22
00:01:43,355 --> 00:01:47,570
folder that will get created at this point and

23
00:01:47,570 --> 00:01:52,110
then you would notice that a bunch of files are already installed there.

24
00:01:52,110 --> 00:01:56,015
Let's go ahead and do an npm install to install

25
00:01:56,015 --> 00:02:01,890
all the node modules on which this Angular application is dependent upon.

26
00:02:01,890 --> 00:02:04,520
This version will also install

27
00:02:04,520 --> 00:02:10,010
two additional node modules called Firebase and then Angular fire two.

28
00:02:10,010 --> 00:02:15,525
I will explain a bit more about these two node modules later on in this exercise.

29
00:02:15,525 --> 00:02:18,915
Once the project installation is complete,

30
00:02:18,915 --> 00:02:23,360
open the project in an editor and then in the project,

31
00:02:23,360 --> 00:02:27,830
go into the source environments folder and

32
00:02:27,830 --> 00:02:32,420
then open environment.ts file and in the environment.ts file,

33
00:02:32,420 --> 00:02:36,980
you will see a set of Firebase configuration that you

34
00:02:36,980 --> 00:02:42,130
need to set up with your own Firebase server configuration.

35
00:02:42,130 --> 00:02:45,105
As we have seen in the previous exercise,

36
00:02:45,105 --> 00:02:48,950
we can obtain all this information when we click on

37
00:02:48,950 --> 00:02:53,150
this button here called "Add Firebase to your web app" and then

38
00:02:53,150 --> 00:02:56,809
copy this information and then paste this information

39
00:02:56,809 --> 00:03:01,835
into your environment.ts file to replace

40
00:03:01,835 --> 00:03:06,500
these with your specific Firebase servers configuration

41
00:03:06,500 --> 00:03:10,940
for all this piece of information and once that is completed,

42
00:03:10,940 --> 00:03:17,390
then you can start up your Angular application by typing "ng serve" at the prompt.

43
00:03:17,390 --> 00:03:21,735
Once your Angular application is compiled with "ng serve",

44
00:03:21,735 --> 00:03:29,905
then go to a browser and then type localhost:4200 to load in

45
00:03:29,905 --> 00:03:34,850
your Angular application and you will notice that your Angular application is compiled

46
00:03:34,850 --> 00:03:40,215
and then loaded into your browser just like before.

47
00:03:40,215 --> 00:03:43,190
So, once your Angular application is up and running,

48
00:03:43,190 --> 00:03:47,585
you will notice that this version of Angular application is going to be making use of

49
00:03:47,585 --> 00:03:51,260
the Firebase server that you have set up in

50
00:03:51,260 --> 00:03:55,625
the previous exercise and so here you would see the "Home" page,

51
00:03:55,625 --> 00:04:00,030
the "About" page as we see here and the

52
00:04:00,030 --> 00:04:09,615
"Menu" and the "Contact" page and obviously since we are not currently logged in,

53
00:04:09,615 --> 00:04:14,975
the "My Favorites" page will display an error saying no user is logged in.

54
00:04:14,975 --> 00:04:17,210
So, let's login ourselves.

55
00:04:17,210 --> 00:04:20,760
Let me go back to the "Homepage" and then we'll login ourselves.

56
00:04:20,760 --> 00:04:22,475
So, when you click on the login button,

57
00:04:22,475 --> 00:04:27,195
you will see the typical form here with the email and the password information.

58
00:04:27,195 --> 00:04:30,715
You will also see an additional button here called "Login with Google".

59
00:04:30,715 --> 00:04:33,600
So let me log in with my Google account.

60
00:04:33,600 --> 00:04:35,750
So, when you click on the "Login with Google",

61
00:04:35,750 --> 00:04:41,180
then it will open another browser window where you will be asked to

62
00:04:41,180 --> 00:04:47,420
authorize for using your Google account by this Firebase server.

63
00:04:47,420 --> 00:04:49,475
So, let me go ahead and authorize

64
00:04:49,475 --> 00:04:53,845
this application and then once the authorization is completed,

65
00:04:53,845 --> 00:04:57,145
then you will see that your Firebase

66
00:04:57,145 --> 00:05:01,850
based Angular application will start up and on the right hand corner,

67
00:05:01,850 --> 00:05:06,200
you will immediately see your name being

68
00:05:06,200 --> 00:05:11,525
displayed here and with the "Login" button now turned into a "Logout" button.

69
00:05:11,525 --> 00:05:14,755
So, at this point,

70
00:05:14,755 --> 00:05:17,530
you should be able to see your favorites

71
00:05:17,530 --> 00:05:20,310
and in this case since we don't have any favorites,

72
00:05:20,310 --> 00:05:22,155
so it'll be empty at this point.

73
00:05:22,155 --> 00:05:27,830
Let me go back to the "Menu" and then add a couple of items into "My Favorites".

74
00:05:27,830 --> 00:05:32,235
So, I'll add this dish to my favorites.

75
00:05:32,235 --> 00:05:34,045
So, when I click on this dish,

76
00:05:34,045 --> 00:05:41,110
you will immediately see the icon turn into a filled heart and let me also select

77
00:05:41,110 --> 00:05:44,350
one more dish and add it into "My

78
00:05:44,350 --> 00:05:49,650
Favorites" and then now when you go to the "My Favorites",

79
00:05:49,650 --> 00:05:52,510
you will see the couple of dishes added into

80
00:05:52,510 --> 00:05:56,330
your favorites as you would expect and again,

81
00:05:56,330 --> 00:06:02,540
you can delete the dishes by clicking on the "Delete" toggle up here and then click on

82
00:06:02,540 --> 00:06:09,695
the cross to remove the item from your list of favorites as shown here.

83
00:06:09,695 --> 00:06:13,570
Now, we can also add as you realized,

84
00:06:13,570 --> 00:06:17,660
we can go to any dish and then add comments about that dish.

85
00:06:17,660 --> 00:06:19,190
So, let me add in a comment

86
00:06:19,190 --> 00:06:28,260
here and the moment you submit the comment,

87
00:06:28,260 --> 00:06:32,435
you will immediately see that your comments will be displayed here with

88
00:06:32,435 --> 00:06:41,825
the comment author's name also included in here and with the date as shown here.

89
00:06:41,825 --> 00:06:45,890
So, you can see that the user's submission

90
00:06:45,890 --> 00:06:49,955
of comments will be supported for any specific dish.

91
00:06:49,955 --> 00:06:55,805
Let me add in one more favorite and so this user will have a couple of favorites.

92
00:06:55,805 --> 00:06:58,180
Let me "Logout" this user.

93
00:06:58,180 --> 00:07:02,930
Go back to the "Homepage" and then "Logout" this user.

94
00:07:02,930 --> 00:07:07,715
Now we will login using the other account.

95
00:07:07,715 --> 00:07:13,490
So, I would- I had set up

96
00:07:13,490 --> 00:07:17,840
this email password account earlier and so we will

97
00:07:17,840 --> 00:07:22,865
login as this other user and once the other user is logged in,

98
00:07:22,865 --> 00:07:29,045
let me again go to the "Menu" and add a couple of items into

99
00:07:29,045 --> 00:07:36,904
the favorites for this particular user

100
00:07:36,904 --> 00:07:40,700
and so when you go back to "My Favorites",

101
00:07:40,700 --> 00:07:44,270
you will see these items listed for the second user.

102
00:07:44,270 --> 00:07:46,775
Now, similarly for this user,

103
00:07:46,775 --> 00:07:51,560
let me again submit another comment by this user.

104
00:07:51,560 --> 00:07:53,150
So-

105
00:08:01,000 --> 00:08:02,600
and you would

106
00:08:02,600 --> 00:08:07,445
see that the comments submitted by the second user is also added into the application.

107
00:08:07,445 --> 00:08:11,615
So, this is how your Angular application works

108
00:08:11,615 --> 00:08:16,490
with the Firebase as the backend as a service.

109
00:08:16,490 --> 00:08:18,529
Now of course you must be wondering,

110
00:08:18,529 --> 00:08:24,170
how do we redesign our Angular application to make use of Firebase instead

111
00:08:24,170 --> 00:08:31,610
of using the Standard Express plus MongoDB server that we have built earlier?

112
00:08:31,610 --> 00:08:38,440
In order to configure your Angular application to communicate with the Firebase Server,

113
00:08:38,440 --> 00:08:42,620
there are two node modules that you need to install into

114
00:08:42,620 --> 00:08:46,860
your Angular application and one of them is the Firebase module.

115
00:08:46,860 --> 00:08:49,730
The Firebase module as you see here,

116
00:08:49,730 --> 00:08:55,190
provides the tools and infrastructure that enables you to communicate

117
00:08:55,190 --> 00:09:01,610
with the Firebase server and to install this into your application,

118
00:09:01,610 --> 00:09:05,720
you type, npm install minus minus save Firebase.

119
00:09:05,720 --> 00:09:07,610
Now along with this,

120
00:09:07,610 --> 00:09:11,395
there is another module called the Angular Fire 2.

121
00:09:11,395 --> 00:09:13,725
So the Angular Fire 2.

122
00:09:13,725 --> 00:09:20,535
Also, again I have provided the links to these two modules in the additional resources.

123
00:09:20,535 --> 00:09:23,795
The AngularFire 2 is the official library

124
00:09:23,795 --> 00:09:27,290
for Firebase and Angular support and as you can see,

125
00:09:27,290 --> 00:09:31,520
it's an observable based support for Angular files.

126
00:09:31,520 --> 00:09:36,545
So, this works to add to the Firebase npm module and then

127
00:09:36,545 --> 00:09:42,125
gives you observable based interface that we can use in your Angular application.

128
00:09:42,125 --> 00:09:44,930
So, we would be leveraging the AngularFire 2.

129
00:09:44,930 --> 00:09:46,994
So, to make use of AngularFire2,

130
00:09:46,994 --> 00:09:49,940
you need to install both Firebase as well as AngularFire 2.

131
00:09:49,940 --> 00:09:51,345
So, in one shot,

132
00:09:51,345 --> 00:09:54,205
install both these into your Angular application.

133
00:09:54,205 --> 00:09:59,320
Now, the version of the Angular application that I have provided for you automatically

134
00:09:59,320 --> 00:10:06,250
installs both these as you will see when you examine the package.json file.

135
00:10:06,250 --> 00:10:08,510
Now, how to make use of these two,

136
00:10:08,510 --> 00:10:12,245
I will illustrate that by quickly running you through

137
00:10:12,245 --> 00:10:17,280
the modified code for the services and a couple of components where we

138
00:10:17,280 --> 00:10:19,955
make use of Firebase and AngularFire2

139
00:10:19,955 --> 00:10:23,135
to modify the Angular application that we have developed

140
00:10:23,135 --> 00:10:30,140
earlier to make use of the Firebase server as the backend as a service.

141
00:10:30,140 --> 00:10:34,075
In order to understand more about how we

142
00:10:34,075 --> 00:10:39,185
leverage Firebase and AngularFire 2 within our Angular application,

143
00:10:39,185 --> 00:10:42,860
our first stop is at the package.json file.

144
00:10:42,860 --> 00:10:45,025
So in the package.json file,

145
00:10:45,025 --> 00:10:50,850
you will notice that I have installed AngularFire2 here and also we have installed

146
00:10:50,850 --> 00:10:57,510
Firebase to use in this version of the Angular application that I supply for you.

147
00:10:57,510 --> 00:11:01,980
So, note that these two will automatically be installed when you type "npm

148
00:11:01,980 --> 00:11:07,720
install" after cloning this git repository that I have provided for you.

149
00:11:07,720 --> 00:11:11,220
If you were starting with a new Angular application,

150
00:11:11,220 --> 00:11:15,590
then you should be installing both AngularFire 2 as well as Firebase in

151
00:11:15,590 --> 00:11:20,184
order to leverage the use of Firebase as the backend as a service.

152
00:11:20,184 --> 00:11:22,365
Now having installed these two,

153
00:11:22,365 --> 00:11:27,360
let's learn how we make use of these within our services.

154
00:11:27,360 --> 00:11:30,030
So, the best way to learn how to make use of both of

155
00:11:30,030 --> 00:11:33,640
these is to visit some of the services that we have

156
00:11:33,640 --> 00:11:36,930
configured in our application and understand how we

157
00:11:36,930 --> 00:11:42,130
leverage the use of AngularFire2 and Firebase.

158
00:11:42,130 --> 00:11:46,235
So, we'll start with dish.service.ts file.

159
00:11:46,235 --> 00:11:48,830
So, if you go to dish.service.ts file,

160
00:11:48,830 --> 00:11:51,095
you will notice that here,

161
00:11:51,095 --> 00:11:55,235
in this dish service,

162
00:11:55,235 --> 00:12:01,190
you will see me importing this AngularFireStore, AngularFireStoreDocument,

163
00:12:01,190 --> 00:12:08,115
and AngularFireStoreCollection from AngularFire to Firestore here.

164
00:12:08,115 --> 00:12:16,680
So, that brings in whatever I need from my AngularFireStore npm module,

165
00:12:16,680 --> 00:12:21,010
also you will notice that I am importing everything from

166
00:12:21,010 --> 00:12:27,615
Firebase/app as Firebase into my dish service here.

167
00:12:27,615 --> 00:12:29,945
So, once we have imported these two,

168
00:12:29,945 --> 00:12:35,415
let's take a quick look at how we reconfigure our dish service here.

169
00:12:35,415 --> 00:12:37,435
So, if you go into the dish service,

170
00:12:37,435 --> 00:12:41,175
you will notice that I am no longer using HTTP client.

171
00:12:41,175 --> 00:12:48,975
Instead, I am injecting AFS which is the AngularFireStore into the constructor here.

172
00:12:48,975 --> 00:12:51,520
The AngularFireStore is the one that gives me

173
00:12:51,520 --> 00:12:55,815
access to the Firebase backend as a service.

174
00:12:55,815 --> 00:13:01,785
Now, also recall that we have already configured all the details of

175
00:13:01,785 --> 00:13:09,450
our server and also the filestore project in the environment.ts file earlier.

176
00:13:09,450 --> 00:13:12,595
So, you should have configured this information already there

177
00:13:12,595 --> 00:13:16,180
on how your Angular application should be leveraging

178
00:13:16,180 --> 00:13:20,930
your Firestore based project on

179
00:13:20,930 --> 00:13:27,710
your Firestore server to access the data that you have configured there.

180
00:13:27,710 --> 00:13:32,290
So, this will give me access to my cloud

181
00:13:32,290 --> 00:13:39,400
Firestore within my Firebase project that I have set up.

182
00:13:39,400 --> 00:13:43,410
Now, the AuthService is of course the same Authservice that we have used before,

183
00:13:43,410 --> 00:13:51,175
but it has modified to make use of Angular support for Firebase.

184
00:13:51,175 --> 00:13:55,095
We'll visit the AuthService to learn how it has been updated.

185
00:13:55,095 --> 00:14:00,410
Now, the AuthService will give us access to

186
00:14:00,410 --> 00:14:06,345
this method called getAuthState which will return in an observable.

187
00:14:06,345 --> 00:14:08,965
This observable, when we subscribe to it,

188
00:14:08,965 --> 00:14:15,855
will give us the information as a user which contains the user's information.

189
00:14:15,855 --> 00:14:21,465
So, I will obtain that and then set up the currentUser in my application

190
00:14:21,465 --> 00:14:28,995
as the user returned by this observable here.

191
00:14:28,995 --> 00:14:30,699
So, when we visit AuthService,

192
00:14:30,699 --> 00:14:33,085
we will learn what this getAuthState will return for

193
00:14:33,085 --> 00:14:35,700
us and so the currentUser's information can

194
00:14:35,700 --> 00:14:36,940
be obtained from any of

195
00:14:36,940 --> 00:14:41,165
the other services because we are already injecting AuthService in here.

196
00:14:41,165 --> 00:14:45,570
Now, let's take a look at how getDishes method is implemented here.

197
00:14:45,570 --> 00:14:47,710
Now, earlier in the getDishes method,

198
00:14:47,710 --> 00:14:55,920
we were using the HTTP client to access the server at base URL+/dishes.

199
00:14:55,920 --> 00:14:57,425
Now in this case,

200
00:14:57,425 --> 00:15:07,255
to access a collection in my Firebase server, we'll say this.afs.

201
00:15:07,255 --> 00:15:10,710
So, this is what AngularFire2 provides for us.

202
00:15:10,710 --> 00:15:16,345
AFS as you see is the AngularFireStore that we have injected here and so we say

203
00:15:16,345 --> 00:15:19,810
this.afs.collection and here we

204
00:15:19,810 --> 00:15:23,010
will specify the specific collection that we are accessing here.

205
00:15:23,010 --> 00:15:26,315
Recall that we had set up the dishes, the promotions,

206
00:15:26,315 --> 00:15:30,415
and the leaders collections on my Firebase server.

207
00:15:30,415 --> 00:15:34,065
So, this directly gives me access

208
00:15:34,065 --> 00:15:38,595
to my dishes collection here and from the dishes collection,

209
00:15:38,595 --> 00:15:42,740
I can either do.valueChanges which

210
00:15:42,740 --> 00:15:47,115
will return all the information in the business collection for me,

211
00:15:47,115 --> 00:15:50,440
or I can do.snapshotChanges which will

212
00:15:50,440 --> 00:15:53,990
return additional information including the ID of the dishes.

213
00:15:53,990 --> 00:15:56,660
So, if instead of doing snapshotChanges,

214
00:15:56,660 --> 00:15:59,310
if I say valueChanges,

215
00:15:59,310 --> 00:16:03,110
it will return only the dish information but it will not return

216
00:16:03,110 --> 00:16:07,890
the IDs of the dishes but since I will need the IDs of my dishes,

217
00:16:07,890 --> 00:16:13,335
so that's why I'm using the.snapshotChanges in this case.

218
00:16:13,335 --> 00:16:16,090
So, when.snapshotChanges is called,

219
00:16:16,090 --> 00:16:19,505
this will return as you see an observable which

220
00:16:19,505 --> 00:16:27,195
I map and so the return value which is called as actions and these actions,

221
00:16:27,195 --> 00:16:31,800
again, will be an observable which I will map each action in

222
00:16:31,800 --> 00:16:38,930
this actions and then extract the data from the action that is returned here.

223
00:16:38,930 --> 00:16:44,525
So the action is a value that is returned from for each of the actions

224
00:16:44,525 --> 00:16:50,765
and this action contains a payload and contains inside that a dark field here.

225
00:16:50,765 --> 00:16:53,200
Now, this is something that I have figured out by reading

226
00:16:53,200 --> 00:16:57,010
the documentation for AngularFire2 and

227
00:16:57,010 --> 00:17:03,705
so when we call this data function on this action.payload.doc,

228
00:17:03,705 --> 00:17:05,875
this will give me the data.

229
00:17:05,875 --> 00:17:09,510
The data for that specific dish that is

230
00:17:09,510 --> 00:17:14,160
obtained from my dishes collection on the server side.

231
00:17:14,160 --> 00:17:18,760
So each document in there will be returned here and

232
00:17:18,760 --> 00:17:24,205
then I obtain the ID for that by saying action.payload.doc.id.

233
00:17:24,205 --> 00:17:27,855
So that's where the ID of that will be

234
00:17:27,855 --> 00:17:32,030
carried and then I will join the two together and return

235
00:17:32,030 --> 00:17:40,035
this as a dish document back to my various components from there,

236
00:17:40,035 --> 00:17:42,150
I will call this getDishes method.

237
00:17:42,150 --> 00:17:43,345
So, as you recall,

238
00:17:43,345 --> 00:17:44,690
from the menu component,

239
00:17:44,690 --> 00:17:47,400
I am calling the getDishes method in order to obtain

240
00:17:47,400 --> 00:17:51,090
the information about all the dishes in my collection.

241
00:17:51,090 --> 00:17:58,505
Collection. So, each of these dish that is returned as a doc will be reconstructed into

242
00:17:58,505 --> 00:18:03,420
a JavaScript object with the ID inserted here and also

243
00:18:03,420 --> 00:18:09,540
the data that is extracted from this action payload.doc.data.

244
00:18:09,540 --> 00:18:16,455
Now this is something that you learn by reading the documentation of AngularFire2.

245
00:18:16,455 --> 00:18:19,470
Now, since I have already done that part,

246
00:18:19,470 --> 00:18:22,755
I'm showing you the exact code that you are supposed to

247
00:18:22,755 --> 00:18:26,160
use in order to extract the data and then supply

248
00:18:26,160 --> 00:18:33,500
this data back to your component that is going to call the getDishes method here.

249
00:18:33,500 --> 00:18:37,090
So, by doing this for each one of the documents there,

250
00:18:37,090 --> 00:18:39,180
this document will be reconstructed to

251
00:18:39,180 --> 00:18:44,800
the dish object that we

252
00:18:44,800 --> 00:18:51,500
use in our Angular application and so we are able to even get access to the ID.

253
00:18:51,500 --> 00:18:53,365
If you just do value changes,

254
00:18:53,365 --> 00:18:59,825
it'll simply return all the documents themselves but without the IDs of the documents.

255
00:18:59,825 --> 00:19:04,920
So, this additional work needs to be done within your service in order to

256
00:19:04,920 --> 00:19:07,835
return the information in the right way so

257
00:19:07,835 --> 00:19:10,865
that myComponents can make use of this information.

258
00:19:10,865 --> 00:19:13,370
Similarly, for a getDish method,

259
00:19:13,370 --> 00:19:17,695
so notice how I am accessing the information for a specific dish.

260
00:19:17,695 --> 00:19:22,020
Again, we'll say this.afs and then you'll notice that I'm

261
00:19:22,020 --> 00:19:26,660
saying.doc and then in here for the.doc method,

262
00:19:26,660 --> 00:19:32,650
I supply dishes slash and then the ID of the specific dish.

263
00:19:32,650 --> 00:19:35,150
Now, the reason why I had supplied ID,

264
00:19:35,150 --> 00:19:39,350
the ID here is coming in as the parameter for the getDish method here.

265
00:19:39,350 --> 00:19:41,985
Now, in order for this ID to be supplied,

266
00:19:41,985 --> 00:19:44,450
I need to be able to supply that ID in

267
00:19:44,450 --> 00:19:47,480
the getDishes method so when my menu is constructed,

268
00:19:47,480 --> 00:19:51,205
every dish will have its ID attached to it there.

269
00:19:51,205 --> 00:19:56,575
That ID is passed in here and so I will be accessing the document at this point.

270
00:19:56,575 --> 00:20:01,260
So, the AngularFire2 allows you to access

271
00:20:01,260 --> 00:20:07,125
a specific document which is inside a collection by saying the collection name slash,

272
00:20:07,125 --> 00:20:15,430
plus the document ID or you can say this.afs.collection dishes just like you did hear,

273
00:20:15,430 --> 00:20:22,540
collection dishes and then.doc and then supply doc and ID inside brackets there.

274
00:20:22,540 --> 00:20:26,725
So, that's another way of addressing a specific dish.

275
00:20:26,725 --> 00:20:32,680
Again, I am subscribing to snapshotChanges and this will return an action which is then

276
00:20:32,680 --> 00:20:35,480
mapped again in the same format to

277
00:20:35,480 --> 00:20:39,495
construct the dish object here together with the ID here.

278
00:20:39,495 --> 00:20:42,410
Now, Firebase keeps the ID separate from the document

279
00:20:42,410 --> 00:20:46,300
itself and so that's why I have to explicitly do

280
00:20:46,300 --> 00:20:49,010
this reconstruction in order to obtain

281
00:20:49,010 --> 00:20:54,750
the dish document in a way that is usable by myComponents.

282
00:20:54,750 --> 00:20:59,660
Then I constructed my own server using Express and MongoDB,

283
00:20:59,660 --> 00:21:03,995
the ID automatically was there in the document itself and so it was very

284
00:21:03,995 --> 00:21:09,235
easy to retrieve that and supply it back to the client side.

285
00:21:09,235 --> 00:21:13,610
Now, for the getFeaturedDish,

286
00:21:13,610 --> 00:21:15,620
recall that for the getFeaturedDish,

287
00:21:15,620 --> 00:21:20,870
we are looking for those dishes where the feature is set to true.

288
00:21:20,870 --> 00:21:25,790
Now, this is where the AngularFire2 allows us to

289
00:21:25,790 --> 00:21:31,180
construct a query and supply that query here for that collection.

290
00:21:31,180 --> 00:21:36,440
Here I am saying this.afs collection dishes here,

291
00:21:36,440 --> 00:21:39,520
so I'm still using the collection but then look at

292
00:21:39,520 --> 00:21:43,140
the second parameter for this call here.

293
00:21:43,140 --> 00:21:49,405
This says ref where the ref refers to each document that is in this collection.

294
00:21:49,405 --> 00:21:53,330
This ref says the ref and this is where I can

295
00:21:53,330 --> 00:21:58,100
use this query set up hears so which says.where.

296
00:21:58,100 --> 00:22:04,695
So, meaning that each one of the documents where the featured,

297
00:22:04,695 --> 00:22:10,445
as you can see, the syntax is fairly easy to follow here which says where featured.

298
00:22:10,445 --> 00:22:15,240
Now, notice that feature is supplied as a string here,

299
00:22:15,240 --> 00:22:17,175
and then the next one,

300
00:22:17,175 --> 00:22:22,230
the operator is equal to so you can even say greater than, less than,

301
00:22:22,230 --> 00:22:25,345
greater than or equal to less than or equal to any one of these things,

302
00:22:25,345 --> 00:22:30,375
but notice that that should be inside quotations here and then you will say true.

303
00:22:30,375 --> 00:22:35,105
So, wherever the featured property of the document is set to true,

304
00:22:35,105 --> 00:22:36,620
extract all of those.

305
00:22:36,620 --> 00:22:40,545
So, this query will extract only those documents

306
00:22:40,545 --> 00:22:45,250
from the dishes collection where feature is set to true,

307
00:22:45,250 --> 00:22:50,195
and then return only those documents from that collection here,

308
00:22:50,195 --> 00:22:53,770
and from there I'm going snapshot changes and this will

309
00:22:53,770 --> 00:22:59,350
return an array of documents and from there I will map them

310
00:22:59,350 --> 00:23:04,270
into individual dish documents and then since I have

311
00:23:04,270 --> 00:23:09,700
ensured that only one of those documents will have the feature set to true.

312
00:23:09,700 --> 00:23:13,030
So, it'll return only one of them but it'll return it as an array.

313
00:23:13,030 --> 00:23:14,980
So, that's why I'm constructing this

314
00:23:14,980 --> 00:23:20,195
with square bracket zero the first element of the array,

315
00:23:20,195 --> 00:23:25,210
and indeed it will contain only one element because only one element in my collection

316
00:23:25,210 --> 00:23:30,745
will match this particular query that I have set up here with the wave here.

317
00:23:30,745 --> 00:23:36,470
There are other query setups here you can also use something called order by.

318
00:23:36,470 --> 00:23:41,000
So, you can order the collection by a certain property,

319
00:23:41,000 --> 00:23:47,310
and some other set of querying options that are available.

320
00:23:47,310 --> 00:23:51,480
Now, this is supported by Firebase on its cloud Firestore,

321
00:23:51,480 --> 00:23:56,890
and that is what we can leverage using AngularFire2 to design

322
00:23:56,890 --> 00:24:03,850
the code in your Angular application to do the query from the client side itself.

323
00:24:03,850 --> 00:24:09,280
So, this is going to return the specific feature dish.

324
00:24:09,360 --> 00:24:15,355
Now, again getDishId is going to be similar to what we have done earlier.

325
00:24:15,355 --> 00:24:16,890
So, no modification there.

326
00:24:16,890 --> 00:24:21,370
Now, for the postComment again

327
00:24:21,370 --> 00:24:27,820
because Firebase with the cloud Firestore beta,

328
00:24:27,820 --> 00:24:31,720
doesn't have the concept of population,

329
00:24:31,720 --> 00:24:34,015
and so on that we have seen earlier.

330
00:24:34,015 --> 00:24:39,890
So, what I'm going to do for the comments is that I'm going to post these comments as

331
00:24:39,890 --> 00:24:46,140
a collection for which is enclosed inside each dish itself.

332
00:24:46,140 --> 00:24:52,040
So, each dish will have its own collection of comments about that specific dish.

333
00:24:52,040 --> 00:24:54,965
When I post the comment I'm going to use the dishId,

334
00:24:54,965 --> 00:24:57,905
and then the comment information.

335
00:24:57,905 --> 00:25:01,735
So, what I do here is that I'm going to first

336
00:25:01,735 --> 00:25:07,175
query the dishes and then obtain that particular dish.

337
00:25:07,175 --> 00:25:11,555
So, you can see that I am using the other way of querying for a specific document.

338
00:25:11,555 --> 00:25:16,070
So, here I'm saying this afs.collection('dishes').doc dishId.

339
00:25:16,440 --> 00:25:22,660
So, I can use this way of accessing a specific document if I want to.

340
00:25:22,660 --> 00:25:25,610
The other way of course you have seen already with

341
00:25:25,610 --> 00:25:33,375
the getDish method where I say doc dishes slash plus ID.

342
00:25:33,375 --> 00:25:38,185
So, two different ways of addressing a specific document inside

343
00:25:38,185 --> 00:25:44,460
a collection here and then dishId and then collection and comments.

344
00:25:44,460 --> 00:25:46,840
So, this this way it's saying in

345
00:25:46,840 --> 00:25:51,100
this collection for this specific document with that dishId,

346
00:25:51,100 --> 00:25:54,140
there is a collection that is included in

347
00:25:54,140 --> 00:25:57,180
this document and that collection has the name comments.

348
00:25:57,180 --> 00:25:59,660
So, this is a nesting of a collection

349
00:25:59,660 --> 00:26:03,125
inside a document which is in another higher level connection.

350
00:26:03,125 --> 00:26:07,110
So, this kind of nesting of collections is allowed by

351
00:26:07,110 --> 00:26:13,590
Firebase Cloud Store Beta up to 100 levels deep if you so wish to choose.

352
00:26:13,590 --> 00:26:15,700
So, inside this collection,

353
00:26:15,700 --> 00:26:17,420
I'm going to add.

354
00:26:17,420 --> 00:26:20,310
So, how do you add a document to a collection?

355
00:26:20,310 --> 00:26:22,105
To add a document to your collection,

356
00:26:22,105 --> 00:26:24,755
you use the add method on a collection here.

357
00:26:24,755 --> 00:26:27,600
So, you can see that on the collection comments,

358
00:26:27,600 --> 00:26:30,380
I'm doing an add here and then

359
00:26:30,380 --> 00:26:33,655
this is the actual document that is going to be added in here.

360
00:26:33,655 --> 00:26:35,280
So, in the document itself,

361
00:26:35,280 --> 00:26:40,645
you'll see that I have the author property here where I have set up the current ID,

362
00:26:40,645 --> 00:26:44,665
and also I set up the first name for the author here,

363
00:26:44,665 --> 00:26:50,885
I only serve the first time here so here I say this current user display name.

364
00:26:50,885 --> 00:26:55,625
If the display name is true then I will set it to this current user display name.

365
00:26:55,625 --> 00:27:00,960
If the user's account doesn't have a display name as attached to it then I will simply

366
00:27:00,960 --> 00:27:06,420
use this current user email as the first name property here.

367
00:27:06,420 --> 00:27:11,035
So, this document which contains the comment,

368
00:27:11,035 --> 00:27:13,150
automatically also carries this first name field

369
00:27:13,150 --> 00:27:16,140
and that is what I'm going to be using to render

370
00:27:16,140 --> 00:27:22,495
the information when I render the comments in my dishDetail component.

371
00:27:22,495 --> 00:27:28,710
So, notice that I am actually duplicating information here in each of the comments.

372
00:27:28,710 --> 00:27:31,865
But that's okay, since these are stored as

373
00:27:31,865 --> 00:27:34,160
Json documents on Firebase it's okay to

374
00:27:34,160 --> 00:27:36,990
duplicate some of the information in the comments here.

375
00:27:36,990 --> 00:27:40,245
But if you want further details of the current user,

376
00:27:40,245 --> 00:27:45,280
you already have a reference to the user's id here so you can actually go and fetch

377
00:27:45,280 --> 00:27:48,150
the document for the particular user and then

378
00:27:48,150 --> 00:27:51,485
obtain further information of the user should you choose to.

379
00:27:51,485 --> 00:27:54,830
Now, when I used Mongo DB plus Mongo's,

380
00:27:54,830 --> 00:27:57,950
you saw that I will just use the current user's ID for

381
00:27:57,950 --> 00:28:01,650
the author and then I will use the populate to populate this information.

382
00:28:01,650 --> 00:28:05,150
Now Cloud Firestore beta at this moment doesn't have

383
00:28:05,150 --> 00:28:10,240
any concept of this populate as far as I can see from the documentation,

384
00:28:10,240 --> 00:28:14,335
maybe a future version might support a way of pulling in

385
00:28:14,335 --> 00:28:16,800
information from another document and

386
00:28:16,800 --> 00:28:19,270
automatically populating it into the current document.

387
00:28:19,270 --> 00:28:24,500
When that happens, then this code will have to be modified to take advantage of that.

388
00:28:24,500 --> 00:28:26,725
But right now as I see it,

389
00:28:26,725 --> 00:28:29,560
Firestore beta doesn't have the ability to

390
00:28:29,560 --> 00:28:33,000
populate information from another document into the current document.

391
00:28:33,000 --> 00:28:36,040
So that's why I'm just replicating only that piece of

392
00:28:36,040 --> 00:28:39,860
information that I really need when I render the comment in

393
00:28:39,860 --> 00:28:43,660
my dishdetail component here and then down below

394
00:28:43,660 --> 00:28:47,945
here you can see that I have the rating and the comment here and then also,

395
00:28:47,945 --> 00:28:49,740
notice that I am creating

396
00:28:49,740 --> 00:28:57,370
these two additional fields in my comment here called "createdAt" and "updatedAt".

397
00:28:57,370 --> 00:29:01,785
Notice how I am putting the timestamp for the "createdAt".

398
00:29:01,785 --> 00:29:05,785
The Firebase, now what is this Firebase I'm using here,

399
00:29:05,785 --> 00:29:12,050
this Firebase is exactly what I imported here as from Firebase app.

400
00:29:12,050 --> 00:29:15,850
So that provides me as you see here down below here,

401
00:29:15,850 --> 00:29:20,395
that provides me with this same Firestore field value.

402
00:29:20,395 --> 00:29:25,260
So this call to the firestorm field values server timestamp,

403
00:29:25,260 --> 00:29:28,390
will return the current timestamp for

404
00:29:28,390 --> 00:29:32,605
me and that is the information that I'm going to be storing in the "createdAt".

405
00:29:32,605 --> 00:29:35,255
Now, when I inserted all the documents here,

406
00:29:35,255 --> 00:29:40,435
you saw that I manually created this "createdAt" field for each of the documents.

407
00:29:40,435 --> 00:29:44,110
Now this is a way of doing the same from within

408
00:29:44,110 --> 00:29:47,895
our Angular code in

409
00:29:47,895 --> 00:29:53,040
our client side and the same thing for the "updatedAt" field that you'll see here.

410
00:29:53,040 --> 00:29:55,270
So, when you post a new comment,

411
00:29:55,270 --> 00:30:00,330
you see that this is how you will add a new comment into that server.

412
00:30:00,330 --> 00:30:03,630
Now, this returns a promise and so that is the information

413
00:30:03,630 --> 00:30:07,410
that I'm using here to construct this promise here.

414
00:30:07,410 --> 00:30:10,930
Then this other method here saying "getComments",

415
00:30:10,930 --> 00:30:16,930
this "getComments as you can see it is accessing AFS collection dishes,

416
00:30:16,930 --> 00:30:22,420
doc dishID and then collection comments and the notice that here,

417
00:30:22,420 --> 00:30:26,580
I am not going to be requiring each comments ID

418
00:30:26,580 --> 00:30:31,220
itself which I will not be using in my Angular petition anyway,

419
00:30:31,220 --> 00:30:33,230
so instead of using snapshot changes,

420
00:30:33,230 --> 00:30:36,285
I'm just using value changes and this will return

421
00:30:36,285 --> 00:30:42,170
all the documents in this comments collection for this particular document

422
00:30:42,170 --> 00:30:47,455
the dishID from the dish collection here and that will be returned

423
00:30:47,455 --> 00:30:53,320
and these comments I will be rendering in my dishdetail component.

424
00:30:53,320 --> 00:30:58,210
Now, in Mongos, you saw that the fact that I included the userID means

425
00:30:58,210 --> 00:31:02,920
that I could do copulating of this information now with Firebase,

426
00:31:02,920 --> 00:31:05,740
there is no way of populating the common information here,

427
00:31:05,740 --> 00:31:10,870
so that is why I am explicitly going and then populating the comments in

428
00:31:11,210 --> 00:31:15,250
my dishdetail component to fetch all the comments about

429
00:31:15,250 --> 00:31:20,000
this particular dish when I render them in the dishdetail component.

430
00:31:20,000 --> 00:31:22,830
So you see, that I had to adjust

431
00:31:22,830 --> 00:31:26,480
the Angular code a little bit in order to deal with the fact that

432
00:31:26,480 --> 00:31:29,765
Firebase doesn't support certain things that mongos supports

433
00:31:29,765 --> 00:31:33,605
at least at the moment Cloud Firestore beta doesn't support these things,

434
00:31:33,605 --> 00:31:38,420
and so I had to work around to deal with what Firebase allows me

435
00:31:38,420 --> 00:31:45,365
to store and retrieve from the Firebase server site.

436
00:31:45,365 --> 00:31:51,640
Now, it is also interesting for us to pay a quick visit to the Auth service here.

437
00:31:51,640 --> 00:31:54,060
The Auth service here again,

438
00:31:54,060 --> 00:31:59,875
notice that in the Auth service here I am importing this AngularFireAuth from

439
00:31:59,875 --> 00:32:06,435
the AngularFire to npm submodule here.

440
00:32:06,435 --> 00:32:11,005
So, here you can see that I'm importing AngularFireAuth and this

441
00:32:11,005 --> 00:32:15,970
gives me access to the authentication aspect of Firebase.

442
00:32:15,970 --> 00:32:21,690
Now, let's see how Firebase authentication actually works from our Angular application.

443
00:32:21,690 --> 00:32:26,300
Now we will start that by looking at how login is implemented.

444
00:32:26,300 --> 00:32:28,775
So, this is where I implement the login,

445
00:32:28,775 --> 00:32:31,420
where I am using the email and the password.

446
00:32:31,420 --> 00:32:38,090
So, this part when I import the AngularFireAuth here,

447
00:32:38,090 --> 00:32:44,910
notice that the constructor I am injecting the AngularFireAuth into my constructor.

448
00:32:44,910 --> 00:32:47,260
So this will inject the AngularFireAuth service

449
00:32:47,260 --> 00:32:50,240
into my constructor and this gives me access to

450
00:32:50,240 --> 00:32:55,975
the Firebase authentication on the server site so that I can authenticate users.

451
00:32:55,975 --> 00:33:01,555
So, if I want to authenticate a user who is signing in with the email and the password.

452
00:33:01,555 --> 00:33:04,490
This login function is the one that is going to be called

453
00:33:04,490 --> 00:33:07,300
when I type in my email and password in

454
00:33:07,300 --> 00:33:10,110
the login dialog that I pop up and then

455
00:33:10,110 --> 00:33:13,735
click on the submit button or the login button here,

456
00:33:13,735 --> 00:33:16,120
this login function is going to be called and

457
00:33:16,120 --> 00:33:20,845
the user information but I retrieve from the login component is passed in here.

458
00:33:20,845 --> 00:33:22,985
So when it comes here,

459
00:33:22,985 --> 00:33:29,410
I'm going to use this afAuth as you see I just injected it into the constructor,

460
00:33:29,410 --> 00:33:33,995
and this supplies this Auth object here,

461
00:33:33,995 --> 00:33:38,715
which supplies this method called "sign-in with email and password".

462
00:33:38,715 --> 00:33:43,530
So this signing in with email and password takes two parameters here as you would

463
00:33:43,530 --> 00:33:49,495
expect the user's username or the email and the password here.

464
00:33:49,495 --> 00:33:53,310
So these two piece of information I am supplying

465
00:33:53,310 --> 00:33:57,290
it as the two parameters to this sign-in with email and password.

466
00:33:57,290 --> 00:33:59,965
So, when you click on that you'll see that it

467
00:33:59,965 --> 00:34:03,790
says the first one should be email and the second one should be password.

468
00:34:03,790 --> 00:34:05,455
Now the way I have set it up,

469
00:34:05,455 --> 00:34:09,590
this user object that is coming in contains the email in the

470
00:34:09,590 --> 00:34:16,735
user.username here and the password in the password property of the user object.

471
00:34:16,735 --> 00:34:18,925
So, when that is obtained,

472
00:34:18,925 --> 00:34:24,670
then I will post this information and then so when this is completed successfully,

473
00:34:24,670 --> 00:34:27,430
that means that the user is logged in properly,

474
00:34:27,430 --> 00:34:29,075
if there is an error,

475
00:34:29,075 --> 00:34:31,510
then you catch the error here right now I am

476
00:34:31,510 --> 00:34:33,960
not doing anything specifically with the error you may

477
00:34:33,960 --> 00:34:38,820
wish to print out this error message to indicate that the user cannot log in and so on.

478
00:34:38,820 --> 00:34:42,070
So, I haven't implemented that part of the deal here,

479
00:34:42,070 --> 00:34:45,390
I'm just leaving it right there if you want to console log

480
00:34:45,390 --> 00:34:48,740
this information you can do that when errors occur.

481
00:34:48,740 --> 00:34:51,495
Now for sign out, in Firebase.

482
00:34:51,495 --> 00:34:56,610
Again we take the help of the afAuth which we have injected and Auth on it,

483
00:34:56,610 --> 00:34:58,975
and this provides this method called "sign out",

484
00:34:58,975 --> 00:35:01,815
which when called will sign out the currently logged in

485
00:35:01,815 --> 00:35:05,610
user and so that is one way of handling this.

486
00:35:05,610 --> 00:35:09,795
Now, you must be wondering how I handle the Google login part.

487
00:35:09,795 --> 00:35:17,980
Now this is also handled with the afAuth so the AngularFire2 module that I'm using,

488
00:35:17,980 --> 00:35:22,780
supplies this information for this methods for us through

489
00:35:22,780 --> 00:35:28,880
the Firebase module which is also used in AngularFire2,

490
00:35:28,880 --> 00:35:33,105
and so this supplies this method called sign-in with pop and when

491
00:35:33,105 --> 00:35:37,280
we do sign-in with pop-up here notice what I am specifying here.

492
00:35:37,280 --> 00:35:42,650
So, I am saying "new firebase.auth.GoogleAuthProvider".

493
00:35:42,650 --> 00:35:48,200
Now, you can also do firebase.auth.FacebookAuthProvider and other ones.

494
00:35:48,200 --> 00:35:52,170
So, as you saw from the previous exercise,

495
00:35:52,170 --> 00:35:58,835
Firebase allows you to do third-party login using either Google,

496
00:35:58,835 --> 00:36:01,520
Facebook, GitHub and Twitter.

497
00:36:01,520 --> 00:36:04,440
So you can configure these appropriately,

498
00:36:04,440 --> 00:36:07,260
since I have turned on only Google authorization.

499
00:36:07,260 --> 00:36:10,470
So this is how I will set it up to use

500
00:36:10,470 --> 00:36:16,160
my Google authorization here and this single line of code that I enclosed here,

501
00:36:16,160 --> 00:36:23,650
is the one that causes the pop-up of the browser which suggests to me to authorize

502
00:36:23,650 --> 00:36:31,580
my Firebase to use Google authorization using my Google account here.

503
00:36:31,580 --> 00:36:34,210
So that's the second part that I've set up here.

504
00:36:34,210 --> 00:36:38,929
So notice that the Auth service has significantly

505
00:36:38,929 --> 00:36:44,170
simplified compared to what we did with the previous version of this application.

506
00:36:44,170 --> 00:36:49,755
So you can compare the two versions to see how this is different from the other one.

507
00:36:49,755 --> 00:36:54,410
Now, not only that this afAuth that we have injected here,

508
00:36:54,410 --> 00:36:57,365
AngularFireAuth part that we have injected here,

509
00:36:57,365 --> 00:37:01,800
also provides this observable called "AuthState".

510
00:37:01,800 --> 00:37:08,045
This AuthState observable, can be subscribed to and this "AuthState" observable,

511
00:37:08,045 --> 00:37:10,130
as you see here,

512
00:37:10,130 --> 00:37:15,880
which I have declared here as an observable Firebase.user.

513
00:37:15,880 --> 00:37:21,400
So that is the information that is applied here and also we can setup

514
00:37:21,400 --> 00:37:27,465
another variable here called current user which is of the type Firebase user here.

515
00:37:27,465 --> 00:37:31,610
So, this afAuthState is an observable which

516
00:37:31,610 --> 00:37:35,570
I can subscribe to and whenever this AuthState changes,

517
00:37:35,570 --> 00:37:38,935
the AuthState keeps track of the authentication state of the user

518
00:37:38,935 --> 00:37:42,780
whether the user is logged in or logged out and if the user is logged in,

519
00:37:42,780 --> 00:37:47,930
then this will then subscribe will return me the user information and from

520
00:37:47,930 --> 00:37:53,475
the user information we can retrieve a lot of information including the display name,

521
00:37:53,475 --> 00:37:58,475
the email, the profile ID and then the

522
00:37:58,475 --> 00:38:04,535
avatar image for the user if it has been set up for the specific accounts.

523
00:38:04,535 --> 00:38:07,555
All these will be supplied to us automatically by the user.

524
00:38:07,555 --> 00:38:10,660
So, when you click on "user" and then dot,

525
00:38:10,660 --> 00:38:14,445
you will see that it provides all these information for us.

526
00:38:14,445 --> 00:38:16,870
So it's a display name email,

527
00:38:16,870 --> 00:38:19,835
whether the email is verified or not and so on.

528
00:38:19,835 --> 00:38:22,855
So some of the things that are specific interest to us.

529
00:38:22,855 --> 00:38:29,325
Photo URL which can be used to retrieve the avatar information for the user,

530
00:38:29,325 --> 00:38:32,430
provider ID which specifies who is

531
00:38:32,430 --> 00:38:35,755
providing this information for you this would be either Facebook ID,

532
00:38:35,755 --> 00:38:43,415
Google ID and GitHub ID and so on and additional information even the refresh token.

533
00:38:43,415 --> 00:38:46,390
So you see a bunch of information being

534
00:38:46,390 --> 00:38:49,840
made available to you through the user object that is

535
00:38:49,840 --> 00:38:53,285
returned by this Authstate when you subscribe to it

536
00:38:53,285 --> 00:38:57,400
and also let me draw your attention to the UID the user ID,

537
00:38:57,400 --> 00:39:01,830
and this is what can be used to index the user in our application.

538
00:39:01,830 --> 00:39:05,950
So that is the authentication service the way I have set

539
00:39:05,950 --> 00:39:10,325
it up to use Firebase authentication in this application.

540
00:39:10,325 --> 00:39:14,730
So, two changes that I have reflected to you to show

541
00:39:14,730 --> 00:39:19,180
how my services are modified to use Firebase.

542
00:39:19,180 --> 00:39:23,605
Much of the updates that I have done to my Angular application are all

543
00:39:23,605 --> 00:39:28,115
in the services in order to make use of Firebase installed.

544
00:39:28,115 --> 00:39:31,900
So, because of the baby structured of Angular application,

545
00:39:31,900 --> 00:39:34,390
the components were simply depending on the services and

546
00:39:34,390 --> 00:39:37,330
the services were the ones that we're talking to the back-end.

547
00:39:37,330 --> 00:39:39,660
So, much of the updates that I have done to

548
00:39:39,660 --> 00:39:43,040
my Angular application involve just updating these services to

549
00:39:43,040 --> 00:39:50,660
use Google's Firebase back-end as a service with the two npm modules,

550
00:39:50,660 --> 00:39:53,815
Firebase and AngularFireAuth here.

551
00:39:53,815 --> 00:39:58,690
So, you would see that much of the updates is restricted to

552
00:39:58,690 --> 00:40:04,285
all these services that I have in the services folder of my Angular application.

553
00:40:04,285 --> 00:40:06,710
Of course, I needed to do a little bit of

554
00:40:06,710 --> 00:40:09,615
minimal adjustments into the dishdetail component

555
00:40:09,615 --> 00:40:15,430
and the header component in order to make it work with Firebase.

556
00:40:15,430 --> 00:40:19,485
You can pay a quick visit to the headercomponent.ts,

557
00:40:19,485 --> 00:40:25,760
the headercomponent.html and the dishdetailcomponent.tsfile to see how the code

558
00:40:25,760 --> 00:40:29,210
has changed between the previous version

559
00:40:29,210 --> 00:40:32,070
and the current version of the Angular application,

560
00:40:32,070 --> 00:40:36,360
the previous version, I mean the version that we used for

561
00:40:36,360 --> 00:40:39,490
communicating with our X plus plus

562
00:40:39,490 --> 00:40:43,230
Mongo DB server which we used in the previous exercise.

563
00:40:43,230 --> 00:40:48,265
Now, one more place where you would see me making modifications,

564
00:40:48,265 --> 00:40:51,640
Interestingly, is in the favorite service.

565
00:40:51,640 --> 00:40:52,930
In the favorite service,

566
00:40:52,930 --> 00:40:55,280
the way I stored the favorites of the user,

567
00:40:55,280 --> 00:40:58,410
is that the favorites is a collection on

568
00:40:58,410 --> 00:41:02,015
my server site and the favorite itself contains documents.

569
00:41:02,015 --> 00:41:06,550
Each document contains the user ID and the dish ID.

570
00:41:06,550 --> 00:41:09,210
So, a particular user could have

571
00:41:09,210 --> 00:41:13,335
multiple documents each of them storing the user ID and the dish ID.

572
00:41:13,335 --> 00:41:20,035
So, a collection of them together will define all the favorites for a particular user.

573
00:41:20,035 --> 00:41:25,865
I found that this is a better way of organizing this data in Firebase.

574
00:41:25,865 --> 00:41:29,195
In our MongoDB plus mongos,

575
00:41:29,195 --> 00:41:34,230
you saw that I had embedded in array of dish IDs into

576
00:41:34,230 --> 00:41:40,575
the favorites document and then define the favorite schema that way.

577
00:41:40,575 --> 00:41:43,010
Here, I am using

578
00:41:43,010 --> 00:41:47,395
one separate document for tracking each of the favorites for each of the users.

579
00:41:47,395 --> 00:41:50,295
Now, because Firebase supports querying, so,

580
00:41:50,295 --> 00:41:55,545
I can query my Firebase and extract all the documents that have the same user IDs,

581
00:41:55,545 --> 00:41:58,585
which matches the user that is currently logged in and then

582
00:41:58,585 --> 00:42:02,405
extract the corresponding dish IDs from the favorites.

583
00:42:02,405 --> 00:42:05,250
Then I will go and then query my server

584
00:42:05,250 --> 00:42:08,475
and obtain the dish information for each of those dishes.

585
00:42:08,475 --> 00:42:13,325
So, it involves multiple trips to the server in order to obtain

586
00:42:13,325 --> 00:42:18,680
all my favorite dishes information before I can render my list of favorites.

587
00:42:18,680 --> 00:42:24,180
But, that is the best way that I could get Firebase to work with my Angular application.

588
00:42:24,180 --> 00:42:26,945
Maybe, at a future date,

589
00:42:26,945 --> 00:42:30,740
Firebase Cloud Firestone might extend to

590
00:42:30,740 --> 00:42:34,475
allow something like populate that we did with mongos.

591
00:42:34,475 --> 00:42:38,570
In which case, I will be updating the code to use that way

592
00:42:38,570 --> 00:42:42,705
of obtaining all the dish information automatically.

593
00:42:42,705 --> 00:42:48,420
So, the burden of constructing this compound document will be shifted to the server site.

594
00:42:48,420 --> 00:42:51,740
Right now, my client is doing much of the work here.

595
00:42:51,740 --> 00:42:53,795
Now, when you go in here,

596
00:42:53,795 --> 00:42:56,400
you will see that in the GetFavorites method,

597
00:42:56,400 --> 00:42:59,495
you will see how I am accessing my favorites here.

598
00:42:59,495 --> 00:43:02,835
So, when I do "Getfavorites" I am querying

599
00:43:02,835 --> 00:43:06,220
this collection of favorites but notice that here,

600
00:43:06,220 --> 00:43:12,545
I say "ref where is this user ID".

601
00:43:12,545 --> 00:43:15,335
This user ID I obtain here.

602
00:43:15,335 --> 00:43:18,320
So, in the constructor of my favorite server,

603
00:43:18,320 --> 00:43:22,855
I am subscribing to this Auth service the Get Auth state in the Auth service.

604
00:43:22,855 --> 00:43:25,075
So, in the Auth service if you go in,

605
00:43:25,075 --> 00:43:28,615
you will see this method called Get Auth state here.

606
00:43:28,615 --> 00:43:33,175
The Get Auth state returns the this.AuthState,

607
00:43:33,175 --> 00:43:35,575
which I have defined right there.

608
00:43:35,575 --> 00:43:39,760
So, this will be an observable as you see me declaring here.

609
00:43:39,760 --> 00:43:41,800
So, that observable is the one that I'm going

610
00:43:41,800 --> 00:43:46,755
to use within my favorite service and then subscribe to that.

611
00:43:46,755 --> 00:43:53,720
So, anytime the user information changes this will be automatically reflected in here.

612
00:43:53,720 --> 00:43:59,180
So, you saw that even in the earlier application I had used an observable,

613
00:43:59,180 --> 00:44:04,525
in order to reflect the user information into my header component.

614
00:44:04,525 --> 00:44:06,030
Similar kind of approach,

615
00:44:06,030 --> 00:44:08,600
that I'm using in my favorites component here,

616
00:44:08,600 --> 00:44:13,055
to get hold of the user ID for the currently logged in user.

617
00:44:13,055 --> 00:44:16,385
So, when I query My Favorites collection,

618
00:44:16,385 --> 00:44:22,825
I will query and extract only those documents where the user matches this.

619
00:44:22,825 --> 00:44:26,220
Then I'm only using the value changes here.

620
00:44:26,220 --> 00:44:29,210
So, I'm only extracting all the documents,

621
00:44:29,210 --> 00:44:34,650
that I don't care about the ID of the favorites document itself at this moment.

622
00:44:34,650 --> 00:44:37,970
So, I'm just extracting all of them and using them.

623
00:44:37,970 --> 00:44:40,690
If the user is not logged in and as you can see

624
00:44:40,690 --> 00:44:43,620
I'm throwing an error here with the observable saying,

625
00:44:43,620 --> 00:44:50,735
"no user logged in" that is what is displayed in my favorite speech there.

626
00:44:50,735 --> 00:44:53,960
Now, the isFavorites is also updated here

627
00:44:53,960 --> 00:44:57,685
but in the isFavorites what I'm doing is I'm going to the DB.

628
00:44:57,685 --> 00:45:02,795
Now here, I will access the database by saying,

629
00:45:02,795 --> 00:45:06,135
"DB is equal to firebase.firestore".

630
00:45:06,135 --> 00:45:09,610
Recall that I am importing Firebase here,

631
00:45:09,610 --> 00:45:12,270
import star as Firebase here.

632
00:45:12,270 --> 00:45:17,970
The Angular Firestore itself doesn't provide me with a method of

633
00:45:17,970 --> 00:45:23,970
doing multiple compound queries here.

634
00:45:23,970 --> 00:45:29,495
The Angular Firestore or the Angular fire to doesn't provide me with doing that.

635
00:45:29,495 --> 00:45:33,390
So, that is why I have to resort to using Firebase Firestore.

636
00:45:33,390 --> 00:45:35,840
So, when I when I say Firebase Firestore,

637
00:45:35,840 --> 00:45:42,310
this gives me a reference to the Firestore database and then I can go into this database

638
00:45:42,310 --> 00:45:48,780
and then say "DB collection favorites" and then I can do multiple queries here.

639
00:45:48,780 --> 00:45:55,470
So,I am saying,.where user is this.wheredish is the dish ID.

640
00:45:55,470 --> 00:45:59,380
So, if I want to obtain a specific favorite.

641
00:45:59,380 --> 00:46:03,640
To check if a specific dish is the favorite of a user I obtain

642
00:46:03,640 --> 00:46:08,285
that particular document where the user and the dish match these two,

643
00:46:08,285 --> 00:46:12,110
if they don't match then it'll return with an empty.

644
00:46:12,110 --> 00:46:16,610
So, that I extract and then return this value here.

645
00:46:16,610 --> 00:46:18,900
Now, then I post favorites,

646
00:46:18,900 --> 00:46:25,770
you see how I'm doing this I'm saying this AFS collection favorites and I'll say "add".

647
00:46:25,770 --> 00:46:29,260
Look at the document that I am storing in my favorites.

648
00:46:29,260 --> 00:46:32,130
The document itself contains the user ID and the dish ID.

649
00:46:32,130 --> 00:46:36,030
So, these two pieces of information enclosed in here and if

650
00:46:36,030 --> 00:46:41,295
not then it will reject the promise with no user logged in here.

651
00:46:41,295 --> 00:46:44,915
Similarly, for the delete favorite that I've implemented here.

652
00:46:44,915 --> 00:46:48,735
Spend some time again going through this code to understand how I have

653
00:46:48,735 --> 00:46:53,375
leveraged Firebase and Angular fire to npm modules in

654
00:46:53,375 --> 00:47:02,170
order to communicate with my Firebase server that I have set up in the previous exercise.

655
00:47:02,170 --> 00:47:05,880
With this, I have given you a quick overview of

656
00:47:05,880 --> 00:47:10,280
how you can set up your Angular application to interact with

657
00:47:10,280 --> 00:47:13,980
Firebase back-end as a service and then be able

658
00:47:13,980 --> 00:47:19,970
to support various operations that you have within your Angular application.

659
00:47:19,970 --> 00:47:21,905
As I've demonstrated earlier,

660
00:47:21,905 --> 00:47:24,150
this Angular application looks exactly like

661
00:47:24,150 --> 00:47:26,690
the previous version of the Angular application where we were

662
00:47:26,690 --> 00:47:31,915
using our own version of our Express MongoDB server.

663
00:47:31,915 --> 00:47:38,510
Now, with this I complete this particular exercise where I have illustrated in

664
00:47:38,510 --> 00:47:42,020
this lesson about back-end as a service and also demonstrated

665
00:47:42,020 --> 00:47:46,630
Firebase as an example of a back-end as a service.