Instructor: So let's work on the ordering part now. 2 2
Whenever a new order is placed, 3 3
we wanna send a notification, a push notification. 4 4
Now we are storing this owner push token 5 5
which we need for sending a notification. 6 6
And actually, we've got two options now. 7 7
Since this is all on the back end, 8 8
we could send this request to expose push server 9 9
from the back end, either by using one of the Expo SDKs 10 10
I showed you earlier, like the one for node and PHP, 11 11
depending on which language you are using on your back end, 12 12
or by simply sending that same HTTP request 13 13
we sent from inside the app earlier from your back end. 14 14
That would also be an option. 15 15
Now Firebase is a special back end, we don't fully own it. 16 16
We instead use the services that we have. 17 17
Indeed, with Cloud functions, there would be a service 18 18
that allows us to run server side code, 19 19
and we could make that all work. 20 20
But since using Cloud Functions isn't entirely free anymore, 21 21
I don't wanna show this here. 22 22
I just want you to know that you absolutely 23 23
could come up with code on the server, 24 24
that would cause the push notification to be sent 25 25
from inside this server 26 26
so that this triggering happens here on the server. 27 27
Now, I will do it from the app instead, 28 28
since that's easier for us here, 29 29
but that is only one possible option. 30 30
Now from inside the app, we'll send the notification 31 31
just as we did it before. 32 32
Here in add order, we do want to send it 33 33
and there we got our cart items. 34 34
Now the cart items we're getting, 35 35
let's have a brief look at what exactly is in there. 36 36
So if you go to the shop, to the orders, to the cart screen, 37 37
that's where we dispatch this action, 38 38
the add order action with the card items, 39 39
and if we have a look at our cart items, 40 40
we see that in the end, card items are fetched 41 41
from our Redux store. 42 42
And card items will be an array, 43 43
where we in the end have objects where every object 44 44
has a product ID, product, title, product price, 45 45
quantity, and so on. 46 46
So what we need here is we also need the product push token, 47 47
so the token of the creator of this product in the end, 48 48
and we can get this from inside our state 49 49
there from the cart, from the items for that key. 50 50
So basically, what we do up there, 51 51
and there, let's look for a push token. 52 52
Now this is a field which won't be there yet 53 53
because we first of all 54 54
need to make some changes to our store. 55 55
There, let's check out the cart reducer. 56 56
When a product is added to the cart, 57 57
we get information about this product here. 58 58
And from there we for example, extract the title 59 59
and the price. 60 60
And then in the end, we add this price and title 61 61
to our cart item. 62 62
Now we don't just need the price and the title, 63 63
we also need the push token. 64 64
So here, let's also extract the push token off this product. 65 65
So added product dot push token, for example. 66 66
This is also a field which won't exist on a product yet, 67 67
but we'll change this soon. 68 68
And then we can add this push token, 69 69
let's say as a third argument here, to cart item, 70 70
and also here, sorry, it's the fourth argument, of course. 71 71
So I'm adding this as a fourth argument 72 72
to the cart item constructor. 73 73
Now for that, we need to change the card item constructor. 74 74
So here card item should now actually get this push token 75 75
as a fourth argument, and then stored this here. 76 76
So this push token is equal to push token. 77 77
But we're still not there 78 78
because now I'm storing this for every card item. 79 79
But I'm getting this 80 80
from my product, and a product doesn't have a token yet. 81 81
Yes, it has one on Firebase, 82 82
but we're not fetching that data 83 83
or we're not using that data in our client side app 84 84
in this React Native app. 85 85
Instead, here in the products actions file here, 86 86
products.js in actions where we do fetch all products, 87 87
here, fetch products, 88 88
what we do is we extract things like the ID, 89 89
title, price, and so on and create a new product 90 90
based on our product model with that information. 91 91
Now here, we should also get that owner push token, 92 92
just like we're extracting the owner ID. 93 93
So here we wanna get the owner push token 94 94
for the individual products and add this 95 95
to our product model, for example, as a third argument. 96 96
So now with that, we need to go to the products model, 97 97
to the product model here, sorry, product in models, 98 98
and there as a third argument, 99 99
we now need to accept the owner push token and store this. 100 100
And I'll name this field push token 101 101
and store my owner push token in it 102 102
because push token is the field name 103 103
which I now also used here in the cart reducer. 104 104
There, I'm accessing added product dot push token. 105 105
So if you use the different name here to retrieve the token 106 106
for a given product, you also need to adjust this name here 107 107
in the product model. 108 108
But with all those changes, we're making sure 109 109
that we're fetching the token that is stored 110 110
for every product and we're using it 111 111
and storing it in the front end in our models as well. 112 112
And we're storing it in every product model 113 113
which we're creating every product instance. 114 114
And we're also storing it in our cart items 115 115
which we're adding to our cart here in the Redux store. 116 116
So now every card item will have a push token, 117 117
and our card item model also stores that 118 118
in a key named push token. 119 119
And therefore, now we'll finally be able to get that data 120 120
when an order is placed. 121 121
Now we don't just need to update how we create products here 122 122
in the products.js file in the actions file, 123 123
but also in the reducers. 124 124
In the product.js file in reducers, 125 125
there, we have to create product case 126 126
which we handle where we also instantiate our product. 127 127
Now since we changed our product model 128 128
to take the push token as the third argument here, 129 129
we also need to update this here, of course. 130 130
So here, the third argument, 131 131
the title, should no longer be the title, 132 132
but instead, it should be coming from our product data, 133 133
and there, it should be the push token. 134 134
Now for data, of course, in turn, 135 135
we need to check where we dispatch create product 136 136
to ensure that the action that adds product data 137 137
also adds a push token to that product data. 138 138
We also create a new product down there in update product. 139 139
And there, it's the same. 140 140
The new third argument which we get here 141 141
in the product constructor should in this case, 142 142
be state user products for the given product index, 143 143
and then there again, it's the push token. 144 144
Push token is the name we have here 145 145
because that here will act as a product stored 146 146
in our user products field and that product 147 147
will have the form a flower product model, 148 148
and there, I pick push token as a name, 149 149
so this also is push token as a name here. 150 150
So with that, back to the create product case, 151 151
as I said, we now need to go to the place 152 152
where this action is dispatched 153 153
to ensure that the proper data, 154 154
the push token is added to the action. 155 155
Now it's the products.js file in the actions folder, 156 156
and there, the create product action creator 157 157
where we do dispatch this create product action in the end. 158 158
And therefore here to product data, anywhere in this object, 159 159
we should make sure that we also add a push token, 160 160
and now this push token value is simply the push token 161 161
we already are using up there. 162 162
So we should store this here as well. 163 163
And with that, we ensure that we don't get an error 164 164
when we create a new product. 165 165
Otherwise, we won't be getting one. 166 166
So back here in the orders actions file, 167 167
in the add order action. 168 168
Here, we now want to get our token from inside the card item 169 169
and send such push notification request 170 170
maybe after adding the actual order on our server, 171 171
because sending the push notification is less important 172 172
than storing the data on the server, I would argue. 173 173
So therefore, after this request was sent here, 174 174
after we added the order in our Redux store, 175 175
after all of that, we want to send our push notifications. 176 176
Now for that, we'll have to go through 177 177
all the card items we have here 178 178
and send one notification per item. 179 179
That's another reason why you might wanna consider 180 180
doing this on the server side. 181 181
If you have a lot of items, this can take some time 182 182
and at the moment, that will all be worked that happens here 183 183
in our React Native app on the client, not on the server. 184 184
On the server might be better 185 185
because it takes that work off your client. 186 186
But for the reasons mentioned, 187 187
since we don't have our own server, 188 188
since we're using Firebase and Cloud Functions 189 189
aren't free to use anymore, because of all those reasons, 190 190
I will actually use the sub-optimal solution 191 191
of triggering that on the client. 192 192
So inside of the React Native app, and therefore here, 193 193
we wanna go through all the card items we have. 194 194
So through all our card items here, and for every card item, 195 195
we wanna get the push token 196 196
simply by accessing card item dot push token, 197 197
and then we wanna send our request. 198 198
So again, with the fetch API here, 199 199
we want to send the request to HTTPS. 200 200
And then that was x dot host, 201 201
slash dash dash slash API slash v2 slash push slash send, 202 202
and add the second object where we configure this request 203 203
to set its methods to post, 204 204
and to also add a couple of headers here. 205 205
And we wanted the accept header 206 206
which should be application, JSON, 207 207
we wanted the accept encoding header 208 208
which should be gzip, deflate, 209 209
and we want the content type header here 210 210
which should also be application JSON. 211 211
But now even more important, 212 212
we wanna add our body to the request 213 213
which should be a JSON stringified object, 214 214
in which we now point at this push token with the to field. 215 215
And then we can add extra information. 216 216
We could add extra metadata about the card item, 217 217
for example, for which there's notification's being sent. 218 218
But here, I'll just as a title of order was placed, 219 219
and then body for this push notification 220 220
where I simply shared, let's say, 221 221
the title of the product that was ordered. 222 222
Keep in mind that in every card title, 223 223
we store the product title on a product title field. 224 224
So therefore, back here in the orders actions file, 225 225
I can access card item dot product title 226 226
to share that product title as part of the push notification 227 227
that should be sent. 228 228
And this is in the end it. 229 229
With that, we're going to schedule a bunch of HTTP requests. 230 230
I'm not waiting for their responses, 231 231
I'm not handling the responses, you could look 232 232
into those responses and try handling possible errors. 233 233
But in the end, this should work. 234 234
And if for some reason, 235 235
one push notification shouldn't go through, 236 236
in this case, it's also not the end of the world, 237 237
but it should really work. 238 238
So let's now save this, and let's give it a try. 239 239
So back here in my application, I'll add a second product 240 240
simply to see if we get two push notifications. 241 241
I'll use the same image, though, 242 242
enter my price and a description. 243 243
Confirm this and now go to the products area, 244 244
and add both to my cart. 245 245
Now, these are my own products, but in this app, 246 246
I can still order them. 247 247
So now let's press ordered out 248 248
which should place the order and we don't see anything. 249 249
Now does this mean that we have an error? 250 250
Not necessarily, we don't see anything 251 251
because you might remember 252 252
that if the app is running in foreground by default, 253 253
no notification is shown. 254 254
And that's the same for push notifications 255 255
because as you also learned, 256 256
they just trigger local notifications in the end. 257 257
So let's fix that and let's make sure we can see something.