1
00:00:02,000 --> 00:00:04,000
Now let's start with the starting page.

2
00:00:04,000 --> 00:00:06,000
Here on this starting page,

3
00:00:06,000 --> 00:00:09,000
we want the featured events.

4
00:00:09,000 --> 00:00:12,000
So we need to load those featured events

5
00:00:12,000 --> 00:00:14,000
onto this index.js page.

6
00:00:14,000 --> 00:00:16,000
So into this index.js component here,

7
00:00:16,000 --> 00:00:18,000
this homepage component.

8
00:00:18,000 --> 00:00:22,000
The question now is how do we wanna load the data?

9
00:00:22,000 --> 00:00:26,000
Now we could do it with client site data fetching.

10
00:00:26,000 --> 00:00:29,000
We could use useEffect with the fetch API

11
00:00:29,000 --> 00:00:34,000
or install and use the useSWR hook here

12
00:00:34,000 --> 00:00:36,000
which we learned about.

13
00:00:36,000 --> 00:00:39,000
We could do that, but does this make sense?

14
00:00:39,000 --> 00:00:41,000
Is this the best solution here?

15
00:00:41,000 --> 00:00:45,000
I would argue that here we actually wanna use,

16
00:00:45,000 --> 00:00:48,000
one of the two forms of pre-rendering instead.

17
00:00:48,000 --> 00:00:52,000
So static generation or server-side rendering.

18
00:00:52,000 --> 00:00:56,000
Because the starting page, which we're looking at here,

19
00:00:56,000 --> 00:00:59,000
this is a page which should be understood

20
00:00:59,000 --> 00:01:01,000
by search engine crawlers.

21
00:01:01,000 --> 00:01:05,000
It's important that they are able to understand our site

22
00:01:05,000 --> 00:01:08,000
and well, direct traffic to our site.

23
00:01:08,000 --> 00:01:11,000
And as a visitor on this page, it would also be nice

24
00:01:11,000 --> 00:01:13,000
if we see something instantly.

25
00:01:13,000 --> 00:01:15,000
It's also not likely

26
00:01:15,000 --> 00:01:19,000
that this data changes multiple times per second

27
00:01:19,000 --> 00:01:20,000
or minute even.

28
00:01:20,000 --> 00:01:23,000
So there isn't really a reason for loading this

29
00:01:23,000 --> 00:01:25,000
on the client side.

30
00:01:25,000 --> 00:01:27,000
It's also not some user specific data

31
00:01:27,000 --> 00:01:31,000
and it's also not data behind a login screen

32
00:01:31,000 --> 00:01:33,000
or anything like that.

33
00:01:33,000 --> 00:01:36,000
So here I would argue, it makes a lot of sense

34
00:01:36,000 --> 00:01:39,000
to pre-render this page with some data.

35
00:01:39,000 --> 00:01:42,000
That then just leaves one question,

36
00:01:42,000 --> 00:01:44,000
should we use getServersideProps

37
00:01:45,000 --> 00:01:49,000
for real server-side pre-rendering where the page

38
00:01:49,000 --> 00:01:54,000
is pre-rendered on the server on the fly for every request

39
00:01:54,000 --> 00:01:59,000
or do we want getStaticProps to pre-render the page,

40
00:01:59,000 --> 00:02:04,000
during the build process and potentially also on the server

41
00:02:04,000 --> 00:02:07,000
if we set revalidate to a certain value

42
00:02:07,000 --> 00:02:11,000
so that we have a mostly updated page.

43
00:02:11,000 --> 00:02:13,000
I would argue for this kind of page,

44
00:02:13,000 --> 00:02:15,000
we don't need server-side rendering.

45
00:02:15,000 --> 00:02:18,000
We don't need to pre-render it for every request,

46
00:02:18,000 --> 00:02:23,000
instead using getStaticProps makes most sense here,

47
00:02:23,000 --> 00:02:24,000
I would say.

48
00:02:24,000 --> 00:02:27,000
So we can export this async function,

49
00:02:27,000 --> 00:02:32,000
getStaticProps here in this index.js file.

50
00:02:32,000 --> 00:02:36,000
Get our context, though here, we won't need it.

51
00:02:36,000 --> 00:02:37,000
So we can also omit it.

52
00:02:37,000 --> 00:02:38,000
And then in here,

53
00:02:38,000 --> 00:02:43,000
return an object with the props for this homepage component.

54
00:02:45,000 --> 00:02:46,000
Now the props should be an object

55
00:02:46,000 --> 00:02:51,000
and in there I want to have my featured events

56
00:02:51,000 --> 00:02:54,000
which now should be fetched from Firebase,

57
00:02:54,000 --> 00:02:57,000
not from the dummy-data.js file anymore.

58
00:02:57,000 --> 00:03:00,000
We're past this world.

59
00:03:00,000 --> 00:03:02,000
Now we have the Firebase backend

60
00:03:02,000 --> 00:03:04,000
and we wanna fetch that data from there.

61
00:03:04,000 --> 00:03:09,000
Now, how do we fetch the featuredEvents from Firebase?

62
00:03:09,000 --> 00:03:12,000
Actually, when it comes to querying Firebase,

63
00:03:12,000 --> 00:03:15,000
you can adjust the HTTP request

64
00:03:15,000 --> 00:03:18,000
which is being sent with some query parameters

65
00:03:18,000 --> 00:03:21,000
to filter the data you are retrieving.

66
00:03:21,000 --> 00:03:25,000
If you search for Firebase realtime database filter,

67
00:03:25,000 --> 00:03:28,000
you'll find this retrieving data article,

68
00:03:28,000 --> 00:03:31,000
and there you'll learn how you can adjust

69
00:03:31,000 --> 00:03:34,000
to the URL to which you send the request,

70
00:03:34,000 --> 00:03:37,000
with query parameters QL,

71
00:03:37,000 --> 00:03:40,000
filter the data which you are retrieving.

72
00:03:40,000 --> 00:03:42,000
And you can filter by a specific child keys,

73
00:03:42,000 --> 00:03:45,000
look for a certain values and so on.

74
00:03:46,000 --> 00:03:50,000
Now you can do that and feel free to dive into the docs

75
00:03:50,000 --> 00:03:55,000
to implement it such that you do filter on Firebase side

76
00:03:55,000 --> 00:03:57,000
for retrieving only selected data.

77
00:03:57,000 --> 00:03:59,000
I will not do that here,

78
00:03:59,000 --> 00:04:01,000
because this is not a Firebase course.

79
00:04:01,000 --> 00:04:04,000
And it's really just a dummy backend.

80
00:04:04,000 --> 00:04:07,000
Instead, I will add a new file here.

81
00:04:07,000 --> 00:04:11,000
Let's say in a helpers folder,

82
00:04:11,000 --> 00:04:16,000
a file which I'll name api-util.js.

83
00:04:16,000 --> 00:04:18,000
So which has utility functions

84
00:04:18,000 --> 00:04:21,000
for working with an API and in there,

85
00:04:21,000 --> 00:04:23,000
I will now add a function

86
00:04:23,000 --> 00:04:26,000
which gives me the featured events,

87
00:04:26,000 --> 00:04:29,000
but I will actually always fetch all events first

88
00:04:29,000 --> 00:04:32,000
and then filter them just here in JavaScript

89
00:04:33,000 --> 00:04:35,000
which is of course not ideal because it means

90
00:04:35,000 --> 00:04:39,000
that we always fetch all the data, even if we don't need it.

91
00:04:39,000 --> 00:04:42,000
But as I just said, that's just not the focus here,

92
00:04:42,000 --> 00:04:45,000
it would be very Firebase specific

93
00:04:45,000 --> 00:04:48,000
if we write the Firebase query logic here

94
00:04:48,000 --> 00:04:51,000
and that, well, basically leads nowhere.

95
00:04:51,000 --> 00:04:53,000
So therefore I'll go to dummy-data.js

96
00:04:53,000 --> 00:04:58,000
and copy the getFeaturedEvents function from there

97
00:04:58,000 --> 00:05:02,000
and add it here in the api-util.js file.

98
00:05:03,000 --> 00:05:06,000
But I'll also add a number of functions here, getAllEvents.

99
00:05:09,000 --> 00:05:12,000
And in there, I will write the logic

100
00:05:12,000 --> 00:05:16,000
for fetching all events data from Firebase.

101
00:05:16,000 --> 00:05:19,000
So I'll turn this into an async function

102
00:05:19,000 --> 00:05:21,000
so that I can use async await here.

103
00:05:21,000 --> 00:05:23,000
I'll also convert getFeaturedEvents

104
00:05:23,000 --> 00:05:25,000
into an async function.

105
00:05:25,000 --> 00:05:30,000
And then here in getAllEvents, I will call fetch.

106
00:05:31,000 --> 00:05:34,000
So the built-in fetch API,

107
00:05:34,000 --> 00:05:36,000
which is available in the browser

108
00:05:36,000 --> 00:05:40,000
and thanks to next JS also can be used inside

109
00:05:40,000 --> 00:05:42,000
of getStaticProps and getServersideProps.

110
00:05:43,000 --> 00:05:48,000
And here, we'll then send a request to this Firebase URL.

111
00:05:48,000 --> 00:05:53,000
So to this rest API URL, which then triggers Firebase

112
00:05:53,000 --> 00:05:56,000
to talk to our database here.

113
00:05:56,000 --> 00:06:00,000
There we wanna reach out into the events node.

114
00:06:00,000 --> 00:06:02,000
So this node, which I added here

115
00:06:03,000 --> 00:06:05,000
and then because it's Firebase,

116
00:06:05,000 --> 00:06:08,000
we need to add .json at the end here.

117
00:06:08,000 --> 00:06:10,000
That's Firebase specific.

118
00:06:11,000 --> 00:06:14,000
Now, since we use async here,

119
00:06:14,000 --> 00:06:16,000
we can also await this

120
00:06:16,000 --> 00:06:20,000
to get our response like this without then.

121
00:06:21,000 --> 00:06:24,000
Under the hood, async awaits still uses then,

122
00:06:24,000 --> 00:06:25,000
but we can write it

123
00:06:25,000 --> 00:06:28,000
in this more convenient way here.

124
00:06:28,000 --> 00:06:32,000
And we can get our data by awaiting response.json.

125
00:06:34,000 --> 00:06:37,000
We also might want to implement error handling here,

126
00:06:37,000 --> 00:06:40,000
but for the moment, I'll skip it.

127
00:06:40,000 --> 00:06:42,000
Instead here, we then have the data.

128
00:06:42,000 --> 00:06:44,000
And as you learned in the last section,

129
00:06:44,000 --> 00:06:48,000
Firebase returns your data as an object.

130
00:06:48,000 --> 00:06:51,000
So I'll transform my events here.

131
00:06:51,000 --> 00:06:53,000
I'll add them as an empty array

132
00:06:53,000 --> 00:06:56,000
and then loop through my data.

133
00:06:56,000 --> 00:06:58,000
So through all the keys and data,

134
00:06:58,000 --> 00:07:01,000
so through all the entries and events.

135
00:07:01,000 --> 00:07:05,000
So these are my keys, e1, e2 and e3.

136
00:07:05,000 --> 00:07:07,000
And I'll loop through them.

137
00:07:07,000 --> 00:07:09,000
And for every key, I'll push a new event

138
00:07:09,000 --> 00:07:14,000
into this events array, where the id is equal to key

139
00:07:14,000 --> 00:07:19,000
and where I then wanna distribute all of the nested data

140
00:07:19,000 --> 00:07:23,000
which is stored under that key into that events object.

141
00:07:23,000 --> 00:07:26,000
And to not manually write all these key value pairs,

142
00:07:26,000 --> 00:07:28,000
I'll use the spread operator

143
00:07:28,000 --> 00:07:31,000
and just copy everything from data

144
00:07:31,000 --> 00:07:33,000
for the given key.

145
00:07:33,000 --> 00:07:36,000
So from this nested object here

146
00:07:36,000 --> 00:07:40,000
into this object, which we push onto events.

147
00:07:41,000 --> 00:07:45,000
That should ensure that events is an array full of objects,

148
00:07:45,000 --> 00:07:50,000
with all these fields here and with an id field,

149
00:07:50,000 --> 00:07:53,000
which is e1, e2 or e3.

150
00:07:54,000 --> 00:07:58,000
And then I will return events here.

151
00:07:58,000 --> 00:08:00,000
Now, overall, we still return a promise here,

152
00:08:00,000 --> 00:08:01,000
because of async,

153
00:08:01,000 --> 00:08:05,000
but that promise will then resolve to this events array.

154
00:08:05,000 --> 00:08:08,000
And in getFeaturedEvents,

155
00:08:08,000 --> 00:08:10,000
we can now get all events

156
00:08:10,000 --> 00:08:15,000
by awaiting the result of calling, getAllEvents.

157
00:08:15,000 --> 00:08:18,000
So this function I just worked on, I call it here,

158
00:08:18,000 --> 00:08:20,000
since it returns a promise,

159
00:08:20,000 --> 00:08:21,000
I await that promise

160
00:08:21,000 --> 00:08:24,000
which I can because I added async here.

161
00:08:24,000 --> 00:08:28,000
Then I have all events and I return all events,

162
00:08:28,000 --> 00:08:31,000
filtering for the events that are featured.

163
00:08:31,000 --> 00:08:35,000
Again, that means that we always load all events first,

164
00:08:35,000 --> 00:08:38,000
but here for this demo, that is okay.

165
00:08:39,000 --> 00:08:41,000
Now it's getFeaturedEvents,

166
00:08:41,000 --> 00:08:45,000
this getFeaturedEvents, not the one from dummy-data

167
00:08:45,000 --> 00:08:47,000
which I wanna use in index.js.

168
00:08:47,000 --> 00:08:52,000
So here we wanna import getFeaturedEvents from,

169
00:08:56,000 --> 00:08:59,000
and then I'll dive into the helpers folder into api-util.

170
00:09:01,000 --> 00:09:05,000
And now here in getStaticProps,

171
00:09:05,000 --> 00:09:08,000
we can get the featured events

172
00:09:08,000 --> 00:09:13,000
by awaiting the result of getFeaturedEvents.

173
00:09:13,000 --> 00:09:16,000
So of calling this function, which we just worked on

174
00:09:16,000 --> 00:09:18,000
which I now imported.

175
00:09:18,000 --> 00:09:22,000
We can use await because that is an async function.

176
00:09:22,000 --> 00:09:24,000
And then it's these featuredEvents

177
00:09:24,000 --> 00:09:27,000
which I'll set as a value for the featuredEvents prop.

178
00:09:28,000 --> 00:09:31,000
Now we can also name this prop just events.

179
00:09:31,000 --> 00:09:34,000
It doesn't have to be named featuredEvents.

180
00:09:34,000 --> 00:09:36,000
And with that in getStaticProps,

181
00:09:36,000 --> 00:09:40,000
we return an object with our featuredEvents

182
00:09:40,000 --> 00:09:43,000
in props and the featuredEvents ultimately,

183
00:09:43,000 --> 00:09:46,000
are fetched from Firebase.

184
00:09:46,000 --> 00:09:51,000
So now in the component function here, which is executed

185
00:09:51,000 --> 00:09:55,000
after getStaticProps, we now should accept props.

186
00:09:55,000 --> 00:09:56,000
So the props which are set

187
00:09:56,000 --> 00:10:01,000
by getStaticProps, and then here we no longer need

188
00:10:01,000 --> 00:10:03,000
to call getFeaturedEvents.

189
00:10:03,000 --> 00:10:05,000
And we don't wanna call it here,

190
00:10:05,000 --> 00:10:08,000
because we don't wanna fetch them on the client,

191
00:10:08,000 --> 00:10:12,000
instead, I just forward prop.events.

192
00:10:12,000 --> 00:10:16,000
So my events here to EventList.

193
00:10:17,000 --> 00:10:18,000
And now let's see if that works.

194
00:10:18,000 --> 00:10:20,000
If we save that.

195
00:10:20,000 --> 00:10:25,000
If we go back to the starting page and reload,

196
00:10:25,000 --> 00:10:26,000
that's looking good.

197
00:10:26,000 --> 00:10:29,000
I see my events and I can still click on them.

198
00:10:29,000 --> 00:10:33,000
And if I reload and view the page source here,

199
00:10:33,000 --> 00:10:38,000
we see that the event data is actually part

200
00:10:38,000 --> 00:10:40,000
of that HTML file

201
00:10:40,000 --> 00:10:43,000
which was sent back by the server.

202
00:10:43,000 --> 00:10:48,000
So pre-rendering this page with the event data worked.

203
00:10:48,000 --> 00:10:50,000
And here we are using static generation,

204
00:10:50,000 --> 00:10:52,000
because we're using getStaticProps.

205
00:10:53,000 --> 00:10:57,000
So this applies what we learned with Firebase

206
00:10:57,000 --> 00:11:00,000
and with getStaticProps to this homepage.

