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