React Authentication Crash Course With Firebase And RoutingMar 01, 2022
this video will cover everything you need to know about
authentication, we'll cover signing up and logging in, we'll cover how to reset passwords via email, how to update passwords within an app, how to create authenticated routes and the best of all tons and tons of best practices you can use to make your
authenticationworkflow better than ever and if you want to take your
reactskills to the next level be sure to check out my full react
coursewhich is linked down below in the description below let's get started now welcome back to web development made simple my name is kyle and my job is to make the web simple for you so you can start building your dream project sooner so if that sounds interesting be sure to subscribe to the channel for more videos like this now to get you started i want to give you an overview of everything we are going to create how can to see we have this login page we can login we click forgot my password and then we can sign up to let' If we create a new account we're just going to say test at test.com enter a password for example , only the password is ok here, we'll just have this as test222. now we have our email here we can update our profile for example we can change our email to tests333 instead click refresh and you will see that will update if we refresh the page you will notice it keeps us logged in and we can close session come here test 333 on test.com and we enter the correct password and we can login successfully we can also click on forgot password type that email 333 on tests.com click reset password and it will send us instructions to reset our password on our email so now let me show you exactly how to do this the first thing you're going to want to do is set up
firebasebecause we're going to be using
firebasefor all of our authentication if you want to use your own custom auth server you can create your own code we're going to write on the front-end it will work with any authentication server. cation you want to use is super flexible but for our case we are going to use firebase because it is very easy and free as you can see I already have the auth demo here that I was using for that but we are going to create a whole new project and we can enter any name we want we're just going to say here test authentication and we're going to want to have we're going to have two different environments like a development environment so we're going to say we're not actually developing here and then we're also going to have a production version and this will keep our site much more secure so we're going to create that development version here we just click continue here it asks if we want Google Analytics we don't need this for this project we can click create project it'll just take a couple of seconds it'll set everything up behind the scenes and we'll create our project and the important thing to keep in mind as I said you're going to have a version of production and a development one of this so whatever you do on the development version you should also do on the production version to make sure they're both in sync with each other so there we go that's complete let's click continue and here we are and the first thing we want to do as we're going to deal with authentication is on the left hand side there's this authentication tab click on that and it'll bring take us to our authentication section you can see it's not yet we have users we need to go to our login methods and we want to enable as many login methods as we want as you can see there are many different ways to login for ours we're just going to use email password because I think that's the easiest for most people and that's most likely what you're going to be using on your website, just click we want to enable this at the top, click I click save and now we have email authentication setup and I'm going to sh Now you know the reason why we actually use a dev and production server here as you can see down here we have authoritative domains so we can make requests to this firebase you already know the auth server using localhost or this url which is the url for our current project and the reason why we have a production version and a development version is a development version if we want that localhost is allowed but our production version we're going to remove localhost so other people can't access our production firebase from their localhost and possibly know to create malicious accounts so now the next thing I want to do is create the version of production you know so let's go back to firebase here we have our development let's go in here and we'll say out of production and then we can cli c go ahead we don't need google analytics and we'll create this project now that's done we can just click continue here do the exact same thing we went into authentication we're going to wa No click login methods and we want to make sure that we enabled email and password and importantly since this is our production environment we're going to get rid of this localhost here because we don't want people to build access via localhost so now you can only access through our own server, so now that we've got that set up, let's go back to our development version here because we need to get all the different API keys that we're going to use to interact with. with this to do that let's go to the project overview tab on the left and here we can say we want to add a web app so we'll click web and we can name this whatever we want for example we can just say development authentication it doesn't really matter what you call it and we can also set up the hosting from firebase if we want to I'm just going to skip this step we'll just click register app here and then once it loads you can see down here we have a bunch of different configurations n configurations we need to copy into our app and you'll want to use your own configurations here because I'm going to delete this account after I'm done so none of these actual keys will work for you so make sure you use your own configuration settings when you're setting this up so now that we've done that let me push this to the side here so you can We are going to use it and on the left side of my screen I have the visual studio code open and all I have done is run the create react boilerplate as you can see I haven't changed anything here and the first thing I want to do is set up a file which will hold all these settings for us and an easy way to do it with react is to set up an env file so we can say dot env dot and these will be all our local environment variables that we don't want to send to our server because we don't want them inside our actual version control, so they will stay locally here and not today. and go to our version control which means we can use all these different dev keys here so let's make sure to set values and when you set environment variables in react they should all start with the react underscore application and then we can put whatever else we want here so we can say, for example, that the firebase api key is the same and then we're just going to copy this api key. come on that's all we need inside this env variable file done now we can go to the source here we're going to create a new file called firebase.js and this is where we're going to configure firebase but to do that we really need to install the firebase library so we can say npmi firebase and that's going to install firebase for us now that the install is done let me zoom in on our screen here we can import firebase so we can import firebase from the app oops firebase slash and then i also want to import authentication so we can say import firebase slash off and this will be the auth module for firebase so we can do this login record now what we can do is create an app so let's say const app equals firebase dot initialize app and this is where we're going to put all these different configuration values in here, so I'm just going to copy this and in l Instead of hardcoding all these strings as you can see here what I want to do is change this to process dot env dot react app firebase api key so for each of these I'm going to replace this hardcoded value with the value from our env file we just remove all these here we go and then we want process dot env dot and then we want the actual name of each one of these so I'm just going to copy it directly from this environment file here so we have our auth domain is our next get url from the database that we go to to get our project id, our storage bucket, our messaging here and then finally this application id and again the reason we're doing this inside an env file is that way when we're developing we can use all these development environment variables and we go and push this production we can set this to use our s production environment variables without changing any of our code so it's really easy to switch between instances now to use this app anywhere else let's make sure we export this as default and we're also going to export a variable for authentication we'll say const auth which equals app.auth and this is a function so we just call this and this gives us our auth instance so we have auth and we also have just general firebase to use everywhere in our now that we have the firebase setup we can start using it to do the authentication so let's start creating our first component to register and to do that and make our styles look good we'll just use boo tstrap so we can say npmi bootstrap and we also want bootstrap to react so we can say npi whoops sorry react bootstrap here so we want to install boot strap and react to bootstrap so we can do some nice styling and I also want to start by getting rid of a bunch of these files that we don't need we don't need any of these css or test files so let's get rid of all of those then in our index here let's make sure we get rid of all this service worker info get rid of the service worker and the css and then inside our app here we're just going to get rid of everything and we're just going to return the text hello world just so we have something printed on our screen get get rid of the logo and get rid of the css and I'm also going to create a folder called components.
I'm just going to drag our app in here and make sure that within our index we update this to be a dot component slash app and now if we say npm start here we should have our app appear here on the side of our screen if we just close these other two tabs we don't really need them open right now give this a second you can see we get the text hello world so now we have the basics of our reaction. the app is up and running we have the firebase setup the next thing we need to do like I said is that signup component so let's create our signup component so just say signup.js and we'll just write rfc hit enter , that will generate this model for you if you have the rack native snippets es6 es7 react redux graphql I recommend you download this extension it's very helpful so now that we've done it inside here we're going to want to use bootstrap so let's import the bootstrap card to save the foam react bootstrap and we'll also use a form on this page and a button so let's make sure we import them all for now so inside our registry let's start here we're just going to return a snippet here because we're going to want to have a card that contains all of our login information and then under that card we're going to put a div that's going to change us to that login page so we can say the class name here equals w100 we want it to span the full width we want to center the text here we want to space it out a bit from our card and inside here we'll just say we already have a question mark on the account and then this is where I'm going to put our login link I'm just going to write the text login for now because we're not actually setting up the link because we don't have
routingin our app yet but that's where this will go when we get to that point we just don't have that component yet now inside our card here let's open up our card body and inside the body,the first thing i want is to put a nice big header we'll make it a giant h2 this h2 is just going to say oops! sign up like this and let's give it some class here sa y class name and this is going to be the center of screaming text and we want to put a margin at the bottom just to separate it from all the form content inside our header here and speaking of which let's move on to our form and here we go inside the form we're going to need to have an email field a password field and then a password confirmation field so first we're going to make a group of form points and within this group we're going to give this an email id here because this will be our email group and we want to have a label and this label will be for email so we'll say email and we also want to have our control so dot control form this will have only one type of email and we'll make sure that it's required and we can close it and another important thing is that this will have to a reference we'll use references for this so we'll say email reference this is so we can get the value when we actually need to submit our form so there we go we've done that let's just copy this a couple times because we're going to have one for our password and this will just say password and type here is password and of
coursethis is a password reference there we go and down here this is going to be password confirmation here we're going to say password confirmation password type and this is going to to be our password confirmation ref so password confirmation ref there we go and that's pretty much all we need for this form just by default so let's keep this here actually we should probably put the button on this form as well so we're going to have a submit type button this will just say sign up and let's make sure we have a class name here that it will be w 100 oops w 100 which will make this button span the width of the page so now with that done we've got our button created we've got our form created let's render this inside our app so here instead of hello world let's just say register auto close this here we go and now while it's compiling hopefully it should show up here and of course it didn't and that's because these references don't exist obviously so let's create those references from react we're just going to import use reference and we're going to create those references so we've got an email reference, whoops, email reference, use reference and we're going to copy this because we're going to have one as a password and we're going to confirm our password now hopefully those errors will go away and you can see that we have our email, our password, password confirmation, our sign up button and lue go this link down here but none of our styles are being applied in our index.js we need to make sure to import bootstrap so we can say bootstrap slash dist slash css bootstrap dot min dot css now if we save you should see all bootstrap styles which we're going to apply and there we go we've got our signup form in so the signup form looks a little better so it's not cluttered in full width so it's actually centered on our page we can go into our app and instead of just having our registration component here, we're actually going to render a little bit more.
The first thing we are going to render is a container. we can say the container puts the record inside here and let's make sure to import it so we're going to import the container and we're going to get it from react bootstrap and this container here will have some classes. so we'll say the name of the class, we're going to put the flexbox class here and we're going to center align our elements, that'll give us that vertical centering, we're going to center justify our content, which will give us that horizontal setting and then , to make sure it spans the full height, what we want to do here is just have a style and the style will just say that the min height equals oops does not equal going to be 100 vh now if we save this you should see that now this looks nice but of course it's next to each other because the screen flexes so again we're going to wrap this inside another div this will have a class name of w100 just so it spans the full width and then we're going to give it a max width so we're just going to say here that a style will have a max width wow max width that's going to be 400px we don't want it to be any wider than 400px close that and then we'll put our record inside of here and now if we save you can see that even if this page gets wider and wider it will never be more than 400px wide and as you can see when our screen gets small enough it just shrinks. with some nice padding on the side which is exactly what we want so now that this looks really good we can go ahead and set up our authentication and to set up all of the authentication for the app we're going to use a context because we want to be able to access our current user anywhere in our app, so we're going to create a new folder called context and inside this context folder we're going to create a context called authcontext.js.
We're going to use the same rfc trick just to set up the boilerplate for ourselves, but we don't want this. to be a default export we're just going to make this a normal export it will actually cancel the provider so now from here what we need to do is create an auth context which will be equal to react dot create context y what we want to do is use this context inside our provider so we can say authcontext.provider and we want to return it like this and we're going to receive children inside our auth provider and we're going to render put them inside here and if you're a bit confused by this pattern i'm using i have a whole video tutorial that covers context exactly like this so i'll link it in the cards and description below lastly we're going to create another function that allows us to use this context so we'll say use off this is just going to return use context whoops context of this auth context let's make sure to import the use context of react so that ah now we have access to our authentication context through this use the authentication hook and we have our authentication provider down here which will return a value and this value will contain all of our information that we want to provide with our authentication so we will say that the constant value equals an object and inside here we want to store a current user which is going to be the main thing we want inside here and we're going to handle that with state so we'll say const current user and set current user equals to use default state, we're just going to have no user at all so it's completely empty and import the using state so now that we have our auth provider set up where we have a current user and return it within this provider to use it anywhere in our app we actually need to set it for this current user actually d is set to th The current user because right now this doesn't do anything so we're going to use firebase to do it so let's import that firebase auth module we just created so we can say dot slash firebase that's this file from firebase here we have that auth module and within our auth context we are going to use that auth module to login a user so we are going to create a function called login this will take an email and a password and actually instead of logging in it will sign up which will take an email and password and inside here we're going to say auth.create user with email and password and here we just pass the email and password and this will return a promise that we'll return when we can actually use this within our registry here to make sure that this actually worked correctly for so that we can give an error message if there is a failure or redirect the user to the correct page, so here we go, we have our log. done completely and you'll notice that we're not actually setting the user when we're creating them and that's because firebase actually has its own way of notifying you every time the user is set, there's a method in here called auth. what it's going to do is allow us to set the user from here so this will be the current user or it will be null so we could say set the current user to this user and now we have our user set to whenever we call this create a user with email and password, it will call the current user and set that user for us.
It's important to note though that we don't want this to be inside our render we want this to be in a use effect because we only want to run this when we mount our component so let's say use effect drop down here put this inside a use effect so that it only runs once and we'll make sure to do that by putting the empty parenthesis here for an empty array and we also want to make sure to unsubscribe from this w When we're done we can say that const whoops const unsubscribe is same to know, the state change here and the reason why we get this unsubscribe here is because this function actually returns a method that when we call this method it will cancel it. outside of the state change event, so we can say unsubscribe again and this will unsubscribe us from this listener here every time we unmount this component, which is exactly what we want, so now to use this register, let's pass that in as part of our you know context here so now we have our record and our current user and within our record we can import the usage we got from that dot dot slash authentication context and we can say that the constant log will be the same. to use authentication so we're just pulling that registration function directly from this authentication context here so we can use that as part of our form so we can say that the function handle the submit is going to take an event that we just want to avoid the default to prevent our form from updating like this and then we can call that registration function and we're going to pass in our email and our password so we'll say the current point value of email ref and the current point value of the password value that will actually do the registration for us, but we want to make sure that we actually check if this succeeded or failed.
You'll also notice that we're getting this error here because we need to make sure that we wrap everything inside of that auth provider so we'll say auth provider and we're going to wrap everything inside of that so we have access to that context and just make sure to import that here which got rid of that error for us which is what we want so now inside our log let's do all our different validation checks. The first thing I want to do is see if our two passwords are the same, so the password ref.current.value is equal to the password confirmation. ref.current.value i want to see if these are not equal to each other because that means we have some kind of error they are not equal so we can go back and we want to set an error so let's create a new const error state and set error equals use state and we're going to have an empty string here because we're not going to have an error by default so we can say we want to set our error to something along the lines of passwords mismatch just so the user knows the passwords they entered don't match and the reason we come back here is because we don't want to continue with the registration we just want to exit the function immediately because there was an error now what we can do is just set up a test capture for this log here because this is an asynchronous event so if we do an asynchronous function we can wait for this and then it will wait for the log to finish and if there is a failure enter á in this catch block here where we can set our error so that we can say that an account could not be created like that and then of course we just want to make sure that before we try anything we want to set our error back to an empty string so that we don't have any errors and we also want to set up a loading state that way when we're signing in for the user we disable this button down here so they don't automatically keep clicking the button and accidentally create multiple accounts at the same time that would be very bad so we'll say set the upload to true and then after it's all done it's going to set the upload to false this will happen after it's donewaiting for the log, that way it's down here after this fetch attempt, so we're going to create that state for the upload and set the upload and of course default. it's not loading at all so we're going to set it to false so now let's use this submit handler as our form's submit so we'll say the submit equals the submit handling here in our button we're going to set our status disabled equal to loading because if we're currently loading I don't want to be able to resubmit our form and then lastly here what I want to do is just put a nice little error so we'll say if we have an error then I want to display a alert from those bootstrap alerts I want this to be the danger variant as this is a bug and I just want it to have the text error inside it so let's make sure we import the alert here save this and hopefully no there is no mistake. here so let's see if this works let's write a random email we're going to write a password here and a password here but they're going to be different passwords so we should get that nice error so we click register it says that passwords don't match that's exactly what we want now let's try to create passwords that do match so we'll just say one, two, three, four, five, six, one, two, three, four, five, six, click to register and you can see that we do not have any errors. which means hopefully this worked correctly the only way to check this is to see if we have a currently logged in user so we're going to get the user here from our auth context we're also going to get our current user , this is just temporary to see if this worked and within here we're just going to display our current user down here and if we save you should notice of course we're getting an error let's make sure to json.stringify this because this is an object which we need to return a string to react to and as you can see we have this huge json object for our current user and what we could do is get our email so we can say current user. email save that and we should get the email we signed up with and of course it says can't read email owned by undefined this is really cool it's important to understand that our current user when we refresh our page is actually null so let's make sure to do it and currentuser.email which just makes sure there is a current user and then it's checking to get the email as you can see that's the email we signed up with now it might be ask how the current user starts as null and then sets itself and the way it happens is that firebase actually sets local storage for you sets tokens so you can check that if you have an already logged in user it will connect to that user for you and it will use this on off state but that means it has an initial load state that you need to pr eoccupy so here we're going to have another property called configure load we're just going to set this to false for example sorry yes false here as long as we have a user when this changes it means we're done loading and initially we're going to set that state here of load and set the load we're going to set it to a use state of true so by default we're loading and as soon as we get this first use effect running that means which did the check to see if there is a user so we're going to set our upload to false and down here what we want to do is a sim Please check a little to see if we're uploading because otherwise we don't want to run this , so we'll say loading and children we mean if we're not loading then we render children otherwise we don't want to render children let's just indent a little here, save this and now what will happen is we can go back to our registry we can get rid of this and check here because what will happen is of course we are going to get an error the reason for this is we just need to make sure we set our user before we set up the load now if we save there come on we don't get any more errors and the reason for this is what's happening is we're making sure we don't render any of our apps until we have our current user set up for the first time and if we don't have a current user obviously this will fail because the current user doesn't exist but that's ok let's not actually I don't want this code here this is just for testing purposes so we'll get rid of that curr ent user code here save this again and essentially we have a fully functional registration page but we don't have any kind of
routingwe still want to build a route between our registration page our login page our dashboard where the logged in user goes so let's work on that now using react router to install react router.
We can come here and say npm i react router dom which will install react router for web and while that works what we can do is we can go back to firebase in our demo our development project as you can see here inside the tab authentication for our users, that user that we created is here, so whenever we create a user, we can see it right inside this authentication tab so we can easily verify it. this is working the other nice thing is this dev environment is completely separate from production so this user doesn't even exist in production he's just in our dev environment so now we have that router configured let's go back to ov Come back here to our app and let's set up routing for our app to do that we need to get our router which will be called browser router we're just going to rename it router so it's easier to work with us. we're going to need a switch so we can determine what page we're currently on and a route to determine what route on the page we're going to is coming from of course react to the dom router like this so now we're going to do all of this within here so inside the container inside our auth provider inside this div here let's set up a router and what this router will have is actually our external provider inside it. we'll work so we'll put our provider outside here here we go and then inside this auth provider we're going to have a switch and this switch essentially determines what route we're currently on so let's create our registration route here then we can say path and this path has a path that is equal to the log slash and this is going to have a component that is going to be that log component we can close that path we can get rid of this log here and if we immediately save our app is going to be empty but if we're going to register press enter you'll notice we're on the registration page so now that we have that route set up we also create another route that will be for our user's dashboard so we can just create a route here, this will be an exact path with a slash path, the reason we do exact here is that it will only match this slash path, ess ially an empty path otherwise no exact would be essentially every single password match because just everything starts with a slash but in our case we only want the things that are exactly a slash so that's what we do exactly and this component here will be a component that we'll call a board and we don't have it created. however we're going to create a simple component called board.js script does a little rfc trick inside here and we'll just say board on this page now if we come here save of course we're getting an error because we need to import that board from the dot bar dashboard now that should be there and if we go to the slash localhost 3000 you can see we're on the dashboard page obviously we don't want to be able to get to the dashboard page right away even though we're just on our page registration to get started now. before we get too carried away with the dashboard page let's start with our login page here so we'll say login and the component will be a login component we'll create now login.js like this and inside our app make sure import that so we'll say here import login from slash login now we have our login component in slash login and if we go to slash login you'll see that it doesn't renders nothing because our login component has nothing inside it if we save this you'll see it's just an empty page so our login component is actually going to be very similar to our registration component.
I'm actually going to copy our entire registration component to our login component and just make sure to change this to login instead of register. We don't need this password confirmation so we'll get rid of that we can get rid of this password confirmation check here and then this final form group for password confirmation obviously we can get rid of it let's change this button to say login we want to change the title this to say login and if we save this hopefully we should see our login page looks very similar to how our sign up page looked but more login oriented and down here we can also change this to say I need an account . this is where we're going to put our login link so let's say link this will come from react router 2 register and we want it to have the registration text so let's make sure we import it from the router import link react from the react path r and now we should have a link down here to go to our sign up page we click on it and it takes us to our sign up page which is exactly what we want let's do the same in our login down here we're going to create i sorry in our log we're going to create a link that's going to go to the slash login and have the text login inside and we just need to make sure we import the react router dom link like so that now we can click login go to our login page click sign up go to our registration page so now let's implement the login page because now it's doing the registration logic we want this to call a login method we also want this error method to say here failed to login so now we create this login which will be inside our using auth so so within our auth context we have our registration function let's create another function called login which again will take an email and password and that's we're going to return auth dot login with email and password and again we just pass the email and password so now we have our login function done let's export that here and the nice thing about it like I said it's very modular if you don't want to use firebase all you have to do is change this login session function to log in to your server for example, just change it in this place and the rest of your app will work fine, so you can do completely fine without firebase all you have to do is change this function and this function here to register now with that done we should be able to login successfully so first create a new user so we know exactly what your email is, we'll say ttt in ttt dot com password it's just password and password we click sign up of course we couldn't sign in let's try again to see if it works we'll click sign up and of course we got another field layout and let's see what's the error we go to the console it says failed to load resource to respond to status 40400 and we go to our network tab here click the record button again we go down here and it says email not found so which is trying to login so clearly what we did was change our records to login yes that's exactly what we did so i want that this is still our registry and it looks like yes we change yes just this so this should stay register this should register we just change the wrong section here this should fail to create an account there we go and now on our login session here is where we want to do the login function failed to login and login here so now we should be able to create an account dot com password password register and nowe get no error so most likely logged in now if we're going to log in we could type you know this auth enter correct password click log in and of course we don't get any error we enter wrong password click start session you'll see we get an error because this account doesn't exist so now what we want to do is when we log in or when we sign up we want to redirect to the dashboard and again this is pretty easy to do with react router we just need to use history it's a nice hook we can use and we can get history from this used history hook so we'll make it say use history and all we can do after we're done logging in if it was successful we could just say dot push bar and this will take us to that dashboard page where you can do the exact same thing on our log history tro. push make sure you get the history wow it equals to use the history and we're going to import it here from this react router dom so now if we log in our user ttt tdt.com password click start session you will see it will redirect us to the dashboard because we successfully logged in as the current user so now what I want to do is make this dashboard a bit more functional right now it just says that the dashboard is pretty much useless so again we are going to use bootstrap for this. to get the react bootstrap card component just like th in and inside here what we want to do is render a fragment and inside this fragment we are going to have our card at the beginning like this and then below our card we are going to use the same trick div we did from login as you can see this div down here we're going to copy this exactly to our dashboard and this will be for logging out so let's get rid of all this extra text this will just be a button that we're going to get from bootstrap and this button inside here will just say log out we want it to look like a link so we're going to say the variant is a link and on click it will be the same to handle the log out we don't have this function, you know, done yet, let's create it here. card we're going to set up our card dot body and again we're going to have a header very similar to what we did on the side of all our other pages so let's just copy this header like this and instead of saying login this is going to say profile we're also going to have the same thing on error we're going to paste this here this is for handling in case our logout fails here so we're going to have an alert lurking on our error here and of course let's make sure get this use state hook so we can use it so const error set air equal to use state and it's going to be an empty string by default there we go alert is undefined let's make sure we import that too oops alert and there we go we have our profile pretty empty right now and we have our logoff button that doesn't do anything but now lastly inside our body let's put our email here we'll put it inside a strong tag e, we'll say email and what we're going to do is print the current user. email put our space in there right and to get our current user we're going to get that from that use off the hook so we're going to get that from off oops dot dot slash context slash auth context and we can say our current user whoops user current is the same as using off there go now if we save you can see our email and we have the email the current user we logged in with lastly I just want to create a link to update our profile so we'll say here we're going to have a link and this link is going to be in the bar update profile link just like that class name is going to be a button and this is a parent button and we want it to take up the full width so we'll say here w100 and the margin top is going to be three just a little space and it says update profile and of course we need to import the link so we'll get it from the react router and if we save it you can see what e have our update profile button right now there is nothing on this page that is perfectly fine we are going to implement that later let's work on our registration however this is much more important so for logging out we are going to get this of our use authentication like everything else because that way, if we want to replace Firebase with something else, we can easily do it just by changing these few features. so we'll say the function log out it doesn't need to get an email or anything all we have to do is say auth log out and let's make sure we return this because it's a promise that's all there is to do to log out and what we have to do is make sure that down here we show our logoff within our context.
Now, what we can do is go back to our board. We can handle this logout by first setting the error. This is to erase our mistake and then we can do. a simple intent to catch where if we get an error we set our error to be equal to fail to log out and otherwise what we can do here is wait for our log out function, log out, come on, so we are going to wait to see if it ends and if it ends we will do that history. win u and push and it will push us to the slash login page so up here we're going to get the usage history and we're going to get const. i'm trying to wait for this inside a function it should be an asynchronous function here we go now we can click log out and you can see it logged us out and brought us back to this log out page but immediately you'll notice something that says that can't read email owned by null is trying to show our dashboard here even though we are on login page react router is trying to show this board and the reason why it is trying to show this board is just because of how the react router works but something interesting is if we try to go to our panel up here we are logged out right now but we can still access our panel we don't want this we want to be redirected to the login page , so to do that we need to change this from a normal route to a private route so we're going to create our own custom class here our own component pair to privateoute.js do that rfc trick here and with this private route really all we want to do is create a container for our current route and all we want to do is get the from there we'll rename it to component uppercase c otherwise the rest of the properties will be here so this is just a wrapper for our current route to get the route of course we'll need to import that route and we need to get that from react router dom and here inside a return we're going to return our route because like i said this private route is just a wrapper around the current route and this route will take all the rest of these props like they would normally be passed to the route the only thing that's different is the rendering , we're going to define our own render, this render takes props and what it's going to do here is check if we have a current user and to do that of course we need that use off hook which creates mos this comes from dot dot slash context slash auth context so we can get our current user which is going to be the same to use auth and down here we can say if we have a current user whoops current user then we just want to render the component that we pass to our class, so we'll say component and pass all these props to it; otherwise if we don't have a current user we obviously don't want to render a current user you know we don't want to render this component because it's a private component so we want to redirect our user and we're going to get that redirect here from the react router so redirect we're going to redirect them to the login page we'll say login with slash and close it so now if we actually use this private route within our control panel here replace this with a private route and we'll import the private route from the dot slash private route save it and of course we're getting an error on our private route and that's just because we need to make sure we return this statement here now if we save you can see that if we try to go to localhost 3000 only, hit enter, it's redirecting us to the login page because we're not currently logged in so we can't or go to the dashboard so now we've blocked this dashboard path by just making this simple private path here now the next thing I want to work on is our forgot password section on our login we should have a little link down here that allows us to go to a forgot password page so we can go down here under our form.
Let's create a div. This div will essentially be exactly the same as this div here. That way it will just be spaced out. kinda we'll just use the top margin three for this one so we've got a nice little div that's going to contain our link to our forgot password page so we'll say link to and this is going to do for forget password and we're going to have the text forgot password question mark save you can see we have a nice little forgot password link down here we click on it and we go to the bar forced forgot password so we're going to create a path for that we say forgot password and our component will forget password we can create now forgot password.js rfc and in our app let's make sure we import the forgotten password from the forgotten forward slash so now we're at that forgot password component if I just render something in this div, click save you can see it appear here and inside this forgot password you guessed it is going to be very similar to all the other sections so it's just copy login for now to forgot password and change some of our names here this should say forgot password like this and we don't need any password information so let's get rid of our password reference get rid of this bunch of passwords here below we're going to change this login button to say reset password we don't need this link here for forgot password but we want a link that goes back to our login page so we'll say login like this keep all this the same just change this from forgot password to login and down here we'll keep this log section complete now if we save this you can see the password reference is undefined let's just see where we are using the password reference it looks like which is probably here that's right we're just commenting on this because we're going to replace this in a bit, so now we can save it you can see it it still says login lets say forgot we'll say password reset there we go there we go and we get our email enter our reset password and we can go to the login page from here and go to our page log from here so we can get to all of our different pages as we need to now let's set this section to do our password for git and of course we need to do that in our auth context so we'll say password reset function and this goes to take in an email for the email we want to reset the password for, and luckily, like all of our other authentication, this is as easy as saying return authentication. reset send password reset email drop an email here and down here we just need to make sure we expose that password reset function within all of our different components so we can get that reset password function and instead of saying here that we want to log in we can wait for our reset password and move on to the email now one of the main things that are different about that is I don't want to change our page when we reset the password so let's get rid of this history.
Hit to get rid of history and get rid of usage history but instead what I want to do I also want to say password reset failed and instead what I want to do here is I want to set a message this will be like a success message saying check your inbox for further instructions there we go our payload can be set to true here our error can be set and we also want to reset our message to an empty string too which is just going to be a state in which c Create here so create a new state called message and a message set like that and it says email is undefined.
This comes from our email benchmark. if this is aemail you see of course it says password reset failed because we don't have any user with this email so let's create a new user with an email and we can get a temporary email to do that we can just use a site called tent mail, for example, this gives us a temporary email to use, so we can copy that, go to our forgot password page, paste that temporary email, and well, actually, first we need to sign up with that email so that can we say register type our password click register there we go we have created our user let's log out lets say oh i forgot my password i wonder what could it be we will click reset password here and if we go to our temporary mail you can see that we received an email to reset our password. opening this gives us a link that we can click on and then we can type in a new password we'll say one two three four five six click save now it says I can log in with the new password so if I go into our app and try of login with that email which of course I don't remember let's just get that from here copy paste that email into one two three four five six click login and now I'm connected to that user with that new password now the last thing we have left to do is show the message to the user to tell them the email you know is being sent this will look like this we could say message we want this to succeed and send a message so now if i close log out just copy this email again log out forgot password press reset password you can see it says check your inbox for more s instructions to reset our password, so we finally create another user will say tt tt. com password password sign up so we are now logged in as this current user and d now we want to be able to update our profile which we don't have a page for right now so let's create a simple component called update profile dot js we can do that rfc trick paste that in there we're going to save that and in our app we're going to create a private path for this because we just want to do this for login this is that bar update profile we don't need this to be exact and we can change our component here to update the profile and just make sure you import that here so now we have our update profile path if we were to put some text here it should display there we go that text appears and just like all our other routes let's copy this directly from our login we're actually going to copy this from our registry because they're so similar we'll go to our profile update l we'll paste it in and up here we're going to say update profile we need to make sure that we're getting our current user from our auth so we'll say current user like this because we're going to use that under our identifier submission we're going to comment out everything here for now because we don't want this to actually do anything yet and now down here we can say update profile, we can go in and say our email will be a default of our current email, so we can say dot currentuser.email, too we can come in here with our passwords and we can give you a placeholder that just says leave blank to keep it the same we're just going to put this in our two password controls like that if you don't actually want to change your password you should leave it at white and it won't change there we go we have our default email and then the markup r position here if we leave our password blank it won't update lastly let's make sure we change this button to say update and then down here instead of saying I already have an account we'll just make this say cancel and it will redirect us . we're back on the board so if we click cancel we're going back on the board and we can click update profile to come back here so now all we have to do is implement this here inside this identifier submission like so that we uncomment all this and figure out how to start from the beginning. what i want to do is check if our passwords are not the same i will set this error it will be exactly the same if we enter a password here and click update and i enter a password here and click update i want to make sure if they are different , get an error so if i save this and make sure i comment out this registry section because we're not actually using the registry and now if i type a password here and a password here that is different click refresh it says the passwords don't match I also want to make sure that this required field is not in our passwords we don't want them to be required that way if I type and I can leave one of these blank for example it still says passwords don't match now the next thing I do What we want to do It's being able to update our email and update our password, so out of context, let's create functions to do that. new password both are pretty straightforward functions we can just say auth dot current user and actually we can say current user dot update email pass in the email and make sure we return this and we can do the same thing down here this is going to say update password and it will take the password because we have to do this individually because of the way it knows firebase works so now let's expose these update email and update password functions so now within our update profile our authentication we can get the update password and the update email functions and now down here we can use those functions so what I want to do is create some promises so we'll say the constant promises equals an empty array and then f lo The first thing I want to do is check if our email is not the same as our email. or current email, so we'll say it's not equal to the current user's email, so if we've changed our email, I want to add that promise, so let's say promises.
I'll pass my email ref dot current.value so essentially what I'm doing is calling that email update function with our current email if our email changes and we're adding this to this series of promises because we want to just do all these promises and then wait until they finish before we throw any errors. I'm going to do something very similar to see if our current password reference point that value exists essentially if we enter a password then I want to do the same thing I want to add a promise here to update the password and I want to get this from our password reference then I do it what i can do down here is just say promise everything to pass in our promise array and this will execute a point and then work that it will execute every time our promise is actually executed as soon as all these p romises finish our point and then it's done they will execute if they succeed so if they succeed I just want to redirect back to the home page so we'll just say the history point push back to the home page if I can spell it right. there we go otherwise if we have an error we can say dot catch inside this dot catch what we want to do is actually set our error so we say set error fail to update account and lastly we can have a finally and what is this finally what we're going to do is set our payload back to false so we just need to set our payload here to true go up here set it to true we need to set our error here to blink so that's our initialization and then down here in our finally this runs whether we succeed or fail we're just going to set our upload back to false so now if I save that I get rid of all this code from test capture down here and i can even remove this async because this is no longer an async function now what i can do is say tt2 click update and of course e we have a field for update Check the account to see what happened, let's just inspect the page here, go to our console, it says error 400, so let's go to our network tab like this, we're going to go back to refresh and click this and see what our error is, it says too old credentials log in again so let's try to login again here we'll just log out and log in tt tt.com the password is password click log in now let's upgrade to tt2 click upgrade and you can see it changed our email so we can also change our password to like one two three four five six one two three four five six update and there we go now if i log in i can say tt2 at tt.com and i want to make the password one two three four five six do click sign in and now all that information has been updated and that's all it takes to create this complete authentication workflow in react if disf you routed this video and want to take your reaction skills to the next level be sure to check out my full reaction course linked in the description below thanks so much for watching and have a nice day
If you have any copyright issue, please Contact