React Authentication Crash Course With Firebase And Routing

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
this video is going to cover everything you need to know about react and authentication we're going to cover how to sign up and sign in we're going to cover how to do password resets via email how to update passwords within an app how to create authenticated routes and best of all tons and tons of best practices you can use to make your authentication workflow better than ever and if you want to take your react skills to the next level make sure to check out my full react course which is linked down in the description below let's get started now welcome back to web dev simplified my name is kyle and my job is to simplify the web for you so you can start building your dream project sooner so if that sounds interesting make sure you subscribe to the channel for more videos just like this now to get started i kind of want to give you an overview of everything we're going to create as you can see we have this login page we can log in we click forgot password and then we can sign up so let's create a new account we're just going to say test at test.com put in a password for example just password is fine here we'll just have this be like test222 we click sign up that's going to log us into our profile we now have our email here we can update our profile for example we can change our email to the tests333 instead click update and you'll see that that's going to update if we refresh the page you'll notice that it keeps us logged in and we can log out come over here test 333 at test.com and we type in the correct password and we can properly log in also we can click forgot password type in that email 333 at tests.com click reset password and it will send us instructions to reset our password into our email so now let me show you exactly how to do this the first thing that you're going to want to do is set up firebase because we're going to be using firebase for all of our authentication if you want to use your own custom authentication server you can create your own the code we're going to write on the front end is going to work with any authentication server you want to use it's super flexible but for our case we're going to use firebase because it's really easy and free as you can see i already have the auth demo right here that i was using for that but we're going to create a brand new project and we can enter in any name that we want we're just going to say here auth test and we're going to want to have two different environments we're going to have like a dev environment so we're going to say actually off development here and then we're also going to have a production version and this is going to keep our site much more secure so let's create that development version here we just click continue here it asks us if we want google analytics we don't need this for this project we can click create project it's going to take just a couple seconds it's going to set up everything behind the scenes and it'll create our project and the important thing to note like i said is you're going to have a production and a development version of this so everything you do on the development version you also need to do on the production version to make sure that 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 very first thing that we want to do since we're going to be dealing with authentication is over on the left hand side there's this authentication tab click on that and it's going to bring us to our auth section you can see we have no users yet we need to go to our sign in methods and we want to enable all of the sign in methods that we want as you can see there's tons of different ways to sign in for ours we're just going to use email password because i find that the easiest for most people and that's most likely what you're going to use on your website just click that we want to enable this at the top click save and now we already have email authentication set up and i'm going to show you the reason why we actually use a development and production server here as you can see down here we have authorized domains so we can make requests to this firebase you know authentication server using localhost or this url which is the url for our current project and the reason we have a production version and a development version is a development version if we want to have localhost be allowed but our production version we're going to delete localhost so that way other people can't access our production firebase from their local host and possibly you know create malicious accounts so now the next thing i want to do is create that you know production version so let's go back to firebase here we have our development let's come in here and we'll say off production and then we can click continue we don't need google analytics and we'll create this project now that that finished up we can just click continue here do the exact same things we go into authentication we're going to want to click on sign in methods and we want to make sure that we enable email and password and the important thing since this is our production environment we're going to get rid of this local host here because we don't want people to build accesses through localhost so now it can only be accessed through our own server so now that we have that configured let's go back into our development version here because we need to get all of the different api keys that we're going to be using to interact with this in order to do that let's go over to this project overview tab on the left and here we can say that we want to add a web app so we'll click on web and we can name this anything that we want for example we can just say auth development it doesn't really matter what you name this and we can also set up hosting from firebase if we want i'm just going to skip this step we'll just click register app here and then once that loads you can see down here we have a bunch of different configuration settings that we need to copy into our application and you're going to want to use your own configuration settings here because i'm going to be deleting this account after i'm done so none of these actual keys will work for you so make sure you use your own config settings when you're setting this up so now we have that done let me just push this over to the side here so we can use this and on the left hand side of my screen i have visual studio code open and all i've done is run the boilerplate create react app as you can see i haven't changed anything in here at all and the very first thing i want to do is set up a file that's going to contain all these configurations for us and an easy way to do that with react is to set up an env file so we can say dot env dot and these are going to be all of our local environment variables that we don't want to push to our server because we don't want them inside of our actual version control so they're going to stay locally here and not actually go to our version control which means we can use all these different development keys here so let's just make sure we set up values and when you're setting up environment variables in react they all must start with react underscore app and then we can put whatever else we want under here so we can say for example firebase api key equals and then we're just going to copy this api key over i'm going to do the exact same thing for our off domain so we can say react app there we go that's everything we need inside this env variable file done now we can go into the source here let's create a new file called firebase.js and this is where we're going to set up firebase but in order to do that we actually need to install the library firebase so we can just say npmi firebase and that's going to install firebase for us now that that finished installing let me just widen our screen here we can import firebase so we can import firebase from oops firebase slash app and then we also want to import the authentication so we can say import firebase slash off and this is going to be the authentication module for firebase so that we can actually do this login signup stuff now we can do is actually create an app so say const app is equal to firebase dot initialize app and this is where we're going to put all these different config values in here so i'm just going to copy this and instead of hard coding all these strings as you can see here what i want to do is i want to change this to process dot env dot react app firebase api key just like that so for each one of these i'm going to replace this hard coded value with the value from our env file we just delete all these here there 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 straight from this environment file here so we have our auth domain is our very next one get the database url we're going to be getting our project id our storage bucket our messaging here and then finally this app id and again the reason that we're doing this inside of an env file is that way when we're developing we can use all of these development environment variables and we go and push this production we can set this up to use our production environment variables without changing any of our code so it's really easy to switch between instances now in order to use this app everywhere else let's just make sure we export this as the default and also we're going to export a variable for authentication so we'll say const auth which is equal to app.auth and this is a function so we just call this and this gives us our authentication instance so we have auth and we also have just firebase in general to use everywhere in our application so now that we have firebase setup we can actually start using it to do authentication so let's actually start creating our first component for signing up and in order to do that and make our styles look good we're just going to use bootstrap so we can say npmi bootstrap and we also want to get bootstrap react so we can say npi whoops just sorry react bootstrap here so we want to install bootstrap and react to bootstrap so we can actually do nice styling and i also want to start by getting rid of a bunch of these files we don't need we don't need any of these css or test files so let's just get rid of all of those then in our index here let's make sure we get rid of all this service worker information get rid of the service worker and the css and then inside of 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 printing out to our screen get rid of the logo and get rid of the css and also i'm going to create a folder called components i'm just going to drag our app into here and make sure inside of our index we update this to be dot slash components slash app and now if we just say npm start here we should get our application popping up over here on the side of our screen if we just close out of 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 react application set up and running we have firebase setup next thing 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 type in rfc hit enter that'll generate this boilerplate for you if you have the es6 es7 react redux graphql rack native snippets highly recommend you download this extension it's super useful so now that we have that done inside of here we're going to want to be using bootstrap so let's just import the card from bootstrap so we'll save foam react bootstrap and we're also going to be using a form on this page and a button so let's just make sure we get all of those imported for now so inside of our signup let's get started here we're just going to return a fragment here because we're going to want to have a card which is going to contain all of our login information and then underneath of that card we're just going to put a div that's going to swap us over to that login page so we could say class name here is equal to w100 we want it to span the full width we want to center the text here we want to space it out from our card a little bit and inside of here we'll just say already have an account question mark and then this is where we're going to put our link to log in i'm just going to type the text login for now because we're not actually setting up the link because we don't have routing in our application yet but that's where this will go when we get to that point we just don't have that component yet now inside of our card here let's open up our card.body and inside of the body the very first thing i want is just to put a nice big header we'll do a giant h2 this h2 is just going to say whoops sign up just like that and let's just give it a little bit of a class here say class name and this is just going to be whoops text center and we want to put some margin on the bottom just to space it out from all the form content inside of our header here and speaking of that let's move on to our form and here we go inside of the form we're going to need to have an email field a password field and then a password confirmation field so we're going to first do a form dot group and inside of this group we're going to give this an id here of email because this is going to be our email group and we want to have a label and this label is going to be for email so we'll say email and we're also going to want to have our control so form dot control this will have just a type of email and we're going to make sure that this is required and we can close that off and another important thing is this is going to have a ref we're going to use refs for this so we'll say email ref this is so we can actually get the value when we actually need to submit our form so there we go we have that done let's just copy this down a couple times because we're going to have one for our password and this is just going to say password and the type here is password and of course this is a password ref there we go and down here this is going to be password confirm here we're going to say password confirmation type of password and this is going to be our password confirmation ref so password confirm ref there we go and that's pretty much everything we need for this form just by default so let's save this here actually we should probably put the button on this form as well so we're going to have a button the type of submit this is just going to say sign up and let's just make sure we have a class name on here which is just going to be w 100 oops w 100 that will make this button span the entire width of the page so now with that done we have our button created we have our form created let's render this inside of our app so here instead of hello world we'll just say sign up self-close this there we go and now while it's compiling it should hopefully render up over here and of course it didn't and that's because these refs don't exist obviously so let's create those refs from react we're just going to import use ref and we're going to create those refs so we have a email ref whoops email ref use ref and we're going to copy this down because we're going to have one for password and we're going to have our password confirm now hopefully those errors are going to go away and you can see we have our email our password password confirmation our sign up button and then this link down here but none of our styles are being applied so in our index.js we need to make sure we import bootstrap so we can say bootstrap slash dist slash css bootstrap dot min dot css now if we save you should see all the bootstrap styles we're going to be applied and there we go we have our signup form in order to make the signup form look a little nicer so it doesn't span the full width and so it's actually centered in our page we can go into our app and instead of just having our signup component here we're actually going to render a little bit extra first thing we're going to render is a container so we can say container put the sign up inside of here and let's make sure we import that so we're going to import container and we're going to get that from react bootstrap and this container here is going to have a few classes on it so we'll say class name we're going to put the flexbox class on here and we're going to align our items in the center that's going to give us that vertical centering we're going to justify our content in the center which is going to give us that horizontal setting and then in order to make sure it spans the full height what we want to do here is just have a style and the style is just going to say min height is equal to oops not equal to going to be 100 vh now if we save this you should see that now this is looking all right but of course it's side by side because that display flex so again we're going to wrap this inside of another div this one's going to have a class name of w100 just so it spans the entire width and then we're going to give it a max width so we're just going to say here a style is going to have a max width oops max width which is going to be 400 pixels we don't want it to be any wider than 400 pixels close that off and then we'll put our sign up inside of here and now if we save you can see that even if this page gets wider and wider this will never be larger than 400 pixels wide and as you can see when our screen gets small enough it just shrinks down with a nice padding on the side which is exactly what we want so now that this is looking really good we can actually move on and set up our authentication and in order to set up all of the authentication for app we're going to be using a context because we want to be able to access our current user anywhere in our application so let's create a new folder called context and inside of this context folder we're going to create a context called authcontext.js we're going to use that same rfc trick just to get the boilerplate set up for us but we don't want this to be a default export we're just going to make this a normal export it's actually going to be called off provider so now from here what we need to do is just create an auth context which is going to be equal to react dot create context and what we want to do is use this context inside of our provider so we can say authcontext.provider and we want to return that like this and we're going to take in children inside of our auth provider and we're going to render them out inside of here and if you're a little bit confused by this pattern that i'm using i have an entire video tutorial covering context exactly like this so i'll link that in the cards and description down 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 just make sure we import use context from react so now we have access to our auth context through this you use auth hook and we have our auth provider down here which is going to be returning a value and this value is going to contain all of our information that we want to provide with our authentication so we'll say const value is equal to an object and inside of here we want to store a current user that's going to be the main thing we want inside of here and we're going to handle that with state so we'll say const current user and set current user is equal to use state by default we're just going to have no user at all so to be completely empty and let's import use state so now that we have our auth provider set up where we have a current user and we're returning that inside this provider to use anywhere in our application we actually need to set it up so this current user actually is set to the current user because right now this doesn't do anything so we're going to use firebase to do that so let's import that auth module from firebase that we just created so we can say dot slash firebase that's this firebase file here we have that auth module and inside of our auth context we're going to use that auth module to log in a user so let's create a function called login this is going to take an email and a password and actually instead of login this is going to be sign up which will take an email and a password and inside of here we're going to say auth.create user with email and password and here we just pass in the email and the password and this is going to return a promise which we're going to return when we can actually use this inside of our signup here to make sure that this actually worked successfully so 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 signup done completely and you'll notice we're not actually setting the user when we're creating them and that's because firebase actually has its own way to notify you whenever the user gets set there's a method here called auth.on off state changed and this is going to take in a user and what it's going to do is it allows us to set the user from here so this will either be the current user or it'll be null so we could say set current user to this user and now we have our user being set so whenever we call this create user with email and password it's going to call set current user and actually set that user for us it's important to note though that we don't want this to be inside of our render we want this to be in a use effect because we only want to run this when we mount our component so we're going to say use effect come down here put this inside of a use effect so it only runs once and we'll make sure to do that by putting in the empty parenthesis here for an empty array and we also want to make sure we unsubscribe from this whenever we're done so we can say const whoops const unsubscribe equals off on you know state change here and the reason that we get this unsubscribe here is because this function actually returns a method that when we call this method it'll unsubscribe this on off state changed event so we can just say return unsubscribe and this is going to unsubscribe us from this listener here whenever we unmount this component which is exactly what we want so now in order to use this signup let's just pass that as part of our you know context here so now we have our signup and our current user and inside of our signup we can just import that use off which we got from that dot dot slash contexts slash auth context and we can just say const sign up is going to be equal to use auth so we're just pulling that sign up function directly from this auth context here so we can actually use that as part of our form so we can say function handle submit is going to take in an event we just want to prevent the default to prevent our form from refreshing just like that and then we can call that sign up function and we're going to pass in our email and our password so we'll say email ref dot current dot value and the password ref dot current dot value that's actually going to do the sign up for us but we want to make sure we actually check to see if this was successful or a failure also you'll notice we're getting this error over here that's because we need to make sure 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 we import that up here that got rid of that error for us which is what we want so now inside of our signup let's do all of our different validation checks the first thing i want to do is i want to see if our two passwords are even the same so password ref.current.value is equal to password confirm ref.current.value i want to see if these are not equal to each other because that means that we have some form of error they're not equal so we can just return and we want to set an error so let's create a new state const error and set error is equal to use state and we're going to have empty string here because we're not going to have an error by default so we can say that we want to set our error to something along the lines of passwords do not match just so the user knows the passwords they entered don't match and the reason we're returning here is because we don't want to continue to do the sign up we want to just exit out of the function immediately because there was an error now what we can do is we can just set up a try catch for this sign up here because this is an asynchronous event so if we do an async function we can just await this and then it'll wait for the sign up to finish and if there's a failure it'll go into this catch block here where we can set our error so we can just say failed to create an account just 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 have no error and also we want to set up a loading state so that way when we're actually signing up 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 loading to true and then after everything is done we're going to set loading to false this is going to occur after it's done waiting for the sign up that's way it's down here after this try catch so let's create that state for loading and we'll do set loading and of course by default we're not loading at all so we're going to set that to false so now let's use this handle submit as the on submit for our form so we'll say on submit is equal to handle submit down here in our button we're going to set our disabled state equal to loading because if we're currently loading we don't want to be able to resubmit our form and then lastly up here what i want to do is i just want to put a nice little error so we'll say if we have an error then i want to render out an alert one of those bootstrap alerts i want this to be the variant of danger since this is an error and i just want this to have the text error inside of it just like that let's make sure that we import alert up here save this and luckily nothing's errored out over here so let's see if this works let's just type in a random email we're going to type in 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 sign up it says passwords do not match that's exactly what we want now let's try to make passwords that do match so we'll just say one two three four five six one two three four five six click sign up and you can see that we got no error which means that hopefully this worked properly the only way to check this is to see if we have a currently signed in user so let's just get the user here from our auth context as well we'll get our current user this is just temporary to see if this worked and inside of here we're just going to render out our current user down here and if we save you should notice that of course we're getting an error let's make sure we json.stringify this because this is an object we need to return a string for react and as you can see we have this huge json object for our current user and what we could do is just get our email so we could say current user.email save that and we should get the email that we signed up with and of course it says cannot read property email of undefined this is actually super important to understand our current user when we refresh our page is actually null so let's just make sure we do and currentuser.email that's just making 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 you may be wondering how the current user starts out as null and then sets itself and the way that happens is that firebase actually sets local storage for you sets tokens so that way it can verify that if you have a user already signed in it'll connect that user for you and it'll use this on off state changed but that means that you have an initial loading state that you have to worry about so here we're going to have another property called set loading we're just going to set this to false for example i'm sorry yeah false here whenever we actually have a user when this changes it means we're done loading and initially we're going to set that state here of loading and set loading we're going to set that to a use state of true so by default we're loading and as soon as we get this first use effect that runs that means it did the verification to see if there is a user then we're going to set our loading to false and down here we want to do is a simple little check to see if we are loading because otherwise we don't want to run this so we'll say loading and children we want to say if we're not loading then we render out the children otherwise we don't want to render the children let's just do a nice little indentation here save this and now what will happen is we can go back into our sign up we can get rid of this and check here because what's going to happen is of course we're going to get an error the reason for that is we just need to make sure we set our user before we set loading now if we save there we go we don't get any more error and the reason for this is that what's happening is we're making sure that we don't render any of our application until we have our current user being set for the very first time and if we have no current user obviously this is going to fail because the current user doesn't exist but that's okay we don't actually want this code here this is just for testing purposes so we'll get rid of that current user code here save this again and we essentially have a completely working sign up page but we don't have any type of routing yet we want to build a route between our sign up page our login page our dashboard where the signed in user goes so let's work on that now by using react router in order to install react router we can just come over here say npm i react router dom that'll install react router for the web and while that's working what we can do is go back over to firebase on our demo our development project as you can see here inside of the authentication tab for our users that user that we created is right here so whenever we create a user we can see them directly inside of this authentication tab so we can really easily verify this is working the other nice thing is that this development environment is completely separate from production so this user doesn't even exist in production it's only in our development environment so now we have that router set up let's go back over here back into our application and let's set up routing for our application in order to do that we need to get our router which is going to be called browser router we're just going to rename this to router so it's easier to work with we're going to need a switch to be able to determine which page we're currently on and a route to determine which route on the page we're going to that's coming from of course react router dom just like that so now we're going to be doing this all inside of here so inside of the container inside of our auth provider inside this div here let's set up a router and what this router is going to have is actually our off provider inside of it i just find that easier to work with so we'll put our off provider inside of here there we go and then inside of this auth provider we're going to have a switch and this switch essentially determines which route we're currently on so let's create our sign up route here so we can say route and this route has a path which is equal to slash signup and this is going to have a component which is going to be that sign up component we can close off that route we can get rid of this sign up here and if we save immediately our application is going to be empty but if we go to sign up hit enter you're going to notice we're on the sign up page so now we have that routing set up let's also create another route which is going to be for the dashboard of our user so we can just create a route here this is going to be an exact route with a path of slash the reason we do exact here is that way it'll only match this slash path essentially an empty path otherwise without exact it would essentially be every password match just because it just everything starts with slash but in our case we just want only the things that are exactly slash so that's what we do exact and this component here is going to be a component which we'll call dashboard and we don't have this created yet so let's create a simple component called dashboard.js do a little rfc trick inside of here and we'll just say dashboard on this page now if we come over here save we're of course getting an error because we need to import that dashboard from dot slash dashboard now that should be there and if we go to localhost 3000 slash you can see that we're on the dashboard page obviously we don't want to be able to access the dashboard page right away though we're just on our sign up page to start now before we get too carried away with the dashboard page let's get started on our login page here so we'll say login and the component will be a login component which we'll create now login.js just like that and inside of our app let's make sure we import that so we'll say down here import login from dot slash login now we have our login component at slash login and if we go to slash login you'll see nothing gets rendered because our login component has nothing inside of 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 signup component i'm actually going to copy our entire signup component into our login component and just make sure up here we change this to login instead of signup 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 we can obviously get rid of let's change this button to say log in we want to change the title this to say log in and if we save this we hopefully should see that our login page is looking very similar to how our sign up page was but more geared towards login and down here we can also change this to say need an account oops if i could spell that right and this is where we're going to put our sign in link so we're going to say link this is going to come from react router 2 sign up and we want it to have the text sign up so let's just make sure we import that from react router import link from react router and now we should have a link down here to go to our signup page we click it and it brings us to our sign up page that's exactly what we want let's do the same thing in our login down here we're going to create i'm sorry in our sign up we're going to create a link that's going to go to slash login and it's going to have the text login inside of it and we just need to make sure that we import link from react router dom so now we can click login go to our login page click sign up go to our sign up page so now let's implement the login page because right now it's doing the signup logic we want this to call a login method we also want this error method to say here failed to sign in so now let's create this login which is going to be inside of our use auth so inside of our auth context we have our signup function let's create another function called login which is going to again take an email and a password and it's going to return auth dot sign in with email and password and again we just pass it the email and password so now we have our login function done let's export that right here and the nice thing about this like i said it's very modular if you don't want to use firebase all you have to do is change this login function to log to your server for example you just change it in this one spot and the rest of your application will work just fine so you can do this completely fine without firebase all you have to do is change this one function and this one function here for signup so now with that done we should be able to log in properly so let's create a new user first so we know exactly what their email is we'll say ttt at ttt dot com password is just password and password we click sign up of course we got failed to sign in let's just try that again to see if that works we'll click sign up and of course we got another field design and let's just see what the error is we go to the console it says fail to load resource to respond to the 40400 status and let's just go to our network tab here click that sign up button again we come down here and it's saying email not found so it's trying to log us in so clearly what we did is we changed our signups to be doing login yep that's exactly what we did so we want this to still be our signup and it looks like yeah we changed yeah just this so this should stay sign up this should be sign up we just changed the wrong section here this should be failed to create an account there we go and now in our login this is where we want to do the login function failed to log in and log in up here so now we should be able to create an account dot com password password sign up and we didn't get any error so we're most likely signed in now if we go over to login we could type in you know this authentication put in the correct password click login and of course we get no error we type in a wrong password click login 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 ourselves to the dashboard and again this is fairly 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 say use history and all we can do after we're done logging in if it was successful we could just say dot push slash and this is going to bring us to that dashboard page you can do the exact same thing in our sign up history.push make sure we get history oops is equal to use history and we're going to import that up here from this react router dom so now if we log in our user ttt tdt.com password click login you see it redirected us to the dashboard because we successfully logged in as the current user so now what i want to do is actually make this dashboard a little bit more functional right now it just says dashboard that's pretty useless so again we're going to use bootstrap for this we're going to get the card component from react bootstrap just like that and inside of here what we want to do is render out a fragment oops and inside this fragment we're going to have our card at the beginning just like this and then underneath our card we're going to use that same div trick we did it from the login as you can see this div down here we're going to copy this exactly over into our dashboard and this is going to be for logging out so let's just get rid of all this extra text this is just going to be a button which we're going to get from bootstrap and this button inside of here is just going to say log out we want it to look like a link so we're going to say variant is link and on click is going to be equal to handle logout we don't have this you know function done yet we're going to create it up here function handle logout just like that it's going to be blank for now so we'll implement this in a little bit now inside of our card we're going to set up our card dot body and again we're going to have a very similar header to what we did inside of all of our other pages so let's just copy this header over just like this and instead of saying log in this is going to say profile also we're going to have this same thing for error we're going to paste this here this is for handling in case our logout fails up here so we're going to have an alert that lurks out our error here and of course let's make sure we get this use state hook so we can use that 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 not defined let's make sure we import that as well oops alert and there we go we have our profile pretty empty right now and we have our log out button which does nothing yet now lastly inside of our body let's put here our email we'll just put this inside of a strong tag we'll say email and what we're going to do is print out the current user.email put our spacing in there properly and in order to get our current user we're going to get that from that use off hook so we're going to get that from off oops dot dot slash context slash auth context and we can say that our current user whoops current user is equal to use off there we go now if we save you can see our email and we have the email the current user that we're signed in with lastly i want to just 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 going to in slash update profile link just like that class name is going to be a button and this is a primary button and we want it to fill the entire width so we'll say here w100 and margin top is going to be three just a little bit of space and it'll say update profile and of course we need to import link so we'll get that from react router and if we save you can see we have our update profile button right now there's nothing on this page that's perfectly okay we're going to implement that later let's work on our log out though this is much more important so to do log out we're going to get this from our use auth just like everything else because that way if we want to replace firebase with something else we can easily do that by just changing these few functions so we'll say function log out it doesn't need to take an email or anything all we need to do is say auth sign out and let's just make sure we return this because it's a promise that's all there is to logging out and what we need to do is make sure down here we render out our logout inside of our context now what we can do we go back over into our dashboard we can handle this logout by first setting error this is clearing out our error and then we can do a simple try catch where if we do have an error we set our error to be equal to failed to log out and otherwise what we can do here is await our logout function log out there we go so we're going to wait to see if it finishes and if it does finish we're going to do that history.push trick again oops push and we're going to push us to the slash login page so up here let's get use history and we're going to get const whoops const history is equal to use history and there we go cannot you know keyword await we're trying to await this inside of a function it needs to be an async function there we go now we can click log out and you can see it logged us out and returned us to this logout page but immediately you'll notice something it says cannot read property email of null it's trying to render out our dashboard here even though we're on the login page react router is trying to render out this dashboard and the reason that it's trying to render out this dashboard is just because of how react router works but something interesting is if we try to go to our dashboard up here we're logged out currently yet we're able to still access our dashboard we don't want this we want to get redirected to the login page so in order to do that we need to change this from a normal route to a private route so let's create our own custom class here our own component for privateroute.js do that rfc trick here and with this private route really all we want to do is create a wrapper for our current route and all we want to do is get the component from that we'll rename it to capital c component otherwise all the rest of the properties are going to be here so this is just a wrapper for our current route in order to get route we're going to need to of course import that route and we need to get that from react router dom and down here inside of a return we're going to be returning our route because like i said this private route is just a wrapper around the current route and this route is going to take all the rest of these props as if it was normally being passed to route the only thing that's different is render we're going to define our own render this render takes in props and what it's going to do here is check to see if we have a current user and to do that we of course need that use off hook that we created this is coming from dot dot slash context slash auth context so we can get our current user which is going to be equal to use auth and down here we can say if we have a current user whoops current user then we just want to render out the component that we got passed into our class so we'll say component and we're going to pass it all of these props 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 react router so redirect we're going to redirect them to the login page so we'll say slash login and close that off so now if we actually use this private route inside of our dashboard here so replace this with a private route and we'll import private route from dot slash private route save that and of course we're getting an error in 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 tried to go to just localhost 3000 click enter it's redirecting us back to the login page because we're not currently logged in so we can't go to the dashboard so we've now locked down this dashboard route by just making this simple private route here now the next thing that i want to work on is our forgotten password section in our login we should have a little link down here that lets us go to a forgot password page so we can come down here below our form we're going to create a div this div is just going to essentially be the exact same as this div here that way it's going to be just spaced out a little bit we'll just use margin top three though for this one so we have a nice little div which is going to contain our link to our forgot password page so we'll say link to and this is going to do to forgot password and we're going to have the text forgot password question mark save that you can see we got a nice little forgot password link down here we click it and we go to slash forgot password so let's create a route for that we say forgot password and our component is going to be forgot password which we can create now forgot password.js rfc and in our app let's just make sure we import forgot password from dot slash forgot password so now we're on that forgot password component if i just render something in this div click save you can see it popped up here and inside this forgot password you guessed it it's going to be very similar to all of other sections so it's just copy login for now into forgot password and change a few of our names here this should say forgot password just like that and we don't need any password information so we're going to get rid of our password ref get rid of this password group down here we're going to change this login button to say reset password we don't need this link here for forgot password but we do want a link that's going to go back to our login page so we'll say login just like that keep all this the same just change this from forgot password to login and down here we'll keep this sign up section complete now if we save this you can see password ref is not defined let's just see where we're using password ref it looks like it's probably up here that's correct we just comment this out because we're going to replace this in a little bit so now we can save you can see it still says login let's say forgot we'll say password reset there we go there we go and we got our email enter our reset password and we can go to the login page from here and go to our sign up page from here so we can get to all of our different pages as we need to now let's actually set up this section to actually do our password for git and of course we need to do that in our auth context so we'll say function reset password and this is going to take in an email for the email we want to reset the password for and luckily just like all of our other auth this is as easy as saying return auth.reset send password reset email pass an email here and down here we just need to make sure we expose that reset password function inside of all of our different components so here we can get that reset password function and instead of saying here that we want to log in we can await our reset password and pass in the email now one of the main things that's different about those though is i don't want to change our page when we restart password so we're going to get rid of this history.push get rid of history and get rid of use history but instead what i want to do also i want to say failed to reset password and instead what i want to do here is i want to set a message this is going to be like a success message saying check your inbox for further instructions there we go our loading can be set to true here our error can be set and we also want to reset our message to an empty string as well which is just going to be some state we create up here so create a new state called message and a set message just like that and it says email is not defined this is coming from our email ref dot current dot value there we go so now whatever we type in here we click reset password and if this is an email you see of course it says failed to reset password because we don't have any user with this email so let's create a new user with an email and we can actually get a temporary email in order 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 just copy this over go over to our forgot password page paste in that temporary mail and well actually first we need to sign up with that email so we'll say sign up type in our password click sign up there we go we've created our user let's log out let's say oh i forgot my password i wonder what it could be we'll click reset password here and if we go over to our temp mail you can see we got an email for resetting our password we open this up it gives us a link which 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 sign in with the new password so if i go into our application and i try to log in with that email which of course i don't remember let's just get that from here copy that paste that email in one two three four five six click log in and now i'm logged into that user with that brand new password now the very last thing that we have left to do is just to show the message to the user to say that the you know email is being sent this is just going to look just like this we could say message we want this to be a success and message so now if i log out just copy this email again log out forgot password hit reset password you can see it says check your inbox for further instructions for resetting our password so let's finally create another user will say tt tt.com password password sign up so now we're signed in as this current user and now we want to be able to update our profile which right now we don't have a page for so let's create a simple component called update profile dot js we can do that rfc trick paste that in there we go save that and in our app we're going to create a private route for this because we only want to do this for logged in this is that slash update profile we don't need this to be exact and we can change our component here to be update profile and just make sure we import that up here so now we have our update profile route if we were to put some text in here should be rendered out there we go that text is showing up and just like all of our other routes let's just copy this directly from our login actually we're going to copy this from our signup because they're very similar we'll go to our update profile paste it in and up here we're going to say update profile we need to make sure here that we're getting our current user from our auth so we'll say current user just like that because we're going to use that down below our handle submit we're going to kind of comment everything out in 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 come in and say that our email is going to be a default value of our current email so we can say dot currentuser.email we can also come down here with our passwords and we can give them a placeholder that just says leave blank to keep the same we're just going to put this on both of our password controls that way if they don't actually want to change their password they should leave it blank and it won't change there we go we have our default email and then the placeholder 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 having this say already have an account we're just going to make this say cancel and it's going to redirect us back to the dashboard so if we click cancel we go back to the dashboard and we can click update profile to come back to here so now all we need to do is actually implement this up here inside of this handle submit so let's uncomment all of this and let's figure out how to get started the very first thing that i want to do is i want to check to see if our passwords are not equal i'll set this error this is going to be exactly the same if we enter a password here and i click update and i enter a password here and click update i want to make sure that if they're different i get an error so if i save this and make sure to comment out this sign up section because we're not actually using signup and now if i type in a password here and a password here that's different click update it says passwords do not match also i want to make sure this required field is not on our passwords we don't want them to be required that way if i type in and i can leave one of these blank for example it still says passwords do not match now the next thing that i want to do is be able to update our email and update our password so in our off context let's create functions for doing that we'll say function update email which takes in a new email and we'll say function update password which takes in a new password these are both fairly straightforward functions we can just say auth dot current user and we can actually just 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's going to take in the password because we have to do these individually because of the way that you know firebase works so now let's get these update email and update password functions exposed so now inside of our update profile our auth we can get the update password and update email functions and now down here we can actually use those functions so what i want to do is i want to create some promises so we'll say const promises equals an empty array and then the first thing i want to do is check to see if our email is not equal to our current email so we'll say not equal to current user.email so if we've changed our email i want to add that promise so let's say promises.push of update email and i'll pass in my email ref dot current.value so essentially what i'm doing is i'm calling that update email function with our current email if our email changes and we're adding this to this array of promises because we want to just do all these promises and then wait till they all finish before we throw any errors i'm gonna do a very similar thing to see if our password ref dot current that value exist essentially if we entered a password then i want to do the same thing i want to add a promise here for update password and i want to get this from our password ref then what i can do down here is just say promise dot all pass in our array of promises and this is going to run a dot then function which is going to run whenever our promise is actually executed so as soon as all these promises finish our dot then will run if they're all successful so if they're all successful i just want to redirect back to the home page so we'll just say history dot 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 of this dot catch what we want to do is actually just set our error so we say set error failed to update account and then lastly we can have a finally and what this finally is going to do is set our loading back to false so we just need to set our loading up here to be true come up here set it to true we need to set our error here to be blink just like that 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 loading back to false so now if i save that get rid of all this try catch code down here and i can even remove this async because this is no longer an async function now what i can do is i can say tt2 click update and of course we got a field to update account in order to see what happened let's just inspect the page here go to our console it says 400 error so let's go to our network tab just like that we're going to re-update and click on this and see what our error is it says credentials too old log in again so let's just try re-logging in here we'll just log out and we'll log in tt tt.com password is password click login now let's update to tt2 click update and you can see it changed our email to that 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 do the password one two three four five six click log in and now all that information has been updated and that's all it takes to create this full authentication workflow in react if you enjoyed this video and want to take your react skills to the next level make sure to check out my full react course linked down in the description below thank you very much for watching and have a good day
Info
Channel: Web Dev Simplified
Views: 256,769
Rating: 4.9511428 out of 5
Keywords: webdevsimplified, firebase react, firebase, firebase authentication, firebase auth, firebase react auth, firebase react authentication, react auth, react authentication, react authentication and authorization, react firebase tutorial, react js auth, reactjs auth, react js authentication, reactjs authentication, react project, react tutorial, react authentication jwt, react jwt, react auth jwt, react js, reactjs, react login, react signup, react password reset, js, javascript
Id: PKwu15ldZ7k
Channel Id: undefined
Length: 56min 0sec (3360 seconds)
Published: Sat Oct 10 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.