1 00:00:02,140 --> 00:00:08,590 So how can we leave these auth screen now if we are logged in or if we did sign up successfully? 2 00:00:09,520 --> 00:00:11,130 Well that's not too difficult. 3 00:00:11,380 --> 00:00:16,690 If we make it past this dispatching here without landing in the catch block, 4 00:00:16,720 --> 00:00:18,730 so it's still here in the try block, 5 00:00:19,090 --> 00:00:26,560 we can just call props.navigation.navigate just as we always did and navigate 6 00:00:26,560 --> 00:00:29,470 to the different screen we set up in our switch navigator, 7 00:00:29,470 --> 00:00:37,500 so in this case to the shop screen. So let's do that, let's simply go to shop and there for now as soon 8 00:00:37,500 --> 00:00:42,950 as we do login successfully, which I'll now do, this loads 9 00:00:43,030 --> 00:00:45,300 and we're here. Now I'll 10 00:00:45,330 --> 00:00:49,300 get a warning here regarding some state update which couldn't be performed, 11 00:00:49,300 --> 00:00:55,450 that's this set is loading state which now fails if we navigate away. The solution is simply we shouldn't 12 00:00:55,450 --> 00:01:01,000 try to update the state on this screen if we're not on the screen anymore, so we can simply move that 13 00:01:01,000 --> 00:01:05,560 into the catch block because we'll only need to reset loading if we have an error because that's the 14 00:01:05,560 --> 00:01:07,600 only case when we stay on the auth screen, 15 00:01:07,600 --> 00:01:12,190 otherwise we don't need to change the loading state because we're leaving the screen anyways. So with that, 16 00:01:12,190 --> 00:01:13,780 we'll get rid of this as well, 17 00:01:13,780 --> 00:01:17,080 if I now try this again, 18 00:01:17,300 --> 00:01:18,170 here we go 19 00:01:18,170 --> 00:01:22,730 and now we're in our main shop. Now we're still of course not utilizing the token, 20 00:01:22,730 --> 00:01:24,620 so let's make sure we do that as well 21 00:01:24,740 --> 00:01:31,550 and for that let's go to the auth reducer and add an initial state there which describes basically with 22 00:01:31,640 --> 00:01:35,850 which state we want to start and what our general state shape is 23 00:01:36,230 --> 00:01:41,960 and there I want to store the token which initially is null and I want to store the userId which initially 24 00:01:41,960 --> 00:01:45,980 is null, so very basic initial state. 25 00:01:45,980 --> 00:01:51,230 Then we can export the reducer function which takes that initial state and which also receives of course 26 00:01:52,010 --> 00:01:57,430 an action and here I want to switch on the action type as always 27 00:01:57,430 --> 00:01:59,960 and I got two cases I'm interested in right now. 28 00:01:59,980 --> 00:02:08,190 One is the login action, so you need to import this identifier from the actions folder and the auth file 29 00:02:08,190 --> 00:02:12,530 there and the other case is the sign up action, 30 00:02:12,580 --> 00:02:14,680 so you need to import this identifier as well, 31 00:02:15,820 --> 00:02:25,400 in other cases, I just want to return my state. So if we do login, I want to return a new state where 32 00:02:25,400 --> 00:02:33,400 the token should be let's say action.token and userId should be action.userId 33 00:02:33,940 --> 00:02:38,530 and that's the same update I need in sign up so we can just copy that over there. 34 00:02:39,220 --> 00:02:44,530 Now of course we need to make sure that our action carries token and userId, so in the action creator 35 00:02:44,530 --> 00:02:51,970 in the end of sign up here when I dispatch the sign up action, we need to add a token field and we need 36 00:02:51,970 --> 00:02:55,300 to add a userId field. 37 00:02:55,470 --> 00:03:03,670 Now the token can be gotten from the response data, there it's that ID token and the same here, resData 38 00:03:03,670 --> 00:03:09,250 is not ID token but it's localId and you see that here in the log, localId, 39 00:03:09,280 --> 00:03:16,530 this here is the userId and if you scroll up, ID token, that's the token. So that's what I dispatch here 40 00:03:17,070 --> 00:03:21,140 and we can just copy that and use the same, almost the same for logging in, 41 00:03:21,150 --> 00:03:28,140 the only thing that needs to change is this identifier and you could even unite login and sign up to 42 00:03:28,140 --> 00:03:34,800 one combined authenticate identifier let's say because in a reducer, we're doing the same thing anyways. 43 00:03:34,920 --> 00:03:40,200 So I just have it split up here to be clear that we have two different things in the end but the update 44 00:03:40,200 --> 00:03:44,420 is the same, so we could definitely combine these two action types. 45 00:03:45,250 --> 00:03:48,970 So with that, we're now storing the token and that's nice 46 00:03:49,330 --> 00:03:51,990 but what do we need this token for again? 47 00:03:52,150 --> 00:03:59,700 We need that token which we are now storing to access our API and for that, let's go to Firebase and to 48 00:03:59,700 --> 00:04:00,870 database. 49 00:04:00,870 --> 00:04:05,940 Keep in mind that when we set up this database, I mentioned that you should start in this test mode if 50 00:04:05,940 --> 00:04:11,370 you remember. What this did is that it set up certain rules and you can check those if you click on the rules 51 00:04:11,370 --> 00:04:15,810 tab. This controls who can read and write to your database 52 00:04:15,810 --> 00:04:20,730 and right now this is both set to true which means everyone can read everything and everyone can write 53 00:04:20,820 --> 00:04:21,930 everything. 54 00:04:22,230 --> 00:04:32,630 That's of course typically not what you want, instead here I'll set both to auth unequal to null which 55 00:04:32,630 --> 00:04:39,200 might look strange and this should be double quotes by the way here but this is Firebase syntax and 56 00:04:39,200 --> 00:04:44,480 you can learn more about the rules here by clicking on learn more or simply google for Firebase real 57 00:04:44,480 --> 00:04:46,960 time database security rules. 58 00:04:47,000 --> 00:04:53,000 What this tells Firebase is that only authenticated users, so only users who send the request with a 59 00:04:53,000 --> 00:04:57,400 valid token should be able to read and to write. 60 00:04:57,560 --> 00:05:00,080 Now you could even argue that Redux should always be allowed, 61 00:05:00,110 --> 00:05:06,710 we could set this to true and you could even be more specific regarding the rules so that you say Redux 62 00:05:06,710 --> 00:05:07,970 from products is allowed, 63 00:05:07,970 --> 00:05:09,770 Redux from orders is not 64 00:05:09,800 --> 00:05:13,200 but again that's something you can check with the official docs. 65 00:05:13,370 --> 00:05:18,950 I'll go with the setup where Redux is always allowed but writing is not. 66 00:05:19,010 --> 00:05:22,160 So now for writing, we need a token, 67 00:05:22,160 --> 00:05:28,640 otherwise we'll face a problem. If we login here and we're storing the token but we're not appending 68 00:05:28,640 --> 00:05:30,440 it to requests right now, 69 00:05:30,650 --> 00:05:33,060 you see we can load all data, that's fine 70 00:05:33,320 --> 00:05:38,510 but you'll also notice that if I try to edit this and remove a couple of exclamation marks here, in the 71 00:05:38,510 --> 00:05:45,420 end I get an error and that error is thrown because I'm not allowed to write and Firebase therefore 72 00:05:45,420 --> 00:05:49,190 blocks the access and returns an error response. 73 00:05:49,190 --> 00:05:54,890 So now we need to leverage the token which is stored in a reducer and actually append it to our outgoing 74 00:05:54,890 --> 00:05:56,360 requests. 75 00:05:56,360 --> 00:06:00,940 Now for that first of all, we need to register this reducer in our root reducer, 76 00:06:00,950 --> 00:06:08,300 so in the app.js file, we need to import it, we need to import the auth reducer from the store and there 77 00:06:08,300 --> 00:06:14,780 the reducers folder and there, the auth file and add it to combined reducers, maybe be here with the auth 78 00:06:14,780 --> 00:06:20,030 key but of course you can use any key you want. That will allow us to then leverage this and access this 79 00:06:20,240 --> 00:06:26,360 token but now we need to attach it to the outgoing requests, for example for products we need to attach 80 00:06:26,360 --> 00:06:29,450 it to the request we send for updating products, 81 00:06:29,510 --> 00:06:38,090 so that would be this request here. Now the way you append a request in Firebase can be found in the 82 00:06:38,090 --> 00:06:44,570 official Firebase docs for the real time database user authentication here, there in the end what you 83 00:06:44,570 --> 00:06:52,640 learned is that you can append a token to your outgoing request simply by adding that auth query parameter 84 00:06:52,760 --> 00:06:55,540 at the end of your request URL. 85 00:06:55,790 --> 00:06:59,690 So here in the end, we need to add question mark of equal 86 00:07:00,080 --> 00:07:06,160 and then here, we need to have our token. Now how can we get access to the token here? 87 00:07:06,180 --> 00:07:12,790 We're in the action creator which means we have no easy access to the store here, to the Redux store 88 00:07:13,070 --> 00:07:20,390 or do we? Redux Thunk, that nice package which allows us to write this syntax with that function that 89 00:07:20,390 --> 00:07:24,720 receives the dispatch function, that actually gives us something sweet. 90 00:07:24,800 --> 00:07:30,860 We can also change this function a little bit and not just get dispatch but get a second argument as 91 00:07:30,860 --> 00:07:35,250 well which is another function which gives us access to the Redux state, 92 00:07:35,510 --> 00:07:43,230 so we get access to the current state of our Redux store. So if I console log the result of get state 93 00:07:43,230 --> 00:07:45,300 here, let's see what that gives us 94 00:07:45,300 --> 00:07:51,860 and to avoid errors, for the moment, here I'll just add an empty string so that we can test this code. 95 00:07:51,870 --> 00:07:56,400 Of course, this will not work but we'll fix it soon, so let's see what's inside of that state if we execute 96 00:07:56,400 --> 00:07:56,700 this. 97 00:08:00,000 --> 00:08:00,540 So 98 00:08:00,570 --> 00:08:03,660 time to login again real quick 99 00:08:04,550 --> 00:08:09,010 and then go to the admin screen and try editing this which of course still will fail 100 00:08:09,970 --> 00:08:13,300 but that doesn't matter because now if I do click here, 101 00:08:13,420 --> 00:08:19,690 yes it fails but what you'll see is that here in the log, what we get is a full output of our complete 102 00:08:19,780 --> 00:08:22,270 Redux store. This is our Redux store, 103 00:08:22,270 --> 00:08:28,570 we get an object with our auth state slice which has yet another object with our token and with the user 104 00:08:28,570 --> 00:08:34,880 ID, our card state slice, our orders state slice and our products state slice. 105 00:08:34,960 --> 00:08:40,540 So this allows me to get access to my Redux store and get access to the token, so the token can be fetched 106 00:08:40,540 --> 00:08:48,060 by executing getState.auth.token because this gives us access to our full Redux store, 107 00:08:48,070 --> 00:08:53,890 this then gives us access to the auth slice and this to the token property which we're managing in that 108 00:08:53,890 --> 00:08:59,810 auth slice. And now in the products action creator, 109 00:09:00,090 --> 00:09:09,440 we can add this token here in the end. So here we can just replace this string with the token variable 110 00:09:09,440 --> 00:09:11,600 which holds our token 111 00:09:11,600 --> 00:09:17,330 and now if we save this, with this little change, if we now login again and later we'll also change this 112 00:09:17,390 --> 00:09:20,000 such that we don't constantly need to relogin, 113 00:09:20,000 --> 00:09:27,490 no worries. If we log in again, we go to admin, click on add it here and now we try this, 114 00:09:27,710 --> 00:09:33,800 this works again because now the token is appended, Firebase validates it and determines that it's valid 115 00:09:33,830 --> 00:09:35,890 because of course we haven't mingled with it, 116 00:09:35,900 --> 00:09:39,170 it's a valid token and therefore this just works. 117 00:09:39,200 --> 00:09:43,190 Now we don't just need the token when we update our products, 118 00:09:43,190 --> 00:09:48,410 we also need it when we add a new product. So I'll copy that logic and add the same logic here, when we 119 00:09:48,410 --> 00:09:54,310 create a product, I get my token with the help of that second argument which we can get here if we need 120 00:09:54,310 --> 00:09:56,330 it, the get state function 121 00:09:56,440 --> 00:10:03,320 and this allows me to change these single quotes to back ticks so that I can conveniently add that query 122 00:10:03,320 --> 00:10:09,530 parameter here at the end with question mark of equals and equal that to my token. 123 00:10:09,530 --> 00:10:15,300 So now we can create a product and update a product, deleting of course also is a write request, 124 00:10:15,410 --> 00:10:22,430 so for delete product I'll do just the same, get access to my store with the get state function here and 125 00:10:22,430 --> 00:10:29,130 then also add question mark of here at the end and add the token. 126 00:10:29,300 --> 00:10:30,290 So that's one thing. 127 00:10:30,320 --> 00:10:36,260 Now in the orders, it's a similar thing, there for fetching, we don't need it but for adding we do because 128 00:10:36,290 --> 00:10:38,260 adding is a write operation. 129 00:10:38,480 --> 00:10:45,110 So there, we get the state if we want to, we can extract the token from there with the same approach as 130 00:10:45,110 --> 00:10:52,880 before and we can append this here and there, we'll actually also need the userId soon, so we'll take 131 00:10:52,880 --> 00:10:54,860 care about this in the next lecture 132 00:10:54,860 --> 00:10:57,810 but for now, just make sure you append the token everywhere 133 00:10:57,890 --> 00:11:02,570 and now let's see how we can also make sure that orders actually really belong to our user.