Build A RealTime Chat App With React & Appwrite Cloud

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
foreign hey what's up everybody welcome to this tutorial where I'm going to be showing you how to build out a real-time chat application with react.js and an awesome new platform that I've recently fallen in love with called apprite which is going to be handling the backend part of this application so the purpose of this tutorial is to build out a minimalist application that has a lot of features that you would need in apps today so things like reading and writing to a database handling things like user authentication which we all know can be a real pain to build out from scratch upright makes this insanely easy and things like real-time features like a chat application or maybe you need real-time notifications in your application you're going to see how to do all of this with apprite and react.js on the front end while building out a pretty cool little chat application so if you haven't heard of app right yet it's a backend as a service platform and it comes on the scene as an open source alternative to something like Firebase so it's making a lot of Headway in the markets it's getting really exciting see in this platform take off so before we get into an introduction of what app right is and how it works let's just go ahead and demo our application so we can see what we're going to build before we get started okay so this is what our application is going to look like in the end so we just have this chat thread I opened up two tabs so we can actually demonstrate the real-time capabilities so first of all users can register once they register they can log in so we'll log this user in and let's just go ahead and send a message so we can see this actually appear in real time so just say hey there and if we send this we're going to notice both users got that message so the sender's message looks a little bit different than the receivers so for each user they're going to see that message differently we can just respond we can say hi and that message is transmitted so each user actually has the ability and permissions to delete their own messages so we do limit those permissions so Dennis here can only delete messages that Dennis sent and solanita only has the ability or that trash icon to delete messages that she sent so the application itself is not going to have any direct messaging it's not going to have multiple rooms we're just sticking to one single chat room so we can focus on the crud operations authentication and the ability to send messages in real time okay so let's talk about app right I want to do a quick demonstration of the console here talk about the features and just do a little walk through before we actually get started so before we do that though I do want to summarize what a backend as a service is for those of you that don't know it I'm actually with you I'm relatively new to this world I typically build out my back end with scratch using something like Python and Django I know a lot of people use express JS with JavaScript or node.js and then there's the PHP larville developers and all the other back-end Frameworks that come with it so I'm in that world I totally get it so a backend as a service in my best description and summary of it it's kind of like what it sounds like it's a back-end tool or a tool that allows you to build out the back end without having to build out and manage that entire infrastructure by yourself so things like the database things like file storage authentication you usually get some kind of tool to come with it an SDK that allows you to build out the back end really fast and focus on the front end development so you can build out applications faster and not have to deal with all that back-end stuff and building things out from scratch so it really can make your life a lot easier there's pros and cons to using it we won't get into that but that just kind of summarizes what it is so for upright so this is the upright website let's talk about this so first of all upright as I mentioned before it's an alternative open source alternative to something like Firebase and with apprite we have something called apprite Cloud that we can use that's currently in beta that has just recently come out but you can also set up a local instance of it so this is run in a Docker container you can get that set up and do the entire deployment on your own so for this tutorial we're going to use apprite cloud it's going to make things a lot easier it's a matter of signing up with an account going ahead and building out our application setting up a database and we're good to go so this right here the first thing you'll see is the app right console it's going to give you all the stats to your application we can see all the requests coming into it the bandwidth real-time connections all the databases users and so on so really pretty cool UI here where we can kind of manage everything so if we scroll down let's talk about the features here so first of all as we mentioned earlier you get a database this is a real-time database that we can read and write to we actually have a UI that we can kind of manage everything from we have authentication this is a lovely feature because I usually build out my own authentication so that was really refreshing to use this and then we have file storage so something like an Amazon S3 bucket upright gives us the ability to store media files things like images videos PDFs whatever kind of files we need to store so we also have Cloud functions so we can write in our own custom functionality we won't get into that right now and then a lot of other real-time features so we'll demonstrate some of these later so a lot of the features that uh Firebase has so um yeah it's kind of again it's just an alternative to it so if you know Firebase you should be pretty familiar with this uh that's what upright is so let's go ahead and sign into our console so I already created an account so you go ahead and create an account here we're using apprite Cloud again normally you can set up a local instance of this but we're going to use apprite cloud so first of all we have our project so we can create a project here I already created My Demo we'll actually walk through all of this once we start the tutorial so this is my project here I can see all the stats to it I just set this up before this video and if we look in here we can actually go ahead and go into authentication and see all the users so we just demonstrated that chat application well we can see Dennis and solomita right here so we see the user we can even modify the user if we need we can go ahead and actually update information so we get this whole graphical user interface to where we can actually work with this data we can create teams to set up user permissions maybe you have admins super admins a different type of user permissions that can all be created in your console and then also through the SDK here and we can see usage of each user so we can see how many sessions we have how many times where a user is logged in all that kind of data for the user along with authentication mechanisms so right now we're doing email and password sign in we can do magic URL Json web tokens phone numbers and all these auth providers that go with it so that's our authentication section if we go into databases to create a database it's as easy as naming your database and then once we go into it so I have this development database I created a table or a collection here so we have this collection for our messages if I go in here here we can actually see the chat messages and all the details that go with it so we see the chat messages if we want to add in an attribute so we can actually go into attributes we see we have a body a user ID and a username so these are all strings we can create a new attribute name it whatever we want set the field type and work with this information so that is our messages table here so we can see all the events that already took place you get a lot of information with this and that is the databases so we create a collection create the tables add the attributes and there we go so if we go into functions we're not going to demonstrate this this is where you can create your custom functions here this is where you can manage them we have our file storage so I just created a test bucket here I added an image so here we go I can go ahead and open this image grab that file file URL and here we go so it's kind of hard to see the URL maybe we can try to zoom in here so it's Cloud upright and then my URL to this bucket image so it's kind of like an S3 bucket we can store all this information here so we can go ahead and add new images again this is all done through the SDK this is just our interface to work with things if we need so that is the app right console let's go ahead and set up our react application we're going to start from scratch I'll show you where you can get the source code and then we're going to go ahead and create a new application connect it to our react app and we'll just start building from there okay so before we get started I'd highly recommend you check out the source code provided in the video description there will be a link to the GitHub repo and here you'll find the final source code to the project itself so I'd recommend checking it out beforehand I just review it and use it to compare against your code as you're coding a lawn here there will also be instructions added here on how to get this set up locally so it's a good reference to have as you're coding along and at some point we are actually going to need to go into this CSS folder and just take the CSS from here this is a place where we're just going to copy and paste here I don't want to focus on CSS in this tutorial so we're just going to go ahead and grab this code at some point as we build out our application so make sure you check out that link because we will need it so let's go ahead and just jump into our desktop here and we're just going to set up our react app so I'm going to use Vite you could use create react app this part's up to you so I prefer white as of late so we're just going to do npm create and then we're just do invite at latest so we're going to go ahead and give it a prompt here so it's going to ask us for our project name and we're just going to call this chat Tut so for chat tutorial and we're going to set up a react application and we're just going to use JavaScript so I'm not going to use typescript here so if you're using Vite you're also going to need to go ahead and open up the project and run an install so I'm going to do this from vs code so we'll just go ahead and open up our application go to chat Tut and we'll open up this terminal so this is the project that white just set up for us and we're just going to go ahead and run npm install and this will set up all the installations that we need and once this is done what I'm going to do is just run the server see what we have and then start cleaning up some code so if you're using Create react app I believe it's npm start but we're just going to do npm run Dev with white and that should open our project up on Port 5173 so let's go ahead and check this out see what we have and here is our application so let's let's start cleaning this up here so we'll go into Source app.css we're just going to go ahead and do control all we're going to delete all that save it remove everything from index.css and that should remove the styling and then we'll go into app.jsx we don't need the Vite or react logo we don't need the use State hook and we don't need this count anymore and I'm also just going to go ahead and remove everything between the fragments here so that should leave us with an empty page and at this point what I want to do is just go ahead and create our room page and just add in some text so we see it and then we'll start setting up the back end so let's go ahead and create a new file so this will be in the pages folder that we're going to create and we're going to call this room Dot jsx and I have a code snippet where I can just type in react Arrow function component export it so RAF CE this is called es7 react Redux code Snippets and it's an extension with the vs code that you can use and it just gives me the scaffolding for my component so you can write this out from scratch I prefer that code snippet so we'll just say room we'll add that text in and then we'll bring this into app.jsx import it so we'll import the room and I will add in routing and authentication later but for now we're just going to have one page as we start with the crud operation so the first thing I want to do is set up the back end we're going to render out some messages and then we're going to start creating messages and then we'll build in everything from there as we act add in react router so let's go ahead and check this out here is our room and we are set up okay so at this point we want to set up our back end and then we want to configure our application with apprise so let's go ahead and go into apprite so apprite.io we're going to use a console here so let's just go ahead and create an account sign in and we just saw this so what I'm going to do is create a new project here so we see our demo project what I'm going to do is go ahead and create a new project and we're going to call this tutorial so that's gonna be our project and we do automatically get a project ID we could create this manually but it's just going to Auto generate one for us if we don't set it so we have our tutorial project now in here we get this interface here and we want to create a web app so that's what we're going to use we're going to use the web SDK so go ahead and click here and we're going to give this a name we're going to call this my chat app and for the host name so this is going to be I guess if we highlight it here it's going to be the hostname that we're going to use to interact with our application in a production or local environment so right now it already prompts us to add in localhost later on if you're deploying on versel whatever that domain name is we're just going to go ahead and add that here so for now we're just going to interact with it through localhost and we don't need the port number so we're just going to set the base up here and I want to remove my face or at least move it to the other side so you can see this next part and at this point we just click the next button and this shows us how to install upright and how to configure it so let's go ahead and just copy this to clipboard we'll go back to our editor here we'll turn off our server and let's just go ahead and run this install so npm install app right that'll get upright set up for us and the next step here is to go ahead and import this client object so we're going to copy this to clipboard and what I'm going to do is just add in all my app right configuration inside of a folder called apprite config so we'll just do apprite config with the capital c dot JS and let's bring this in let's go to the next step here and now we have this client object we're going to set up an instance of it and connect to our application so we're going to copy this to clipboard here and you want to make sure you hide this information so you want to put this inside of environment variables for this tutorial I'm going to leave it as is but you do want to hide things like your project or your app ID and so on so we're just going to go ahead and set this up here and then export it because we are going to use it later so we'll just do this as a default export and we're going to export the client object inside of the upright config file okay so there's a little bit more that we still have to do here but let's continue walking through this process and let's see what's the next step so at this point we are ready to go our project is set up and this is our fresh dashboard so to show you how to get back to this project we'll go back to the app right console and here we go we see the tutorial we click on here and we're in the console okay so from here we already walked through databases let's go ahead and actually create a new database a new collection which is going to be just a table in a database and then we're going to we're going to create documents in that collection so those are going to be instances of Whatever item we're adding to that database so typically you have a production level database a development database maybe a testing database so we're just going to pretend that we're already ready to go into production we're going to call this production again we get an automatic generated ID here so we don't have to specify anything here and inside of this database we're going to create a collection and this is going to be our messages table so our messages collection and it's also going to have its own ID we're going to need these values later to reference um as we're building things out so in here what I want to do is just go ahead and actually create a few documents so a few messages just so we can see how things work so we want to create some attributes if you're comparing this to an Excel table these would be like columns inside of an Excel table if you are creating like models if you were using a backend like python or even node.js and express these would be attributes in that model so we're going to create that let's go ahead and we're going to create a body so every message needs a body this value will be a string for the size let's just say the maximum value could be a thousand and we want to make sure that it's required so we cannot create a document without having something in this value now there are some default attributes that are already created and we'll see those um some of those are going to be like created as so it's going to generate a timestamp for when this value was created and there'll be a few others but we'll just kind of see what we need as we go so for now we just have the body and we do want to connect this to a user later so we're going to do user ID and we're going to store a user's ID value so we can get a particular user's messages so I think a user ID shouldn't be more than 100 maybe but we'll just set that to 250 we won't require it because for now we're not going to have any users and let's just say username so we also want to just hard code that value in for now and again we'll just do 250 for the name we won't require it and our document now has these three attributes so only one of these is required so the next step here is let's just go ahead and create a document Let's uh create some messages and we'll just say for the first one we'll say hello world so this UI is really nice to actually be able to work with it and test things out directly in here so if I create a document I can even go back in here view this document I can edit it I can see all this information about it I really need to have this I can see the activity let's see well I guess we don't have anything right now so we'll just go back and let's create one more so we'll just say this was created in the console so why I'm creating this is I want to be able to actually query these items as our first step from our react app so once we connect to our application here I want to first show you how to query items from the database and then we'll see how to add items in here so we have these talk we have these documents now in theory you would think oh I can just create the database and make requests here well we also have to set permissions and we can set permissions at the collection level or at the document level so what I mean by this is if we go into settings here for our messages collection we can actually update our permissions and decide who can do what with our database or with this specific collection so if we look here we have permissions for any user that means anybody can make requests and then we'll specify the types we can say only guest users permissions for users that are authenticated maybe you create a team of admins or so on so different users you can actually give different permissions to so at this point we're just going to say any user can create they can read they can update and delete collections or documents in this collection so this is how we can add this these permissions to a specific collection now what I want to do is I actually want to show you the error that might happen if you forget to set these because I forgot this a few times and I was trying to figure out what I was doing wrong and it was because of this error that I was having this issue so what I want to do is actually remove these permissions run into that error so you're familiar with it when you see it that way it just kind of sticks in your brain so we just removed those permissions from this collection and let's try to query this database so there's a little bit more setup that we have to add in so let's go ahead and go to our documentation and what I'm going to do here is I'm actually just going to follow the documentation so you get an idea of how to use it and then you can use it as you need as you go along here so in our documentation I'm going to change this to White mode I feel like this might be a little bit easier to see it's kind of hard to zoom in because if I zoom in it removes that left column but let's uh let's just zoom out hopefully you can view this part from a desktop and let's go into databases so I want to see how we can query the database for a specific item so we went to databases just want to make sure you can see that and I think what I can do is actually at this point just move my face back to the right here so in databases we have these instructions on how to create list get a single document update and delete so we'll just keep referencing this so let's go to listing listing a particular document so we can actually use this rest API we're not going to do this right now there's a few more steps that you have to do to use that we're just going to use the SDK so specifically we want to use the web SDK so in here we actually get the source code and the details of what we need so in order to list a document we need to provide the database ID and the collection that we want to list out and then there's options on how to pass in search queries and add in different things which we'll work with later so let's see this example request so first of all in order to make this request we need this databases object right here so we need to initialize it then we need to go ahead and call databases dot uh we're in query document so let's go to list sorry I got ahead of myself there we're going to go into databases dot list documents that's the command and we pass in the ID and the collection those are the two required parameters to query our database so let's go ahead and take this databases object and initialize it so I'm just going to copy this right here again use the documentation even in this tutorial it'd be nice to use it so you can really get an idea of what's going on here so we're going to go ahead and create this databases variable let's export it so it'll be a named export and we need to import databases okay so we pass in the client object into databases we created it and we exported it so that's how we make that request what I want to do is also get this database ID and the collection ID so let's actually jump in here and bring those and Export those from this upright config file so we're going to do export const and we're just going to call this project underscore ID so we're going to need a few of these values and that will be a string we're also going to export the let's see the database ID database underscore ID so this will be our production database and we're going to export The Collection ID so we're going to do collection collection underscore ID and specifically this will be messages so we need to get these values so we'll go back into our console and let's grab these values so we have our messages collection so first let's grab the database ID bring that in then we will go into the messages collection grab the collection ID and we also want the project ID so project ID up here and now we should be good to go okay so let's go ahead and actually go to our room and make a request here so we're going to test this out we'll go into room.jsx here and let's just go ahead and import databases and that's going to be from apprite config so it just goes ahead and adds that import we're going to want to add in some state so we're going to use State and use effect and we want to query the database when the page first loads so in here let's just go ahead and call this get data or get messages so we're going to do const get messages and let me just make sure you can see everything because I've done this before where I've recorded and then found out that something was blocked or wasn't recording that's always a pain so let's just go ahead and make this an async function get messages uh what am I doing wrong oh okay so got ahead of myself okay so we have this async function and we want to go ahead and call this on use effect so we're going to use effect and we're going to call this on the first load so we are going to throw in an empty dependency array and we want to call get messages okay so in here we're just going to go ahead and do const response so we want to get that response right away we'll do a weight and we can access databases Dot and let me fix this indentation we'll do dot list documents and what do we need here well we needed the database ID so we'll import that database ID and collection ID of messages so we'll just do database ID collection ID and that should be it so at this point let's just go ahead and console this out and see what we get and remember we're going to get an error so if you get ahead of me here and then pause the video and start trying to debug it well let's not do that because we want to see this first okay so we're gonna go back here let's go into our application let's check this out and let's refresh it oh and I didn't turn on my server so I probably should do that so npm run Dev all right let's see this okay so the error we're seeing here is the current user is not authorized to perform this action or request so you might see this a few times as you're learning how the permissions work with an app right because there's different levels that we can set so the reason why this is working is the type of user that we are well we are we're not a guest we're just any user we don't have any permissions we're not authenticated nothing like that so we're going to go into settings and say okay at this point we want to be able to still make requests it's not safe to give any user create read update and delete abilities maybe we can have them read but we shouldn't have them do all of these things so we'll change this later but for now any user should be able to make all these requests so now if I refresh this this error should go away and here we go we see this response so we see two documents we see a total of two with the array two documents if we look at this object here we see the collection ID we see created at the database ID the ID of the value itself the body that's hello world the user ID which we haven't set and the username okay so this is all great let's go ahead and just render this out and we'll move to the next step so we're going to render this out and then we'll actually start creating items so at this point this is all just going to be some react stuff we want to go ahead and create a messages array we want to have an update function so not set update but set messages you want to have a Setter here for use state and this will be an empty array so what we want to do is when we get the messages we want to just go ahead and render these out we want to set the state so we'll just do set messages and that's going to be response dot documents okay so we have that and in here we can just go ahead and let's create a div around this and we just want to render all messages out so we're just going to say messages dot map and we'll pass in the message itself use an arrow function and we have the message ID so what we're going to do is create a container and with react we always need a key so the virtual Dom can update things so we're going to set the key to message dot ID and the ID has the dollar sign before it so after that we're just going to go ahead and create another div and I'm going to start slowly styling a little bit and with my styling I'm going to have a div with a span tag for the message quality so we're going to do span and we'll just do message dot body so we want to be able to see this and let's actually first render that out so here we go we see Hello World this was created in the console everything's working correctly and let's also create a message header and the header will eventually create it'll store the sender's name and the created at timestamp so we'll go ahead and pass in a paragraph tag and we'll just say message Dot created at and it's going to be an ugly time stamp that we're going to style later but there we go we have our messages and that looks good well it doesn't look good but it's good because we've done some work here so at this point let's just go ahead and grab some CSS let's bring this in let's make this look a little bit nicer and then we'll move on to creating things so if you want to kind of fast forward to this you can if you don't care about the styling but I just want to take care of this so it's more satisfying to work with so inside of our GitHub repo go into source and index.js or index.css and we're just going to copy all of this and I wrote this up pretty quick so if you're a CSS Pro don't don't mock me here I just put this together that's not my specialty um I just did the best I could use some CSS variables and we added that in here so here's all the settings we have some default settings with some fonts colors and so on and what I want to focus on is just rendering out some buttons and The Styling for the messages itself so we have a room container that we're going to set up right now we're going to have the message wrapper so that class message header and a message body okay so let's take this or let's take a look at this so here's our styling and I'm going to jump into my demo code so I can see what I'm doing and then we'll just start piecing this together okay so first of all uh inside of our room let's go ahead and actually wrap this in a main tag and we'll just give this a class name of container and we'll just peek at the output every single time so uh I thought the container was supposed to do something I'm trying to remember what the container did should set a Max width oh I think I'm just so zoomed in that yeah it doesn't Okay so it actually did Center it I'm just so zoomed in that you won't be able to see it so that should Center everything for you and then after that we're going to create a room container so inside of this div right here we want to create another div around this so we're going to wrap this messages output because that's going to have its own wrapper here so let's see we're going to wrap this right now create another div and this is going to have the class of messages container a room container hyphen hyphen container so two dashes and we can just take this closing div and paste this down here so the messages should have their own div okay so here we go we added some more styling and I'll just zoom out for now and inside of the messages themselves we're just going to go ahead and add in a class here and this is going to be message double hyphen wrapper okay we have that and then we have the message header hyphen hyphen header and for the message timestamp let's go ahead and just add this in and this is actually going to be a small tag and we'll just add in a class of message double hyphen actually single hyphen here so I might update the code to be double hyphen so if that doesn't work just make sure to check that out and there we go so it did style that a little bit differently and then the message body so we just want to wrap this and we're almost done with the base styling so I just wanted to set this up here so the message body here let's see this will be message double hyphen body and if you saw in the demo the body here at this point is just going to be red but the sender their messages will always appear with the outline so I wanted to separate those we'll change that up a little bit later if we need but I think that's going to be it for now so we just have let's see the message wrapper I don't want to spend too much time on this messages wrapper okay so that I needed to fix that okay so that looks a lot better so let's move on to creating a message so let's jump into the documentation and see how we create an item so now we can go back to the create request so we have list and we have create a document so in order to create a document we need the database ID so you're going to start seeing a theme we need a collection ID and then the document ID so at this point there's actually a method that we can import and use is called id.unique so we can just import this and it'll automatically generate an ID for us we can create our own ID but this way you get more it's more of a theme with how apprite does things so it's able you're able to stay consistent with that oh and then you also need the data so the payload of the object that you're sending at this point is just giving an object with an attribute of message body or the body of the message and then any permissions we want to set for this and so on so let's go ahead and look at this so we're also going to do databases dot create document and here we go so we're going to run this and then this part's going to be a little bit different so at this point what I want to do is just go ahead and create the function and we're going to call this so we're going to do const and we'll just do handle submit so this is going to be for our form we're going to have a form and when we submit it this is the part that takes care of everything so by default when you submit a form the page usually refreshes so we want to do e.prevent default prevent default we want to make sure that it doesn't refresh that and then we're just going to go ahead and call let's actually set this in a response so we'll do response is equal to await databases dot create document so when we create this document let's actually just go ahead and indent this and we're going to say this is the database ID so we need to send this this is going to send a post request and then we want to pass in the collection ID and at this point Let's see we also want to pass in the document ID so let's go ahead and run a quick import so what we can do is actually import the ID class I believe it's a class the ID class from app right so this is going to generate a document ID for us so we want to pass that in as the third parameter I believe so we can just do ID dot unique pass that in and then we need payload okay so the payload is just going to be an object and I'll set this up right here we'll just do payload and we just want to set the body and that's going to be the message body state that we're about to set so we're kind of doing this backwards here so we're going to set that body so let's go ahead and actually create the state so as we fill out the form here we're going to have a message body values that's going to be that form input field and then we're going to call set message body so we're going to create it and with you state we're just going to throw in an empty string so that's going to be an empty string that's the message body so when we submit it we're sending whatever we have here as the payload to create document to the collections or to the messages collection with this ID with this payload so we're just sending the body at this point and then once that's done what we want to do is just set message body to an empty string because we want to reset that form okay so when do we submit this what we want to do here is we just want to go ahead and create the form just below the room container and above this messages wrapper so let's go ahead and create this form here so we'll do form close this off here and I'm just going to go ahead and pass in the ID of message form and this will give it the styling based off of what I have in that CSS file so message form and that's double hyphen now inside of this form we're going to have an input field that I'm going to wrap in a div and I added a div for styling so we'll just do actually it's not going to be an input field it's going to be a text area I want it to have multiple lines and more flexibility on how I work with this so we have this text area and in the text area we're going to make sure that it's required then we want to make sure that we have a max length and that's going to be can't believe I'm setting this to a thousand but it's going to be a thousand for now we'll leave it there placeholder we'll just say something I guess that's a good prompt I don't know why Timmy when I see say something it almost sounds aggressive it sounds like a street fight to me okay so on change as users are adding in messages or as they're typing what we want to do is go ahead and get that value and we want to update the state here so we're going to do set message body and that's going to be the value of this field so e dot Target dot value okay so on change as they're typing we're going to go ahead and add that in and then we also want to set actually I guess the value can go after this we want to set the value to the message body message body okay so here we update the message body here we message okay there we go talking and thinking doesn't always work too well okay so we have the message body and I think we're good for the form and we also have the input field that we need to add but let's just make sure everything's working okay so here we go as we're typing that all checks out let's see if we have any errors let's go ahead and inspect no errors okay looking good okay so now what we can do is go ahead and add in the submit button so we'll just do a div around this and we're going to do input type of submit and the value will just be send so we'll just do value send and this is all tedious stuff this part you should be familiar with we should be focusing on the app right stuff but we do have to take care of this part so I know that everyone's here to actually see how this works okay so we have that send button do we have an error no okay so the send button doesn't look so good right now so I do have some CSS or some classes that we can add to it so we'll do class name and this is going to be BTN BTN hyphen hyphen secondary okay so we'll throw that in that should give us some styling and I want this button to be on the right which is why I put a wrapper around this and we'll just do class name and this is going to be send Dash BTN Dash Dash wrapper okay so there we go now on submit when we submit this form let's just go ahead and add this in so on submit let's just go ahead and pass in handle submit so when we submit the form let's just make sure everything's good we prevent default take that state pass it in as a payload to create document create the ID we're passing it into the right collection and then we reset it so I actually want to console out the response let's just make sure everything feels good so we should get back the instance of our object when we create it so we'll just do created and then the next parameter will be response let's see what this looks like so we'll just go to inspect okay and if I say test send here we go so it hasn't rendered out here but now we see created and we can see all that information we see the message body test perfect okay so that is how you create an item and the form should be reset so we'll just do one hit send and it clears okay so let's just go ahead and make sure that we actually add this to this array so what we want to do is update the messages array with that new item so this is just going to give us give us back an object so that response so let's go ahead and just do set messages so we want to update the messages array so that's the problem with setting State that's too similar to something else always throws me off here so we have this array we're going to pass in the new response object actually you know what I want to do I always I think it's much safer to do things this way where we have the previous state so we want to set that so give me one second so we'll just do pre State and I believe we can just do the arrow function and then we can pass in the new values that's going to be the response and then spread out the original array I believe that that's how you do it see messages okay so let's test this out we'll just say one send to send perfect okay so it's working now I want to show you one thing here and I want to be able to show you how to sort this response here so right now we're just adding this response to the beginning of the rate which is why it works but we're sorting in ascending order so what that means is if I refresh this the oldest item will always be at the top so what I want to do is invert this to where the newest item is always going to be at the top so right now it's only working because we're manually adding it with this value right here but what about users on the other end so we just always want to make sure to sort that and at this point this is a perfect opportunity for me to be able to show you how this query object works so we're just going to import query and in our documentation if we're in I guess I'm taking ownership with app right but in the app right documentation uh inside of list Let's see we have list documents the third parameter is going to be all the queries I can that we can add and this has to be an array and we're going to use this query class to actually throw those in so what we're going to do is as the third parameter we're going to pass in in Array and we're going to use that query class that we just added in and we're going to go ahead and say query Dot and I believe we can do by descending order descending and we can specify the attribute that we want to order it by and I want to order this by created at I believe that should work so if I save this now if I refresh it I guess that didn't work give me one second figure out why that didn't work so query dot order descend created at let's see am I getting an error let's just check this out Okay so invalid permissions order not allowed okay so I just realized something I believe that next okay so we're creating okay I added this to the wrong area my apologies okay so that is supposed to be the permissions array that we add to create document I need to go down to list so sorry about the hitting about hitting the mic there that might be loud uh let's go ahead and fix this indentation and we'll throw this in as the next parameter here so that should do it so this is in list documents not create documents okay so there we go as we add new items let's just do three that gets added and now if I refresh it it stays that way so if I want to change it I can do order ascending and I believe that's going to be how do you do Ascent you know I'm not even going to try that let's just you get the idea we can re-order that we can also limit queries so right now let's see we have one two three four five six seven eight messages what I could do is I can always just go ahead and add in another value here we can do query so we're not going to talk about pagination but what we could do what I'll do is just show you this limit right here so we'll set this up and I might cover that in another in another video um I can just set this to two so the limit will be two that means we get two messages on every response I can set this to five we'll get five and let's just set it to 20. let's say we want to see 20 messages on each query so that's how we can take care of the limiting and ordering our responses so the next thing I want to do is add in the ability to actually delete a message so what we're going to do is go ahead and create a method called delete message and if we go into our documentation in the databases API there's going to be a section for deleting a document so let me just zoom in here let's see if it messed up my scroll position deleted document so in order to delete a document we have to pass in the database ID The Collection ID and then the document that we want to delete and that's it so the request would look something like this where we just call databases dot delete document and pass in these parameters so let's just go ahead and take this part right here I don't need that response unless I'm trying to air handle later on that would probably be a good idea but for now we're just trying to get rid of that message and let's just go ahead and bring in a new method called delete message that will create so we'll just do delete message and we'll just make this an async function message underscore ID create that Arrow function and we're just going to call databases dot delete document and we'll pass in the database ID The Collection ID and the document ID so the document ID is going to be the message that we clicked on and the way we're going to pass this in is going to be through here so on each iteration and I just realized we have messages dot map messages that should be messaged and I don't even know how that works technically I think that's supposed to throw an error so it looks like it's been working up until this point so it should be message like that so let me just make sure that didn't change any anything or throw any errors okay still looks like it's working cool so what we're going to do here is inside of the header I'm first going to add a button we're going to test it make sure it works and then I'm just going to throw in an icon for some styling we're going to use react feather we're going to bring in like a trash icon so people know instinctively to click on that to delete the message so let's go ahead and create this button let's just throw in an X for now and we're gonna we're just going to do on click and we'll just throw in the function and to be able to pass into parameter we're going to go ahead and wrap this in a function and then call delete messages and we can get the message Dot ID like that so when we click on it we're going to go ahead and delete the message by passing that in this is going to call the delete message function and in here what I want to do is I just want to go ahead and update the messages array so I want to be able to move it or remove it from messages here so we're just going to go ahead and get the messages and see how do I want to do this I think I can just do preview stage or previous state then we're going to do messages dot filter and we're going to filter out this message by getting the message pass in the function here and then we'll just do message dot ID so when the message ID matches or is not equal to the message ID like that so we should be able to filter out all message or filter out the message that we just clicked on so let's see message here let's just test this out let's try it so if I click on this there we go it says filtering it out so we're going through the messages and we're going to create a new array here and reset it and we're just going to go ahead and filter out the messages that are not this message ID so I confuse myself with that filter process I always get filter and map and reduce mixed up here so we filter that message out and it looks like it works successfully no issues in the console so we can actually go ahead and just remove test here so this is the message we'll click delete we'll delete that duplicate and there we go so that's all working awesome so let's go ahead and bring in that icon so we want to make sure this looks a little bit nicer so we'll focus on styling for the next couple of seconds so we'll just look up react feather so react feather has this package for or feather icons has a package for react and we're just looking for the trash icon so we're looking for this one that's trash two and what we're going to do is just go ahead and run and install for react feathers we need to install the library or the package npm install react Dash feather we'll bring this in let's go ahead and start up our server again and we can bring in import trash two from react Dash feather so bring that in let's go back here Let's see we have uh the header oh that's the form okay here we go so all we need to do is just modify this so let's just go ahead and bring in that icon from scratch so we'll just do trash two and then we'll just add in this event listener into this icon and then we're going to give it some styling so if we go back here let's close out react feather here we see this trash icon I just want to make sure it's styled now so we can just add in the class right here let's go ahead and just move this down and we'll just do class name and the CSS I gave this one was delete double hyphen BTN so there we go so on Hover it turns red and that looks a lot better now really quick for the timestamp let's just do this right now while we're here so this should be pretty simple you can change up The Styling if you need but for now we're just going to do new date we're just going to wrap this and we're just going to give it a date and a time stamp so we can just go ahead and do that and then Dot to local string now the reason why I don't like this is because it makes it look a little bit better but we get the milliseconds here and I don't like that but that's not what I want to focus on it's going to bug me a little bit that it's there but I'll leave that part up to you if you want to format that and make it look nicer you can take care of that so what we want to focus on next is going to be that real-time functionality so we want to make sure users get messages in real time so we want to be able to subscribe to different events and then have that data transmitted so let's go ahead and look at the documentation and we'll just get a start there and we'll start building this in and this is definitely one of the things I was most excited about when I started using app right is how easy it made this because I've worked with websockets before and it's no walk in the park to do that so this is really really exciting so if we look at this upright let's subscribe to a series of what it calls channels so these are different channels for example if we look at this example we're subscribing to the file system so anytime an event happens inside of our storage buckets let's say a new file is created or updated in were removed from our buckets we can subscribe to this event and we can get that feedback in real time so it's listening to that event we can subscribe to database events we can subscribe to user account events so let's say a new user logged in or created an account these are all different events we can subscribe to so if we look here we have an account so when something happens with the accounts we subscribe to in this case it looks like all of the events so I'm assuming create read update will not read but create update and delete if we go down here this is an event that looks like it's subscribing to a specific document in the database I'm assuming a right here is that document ID because that's a placeholder right here for the collection ID so we can actually subscribe to a series of events so right now we're subscribing to a document in a collection and the file system and then there's also the ability to unsubscribe to events we'll talk about this in a second once we run into the error I always prefer to create the bug and then fix it so let's go ahead and just copy this code and we're going to modify this so we're going to bring this into our application and the area where we want to subscribe to this event is going to be inside of the use effect hook so let's see right here so we only want to subscribe to the event when we first load the page and when we go to the room specifically other than that I don't care for message events I don't need to see messages if I'm not specifically in this room so I only want to subscribe to one event so we'll remove this array and we can remove that and what I'm going to do is change this to backticks here and then at this point what I can do is go ahead and just change this to the collection ID so we want to listen to the messages collection and we want to listen to events from all the documents in there now if we look at the documentation let's just see how this works so we have the unsubscribe event if we look here this is where I read about the different channels so a list of channels you can subscribe to so all account related events here we go so any create update and delete event to any document in a specific collection so what we need is databases the database ID then we need collections The Collection ID and then documents so let's go ahead and modify this so we're going to do databases and then at this point we can just do Dot and we'll bring in the database ID so we'll just go ahead and do database ID and we're going to listen for all the events we have database ID dot collections and then after this section what we want to do is add in a DOT right there and then Collections and let's see collections dot documents and I think that should be good now we also need to import that client object so inside of apprite config we had the default export as clients so let's go ahead and bring that in so we can go into the upright config section where we imported everything in an upright or the client instance will be outside here let's go ahead and check this out and let's just test this out so at this point I think we should be good to listen for all events with the messages collection okay so let's just go ahead and add in some kind of string here we'll just say real time right here okay we'll save that and let's just see how this works so go in here open up the console see if we have any errors refresh it and let's just say hello we'll hit send and here we go so we see real time right here and we see that response so what I want to do is first of all make sure that this is really real time so I want to make sure that users that are also in this room see this event so what I'm going to do is create another tab here and we'll paste this in and let's just refresh this so right now we only see the response and let's pull up the other tab so when I send a message here I should see not only in my own console here which we won't worry about I want to make sure that the event listener fires off over here for the remote user so let's just go ahead and say hi and we'll send it and look at that this user sent the message and this user received it so that means it's properly working it's all happening in real time I didn't have to refresh anything it all worked so let's go ahead and look at this response here so I need to actually listen for this event and then take the message that was sent and add it to the Dom right so we want to be able to see that message appear in real time for the remote user right now we only listen to the event listener and we only see it in the console so if I click this we see the channels so this tells me about what I'm subscribing to so I'm subscribing to documents that's the I believe the channel type then I'm subscribing to a database specifically this collection right here which is the messages collection I see the ID so I see the all that information about that specific event or that channel that I'm subscribing to then I see the payload so right here from that remote user we sent this message so I see this object we see the payload I see the body it says hello or hi so I'll be able to get this message take it and then append it to the Dom or render it out now what I need to listen for or look for is going to be this events array so I'm still trying to fully understand the details of what's happening I'm looking through the documentation but it looks like this event or events array is telling me a bunch of information about the type of events that fired off and what happened so specifically right now we just created a item right so somewhere in here if we look at index number one we see databases dot collections so we're subscribing to collections documents I see create here so I noticed every single time we're creating an event the create string rate is right here so if I delete a object here remember we're subscribing to create update and delete methods if I delete or hi not Hello if I delete it we should see this event let's see what's going on with my code or did I not refresh that so if I delete hello here we go I see that message in real time and same thing if I go to this channels or events array I see databases collections documents delete so I know it's a delete event so what I need to do is pay attention to delete or create or even update in the future and I want to respond differently so if a user deletes a message I don't want to append a new message to the Dom because I'm just going to get an error if I add a message I don't want to remove a message from the Dom remember this event handler is going to handle all sorts of events it's listening to all of them so what I need to do here is I need to add a condition here and go ahead and listen to those events so let me try to go through this slowly so it all makes sense if we go to the real time documentation here we see the response object for when an event or a document is updated if we look here we have all this information again I haven't studied all these details I just understand based off of examples that I've seen I need to look for this specific string so what I want to do is I need to check and say hey if I'm looking for an update event I need to make sure this string exists in this array if I'm looking for a delete event I should see this string with the end value being delete and if it's a create event this value right here should be create so that's what I'm looking for so I'm getting that response and I'm looking for this specific stream so let's try this so let's go ahead and run through this so we'll just do if response dot events so we're going through the events remember that we just saw that in the console we're going through the events.includes let's go ahead and grab this entire string and there's probably more efficient way to do this but I just want to try it out this way so if the response events array includes databases collections documents and we're looking for create then we can say an item was created so we'll just do console.log or we'll just say a message was created then what I also want to do is I want to listen for delete events so we're just going to remove this real time console here for this statement then we want to look for delete so we're just going to say delete so if that's the event type we'll just say deleted with an exclamation point so we can see it differently so now this will fire off at any event but we want to respond differently depending on the event type so let's try this okay we'll refresh it and let's go ahead and create an item so we'll just say hi or create a message we see message was created and if we delete a message we'll delete hello we see message was deleted the only issue right now is that it's firing off twice but we'll take care of that so here we go we're listening to two different events I keep deleting messages it's all working perfectly fine that's exactly how we needed it to happen and remote users are getting this okay so what I want to do is actually I want to clean this up a little bit actually for now let's just focus on this so what I want to do is actually remove the messages when they're added and then add them when they're deleted so I can just go ahead and go to delete messages and I'm going to comment this out right here and I no longer want to delete messages from this method because all users are simply just going to listen to that event so that means even the sender will also get back that event so this way we can confirm that it happened so we're just going to go ahead and do set messages previous state message Dot message ID so at this point what we can do is instead of the message ID here we're just going to do response dot payload and we can get the ID of the message here so we're going to filter out the message that was deleted so now this will actually occur to remote users and we want to do the same for the create message method here so anytime a message is created on handle submit before what we would do is would get that response and it would update the messages array or the state we want to comment this out and copy it and let's go ahead and bring this up here and we're going to let this event listener right here respond to it so anytime we create a new message for all the users we're going to go ahead and get the previous state response dot previous day so at this point we're going to do response.payload so before we just have the response now we need to access the payload and make sure you're updating the state this way by the way so I know sometimes people update it like this where you can just do that right there and get messages this won't work because what's going to happen is when this use effect is called the array is going to be empty so anytime this method is going to be called what's going to happen is you're going to add the new message but it's the only message you're going to see is actually going to erase your old messages and that's because of when the Subscribe method is called so I just kind of wanted to point that out so keep this at this right here so previous state response.payload and get the previous state this is the more proper way to update this right here okay so let's go ahead and just refresh everything Let's test this out and we're about to get an error and this is going to be where we fix a few things so let's just go ahead and add in hey we'll hit send and look at this so the message was sent twice so we see hey twice and hey twice here so the issue occurs with how use effect is called so use effect gets called twice here so when use effect subscribes what happens is the second time it gets called we subscribe twice to that same event so what's happening is we have two subscriptions to this Channel and then therefore when that event fires off both subscriptions are listening and firing off that event so what we need to do is we need to have a cleanup function that basically gets called anytime use effect is unmounted or our component is unmounted so what we're going to do is we're going to go ahead and create a cleanup function and we're just going to go ahead and unsubscribe to this event so anytime or on the first iteration when use effect unmounts we're going to unsubscribe and then resubscribe on that final iteration so we only have one subscription to this collection so we have this cleanup function inside of use effect and if you look at the documentation it does actually talk about this and or at least it shows you how to unsubscribe to an event and let's just go ahead and find that so here we go so it looks like subscribe will actually respond or return a function in a function that lets us unsubscribe so what we're going to do is we're going to set this value of unsubscribe to the return value of subscribe and then we can call that function to unsubscribe so let's try this so when we subscribe let's go ahead and do const unsubscribe and we'll set that and then on that cleanup function we're going to go ahead and call that again so we're going to save that so this should give us one subscription only to that event so let's go ahead and try this again we'll just say one send and there we go now we get one instance of it then we do two there we go and if I hit delete now let's be deleted and we are updating in real time with no errors I think we're good so yeah that looks like it checks out so let me look at my notes and I think the next section is going to be where we are adding in authentication and routing so let's start taking care of that let's go back into here and the first thing I'm going to do is actually import react router Dom we're going to create a login page so we'll just add in some basic routing and then we're going to create protected routes and we'll start dealing with user authentication so we'll go into pages and let's start by closing all of this out just to kind of keep things clean and we'll create a new file called login page I guess we can call it page we'll just put that in there jsx here and then we'll just do react Arrow function component export and we'll just say login okay so this is our login page for now we'll keep it simple for the router let's go ahead and install react router Dom so what I'm going to do is just open up another terminal we'll just do npm install react router Dom okay so we're just going to set some basic stuff up here you know my leg just fell asleep so I need to readjust here okay so we have react router Dom installed we want to make some imports so first of all we want to import the login page we'll bring that in and then we're going to make a few imports from react router Dom so we want to import browser router and we're just going to do as router and then we're going to do routes and route so bring all this in from react router Dom and we can just wrap all this in our router and then we'll just do routes and inside of routes so we're no longer using the switch statement that's kind of old news by now I think that's last time we used that was in react router 5. so now everything's gonna be a part of routes and we create the actual route here and we can bring in the components so we'll set the path we no longer have to set exact and we'll just do element I believe it's element before ECB component and we'll just do room so room will be the home page so we can get rid of this and we're gonna have a path for the login page so let's go ahead and do this login page and we're going to test this out we're going to have to protect these routes too so we'll create a private route here real soon so let's just make sure the routing is working if we go back here refresh it log in here we go we see the login page and I don't know why this bar is showing let's see minimize this okay there we go and then we have our home page so from here what I want to do is go ahead and create those private routes so I'm going to create a component that's going to wrap any route that we want to protect so let's go ahead and create a new folder and file so we'll make a components folder and this will be private routes so it'll be plural private routes.jsx and that'll be in the components folder we'll just use our code snippet react Arrow function component exported and we want to import Outlet from react router Dom and we want to import navigate and we'll just go ahead and do Dash Dom I think just having react router will work just fine but just to be safe we'll update that so what we're going to do here is we're going to create a component that's going to be or I guess a parent component that's going to be a parent route to any private route so we're going to use Outlet here and we're going to check the authentication status of our user and if we're authenticated what's going to happen is we're going to use Outlet to pass down the routes down to the the child routes from this parent component and if we're not authenticated we're going to redirect our user to the login page so actually wrote an article up about this from using react router 5 where we used to create this component here so what basically it used to do this right here would basically create this private route pass down the children and then we would just redirect our user to the login page if not we would pass down all the child components well in react router 6 because of how router and routes work every single route needs to be a child of the routes component so we could we can't do this anymore and I break this down in this article so I'd highly recommend checking this out it's in the video description so essentially we have to create our component and use Outlet now and we just passed down all the child routes so we're not passing down a component now we're passing down child routes so that's what Outlet does for us so inside of private routes let's go ahead and create a fake user we'll actually set this up in a minute but for now we're just going to say user is equal to false and we're going to use a context API to actually lift up our state and hold the user in there but for now we're going to pretend that our user is follows me we don't have anything there typically this would be something like null so that also works and we're going to say if we have a user then go ahead and pass an outlet here and let the navigation continue down to the child routes if not so if this user is false or this value is not true let's say we don't have a user object in there we're just going to go ahead and call navigate and we're going to redirect the user to the login page and that pretty much sums up the entire component so now to use this and this is just going to help us build out our application to where once we're scaling it up so we're not having to check every single component so we're going to create a route that's going to wrap these so let's go ahead and bring this in so we'll just do import private routes and actually want to put this import above here because any pages that I'm going to be adding in the future we want those down here so when I keep those in order so bring in private routes and now this is the way we wrap our components so let me just pull up my sample just to kind of confirm things so what we're going to do is we're going to create a route here and we're just going to go ahead and pass in the element and the element is going to be the private route so we're going to do private routes here bring that in close off the component and that can be closed off like this if I can actually type here so we have our route and that's going to be the private route component so I can just remove this and fix that so we have our private route and what I do with all the children is I actually pass in this route down here so that's what Outlet lets us do so Outlet just continues this so we check this we go into the private route component if everything checks out the user clears out we go to outlet and that passes us down to this next page and this is where any protected Pages would sit in here any unprotected Pages would be out here so that's kind of the idea I hope that makes sense uh maybe if you already understand this and I'm just over explaining uh but at least people can understand it and kind of get through this part here okay so we have that let's go ahead and check it so we will go into the login page here we go so at this point if I try to go to the home page so let's try to do this we'll remove that and we'll hit enter and it takes me back to the login page now if we set user to true we're still in the login page so at some point we're actually going to say hey if we're logged in send the user to the next page or to the home page so now that the user is true we can log in so the private route works that's exactly what we wanted so everything's checking out and let's go ahead and create or use a context API and actually create and lift up our state so we can get a user from there and then pass it down to all the components where we need it so let's go ahead and do this we're going to create a new folder let's see did I have it structured like this I think I created a context folder so I'm going to create a utils folder so any utility files or components that we have we're just going to put in there so we'll create a new file and this is going to be in a utils file or folder it's a new file utils and then we'll just do auth context dot jsx okay so we have our auth context and inside of our alt context we're just going to use the context API to build this context out and then pass everything down so let's just go ahead and run some imports so we're just going to import create context and this is going to be from react we also want to pass in use State and at some point we're going to need use effect and we want to create the context itself so let's go down to the next line and let me just close this file out so from here I'm just going to go ahead and create the auth context so we'll just do auth context and we'll just use the create context method and then we're going to go ahead and create the provider just directly in here so we're just we're just going to export the auth provider so const auth provider and we're going to pass in children in here and we're going to wrap all of our components with this provider so we're providing down the data to our child components okay so we have our auth provider and I also want to export the auth context as default so I'm exporting the alt provider as a named export we'll just do export default and we'll just do auth context if we ever need to use that anywhere else we're just going to export it that way and with this provider let's go ahead and return the values that we need so we're just gonna return the auth context dot provider and let's close this out in here we need to pass in the values that we want to pass down to the child components we'll just do the value and this is just going to be an object which we need to set right here so we're just going to call this context data so this will be an object that we're going to pass all the data to so right now it's going to be empty but we'll pass in context data there okay so from here what we want to do is just set up some State now so in our auth provider in here we're just going to use uh use state we're gonna set a user and then set user and use state will give us the value of null in the beginning so a user will always start off as null and we also want to set a loading value so we want time to actually load in a user in the future so I'll just do loading set loading use state and the value by default to loading I think I want this true so anytime we're loading the page this is going to be true until we actually update it so just in case any of the child components rely on anything from our auth provider we want to make sure that we're first loading and don't render any of the components below so what we're going to do here all the child components we're just going to go ahead and check the loading state so if we're loading loading is true at first we're just going to go ahead and throw in a paragraph tag later on you can put in load spinner something that lets people know it's loading for now I'm just going to do loading like that once loading is false we're just gonna go ahead and render out the children so once loading is done we just say hey go ahead and continue and pass down the data okay so user is null we have loading context data let's go ahead and actually wrap our app component to pass this data down and then we're going to go into private routes and get that data from here so we can go into app here and inside of app just underneath our router I can go ahead and add in our auth provider so we'll import auth provider and that's coming from utils all contacts perfect let's just go ahead and wrap this right here so auth provider and we need to close this out this is going to be just under routes okay so we have our alt provider that means all the data should be available in the child components and we're going to create a custom hook so we can access this data in a cleaner way here so we'll create that custom hook and this is going to be easy to do usually I'll create like a whole hooks folder and keep the hooks in their own area if this project ever did scale up I would do that but for now let's just go ahead and Export const and we're going to create a hook called use auth so this is going to allow us to hook into the state of this context provider and use a context data here without having to use the use context hook it's just like an extra import if we do that so we're just going to call we're going to create the use auth hook which is going to keep things a little bit cleaner so we'll create the function and let's just go ahead and return use context and we're going to use the auth context so typically you'd have to import this use context hook inside of every child component but once we have use auth it's going to just it's just going to make things a lot cleaner so now we can access all this data right here that we're about to pass in so we'll just do user so that's the first thing we want to pass in we don't need to pass in loading so we're going to pass in user that's going to get passed down to the children and then we're going to use this hook to get this user so inside of private routes we're just going to go ahead and do this and we're going to call use auth and it should user use auth like that it should go ahead and automatically import use auth and there we go we can just destructure this object here we'll get back the user and now the user is going to be either true or false or null or an object from the auth provider so we're no longer having to manually set that value in here so let's just test this out here we see loading oh I guess I probably should update this so inside of use effect at this point what I'm going to do is actually go back into use effect or into my private routes in my auth context and we're just going to set up that use effect here and essentially what we're going to want to do later is actually get that user data on first load and we're going to update loading once we get that data but for now let's just go ahead and set loading to false so let's just imagine we got that data and we just update loading from here and there we go so now we should be able to see the children are the child components let's see alt provider what's going on here above air private routes I did start typing something it must have messed with this component use auth user alt provider oh this is supposed to be auth context there we go okay so we're in that login page if I try to go to the home page it won't work and now if I just update the user inside of my auth context we can set that to true and now that should work we should be able to go to the home page okay so really quick what I'm going to do is just go to our login page and we're just going to make sure that a user can't be in the login page unless uh they're not authenticated so we want to redirect them from this page to the home page so we'll just do use effect and we're just going to check something so now we can just use that alt provider so we'll just do user and we can use this in multiple areas we'll just do use auth we'll bring in that user object and inside of use effect Let's see we want to set an empty dependency array here so only on the first load we're just going to ask a quick question we're going to say if user getting ahead of myself if user then redirect our user so if user then let's just go ahead and import navigate oh use navigate it's a hook from react router Dom so use navigate and in order to use this we just need to go ahead and set this up so we'll just do const navigate is equal to use navigate and then we just want to redirect our user back to the home page okay so what I'm going to do is just minimize this and then we'll bring this to the right side so at this point we can go back to our auth context just to kind of demo this out let's go to we can close out private routes and close out app.js for now and let's see so if we set this to null or false it'll read us redirect us back to the login page if we set it to True it'll redirect us back to the home page okay so that's perfect that's what we wanted so what we have to do next now is build in the login form so we're going to build out the form and then we're actually going to start dealing with the methods that apprite gives us we're going to use their SDK to start actually logging our user in so let's build this out here so for our login form there's just going to be a little bit of prep work to do here so go to login page let's just start building this out here so for the form itself we're going to create a div and I'm going to start adding in some of the classes right now just to build this out as we go so we're not having to come back we'll just call this auth hyphen hyphen container okay so we have our auth container in here we're going to go ahead and create a wrapper for our form so this will be a class name of form double hyphen wrapper and then we're going to build in the form itself so let's create the form okay so inside of the form every single field will be wrapped in a div here and that div is going to have the class name of field double hyphen wrapper okay so in here let's just throw in a label tag and this is going to be our email so we're going to do email and password for login so we have the email and then for the input field input field of type is going to be email and let's just go ahead and indent this right here so we can start working with that so we have the email or the type of email this is going to be required for the placeholder or for the name we want to call this email so for the actual field name then we want to have a placeholder that says enter your email enter your email dot dot and we also want to set the value here and then the on change event so there's a few different ways we can do this we can use use ref to actually submit the form and pull the values out of this input field what I'm going to do is just still set the state inside of the login page so we're going to set our state and this is going to be called credentials here and we're just going to have an object with an email and a password and then we're going to have a dynamic way of actually updating it so I don't know if maybe you've seen this method or not but if you haven't you just get to learn a new way if you want to use your way that's totally fine but I actually like using this method of setting up the credentials here so just do credentials okay so credentials and then set credentials and then in here inside of the state itself we're just going to go ahead and pass in email and that'll be an empty string and password and that'll also be an empty string so that means for the value we're going to access credentials and when you we just need to get these values from here so we're just going to do um value and that's going to be equal to credentials and if this value doesn't exist for some reason we could just go ahead and pass in um actually I guess we can just access it directly we already know it's there so we'll just do credentials.email like that so we have the email and we also need to pass in the on change value so on change what do we want to do here well we're going to have a handle input change method and this is how we can make this Dynamic so inside of handle change this is where the magic is going to happen so we're going to call this handle input change and in here what we need to do is first of all we need to grab the event itself so we're going to grab the event and we're going to set the name and the value of the current field that we're working on so name and value okay so for the name we're just going to do e dot Target dot name and for the value e dot Target dot value and then when we update our state we can use this same field for both or the same function or handle function for both fields that we're going to add for you know our email and our password field so at this point then all we need to do is just do set credentials and we're going to pass in an object with a spread operator taking the original credentials that we have and then we're going to go ahead and just pass in the name and make sure that you wrap that in square brackets and we're going to pass this value in so the reason for this I don't want to get into this right now but because we're using the name value like this and because it's a dynamic value you can't just do name like that this will not work it'll actually I believe just take the hard-coded string value of name if you pass this in you tell it it's a dynamic value so that means as we start changing the input field if the input field value is email this will be email if it's a password then this will be password so let's just cancel this out and see what happens so let's do console.log and let's just throw in credentials okay so handle input change uh let's actually just grab the second field now and this will be the type of password and the name of password and then enter password enter password credentials Dot password on change handle input change that looks good and let's just go ahead and go into our browser what I'm going to do is just just type in some information here we'll just do Dennis at email.com just to make sure that it doesn't accidentally autofill one of my passwords so we'll just do some random characters and if I go ahead and inspect this uh we see this object and as we're typing here we should be able to see the password and email get updated so it knows exactly which one to update if we start updating the email it updates the email if we update the password it updates the password field okay so that looks good everything's working let's go ahead and continue here so at this point I actually need to change this to class name saw the error in the console earlier so we want to fix that and now we actually want to handle the login so what happens when we submit this so we're going to need to create a function that actually handles the login method now for this what we're going to do is we're actually going to process this from the auth context so we're going to create that function from there we're going to pass it down and then we will make sure that it gets triggered when this function gets submitted so I actually really quickly just need to complete this login form so we want to create another wrapper completely forgot about this we'll just set an input type this value will be of submit so when this form is submitted we'll just go ahead and let's see this the type is supposed to be submit and then the value okay one second so value is supposed to be log in so we'll close that out and let's give this a class name of believe I just called it it's a button so it's going to be the main button so class name and this is going to be BTN and then BTN dash dash LG so a large button and BTN dash dash Main okay so there we go that looks a little bit better and let's go to our auth context so we're going to create the handle user login function just underneath our use effect here so we're going to do const handle user login and inside of this alt context is where we're going to store all of the login logout and register user functionality so we just want to keep that up inside of this context here that's really up to you and how you do this but I like the idea of keeping it here because that information will be stored in sort of like the global scope of things or in the global state so we just want to keep it up here and then just pass down any function we need into like the log out button or that register form so we're just going to pass in the original event we'll pass in the credentials so we'll just do credentials pass that in here and then with this form we'll just do e-dot event default and will stop the original form submission and at this point we're about to go into the upright documentation but at this point let's just go ahead and write the try catch so what we're going to do is we're going to attempt to log the user in get the user information and then we'll just do an accept lock here or catch not accept except as python so I work with both and we're just going to console the air out so console.air and let's just pass that out here so okay so in here is where we're going to log in the user so we're going to submit it pass in the event and the credentials now what I need to do is just go ahead and go down to the context data pass in the function which will be passed down to all the child components so anywhere I need it it'll be available through context data which now means I can go to the login page and I can just use the use auth hook and bring in handle user login here we go and then when we submit this form we're just going to do on submit we're just going to go ahead and create a function and wrap this in it we're going to take the original event and pass that through to handle user login which will take in the event and the credentials okay so recall and handle user login with the events and credentials you can just go ahead and get rid of that then we pass that up to the auth context which is going to go ahead and take that information and try to log our user in so let's add in this logic so if we go to the documentation we'll zoom out again make sure this is formatted let's go into the account settings here so we'll go into account and with the web SDK from the client side in order to log in a user we have a few methods here we can create an account create an email session this is what we want to focus on right now so let me try to zoom in here we'll do create an email session we'll find that part and let's just look through the code here and my mouse just died so let me pause this and I'll restart in a minute okay so I'm back looks like just the Bluetooth got disconnected but uh yeah we are in the client section in the web SDK and let's just scroll through here so we have create an email session let's go down to this part so we have that through the rest API we're not going to use that we just need to send a request with the email and password to create this email session okay so if we look through the code here let me zoom in a little bit more we have this create an email session function where we pass in the email and password and this comes from the account object which we need to create and this is going to be from the account class so let's just copy this right here and let's just go back into our app right config section and we'll just pass in account and we'll bring this in next to databases and let's just do a default export so it takes in that client object just like we did with databases we call new account create a new instance and we'll just export it okay so that means that we can just go into our auth context and first of all is just import the account so import ant account from apprite config then we go down to this handle user login inside of the try statement what we're going to do is just go ahead and copy this right here so account Dot create email session and we'll just do a response and then this will be you wait and let's just see what we get back for the response so what we're going to do is we're just going to pass in the user email and we haven't created a user so we're about to do this in a second we'll do credentials.email credentials.password okay so we passed that in and let's just first of all see what kind of response we get let's just try it without a user so let's just go ahead and inspect console let's just try to log a user in so it looks like we have invalid credentials that's exactly what we needed perfect so now we can go to auth so in here let's see I'm in the Ron app so I need to go back to tutorial that was the demo app so in here and it looks like it's starting to read the request so that's perfect we'll go into authentication and let's create a user so we'll just create a user called Dennis Ivy email will be Dennis at Dennis ivey.com and we don't need a phone number but we'll just pass in some kind of password we'll just do password one two three let's just see if that works okay looks like it worked perfect it's telling me to change my password well we'll leave it be for now okay so let's try to log in we'll just do Dennis at Dennis ivy.com uh password one two three we'll hit login and let me just zoom out a little bit apprite is using local storage okay that's all good looks like I am logged in so we forgot to console out the response let's do console.log and we'll just do logged double G there we go logged in and let's just get the response okay yikes accidentally hit save okay okay Google stop yelling at me never don't save it okay I guess I probably should have used my other email because now I probably do need to save it because it's going to keep asking me to Auto or manually type it in Dennis ib.com let me just copy this and then password one two three we'll hit submit all right there we go so here is logged in we see our user so we see some basic information about our session so it doesn't exactly give us back the user it just gives us back all this session information so it tells us um our location it gives us all this information hopefully nobody tries to get this information kill me later um but yeah this is all the information for the session but we also want to get our user information so what I want to do is right after we log in if everything checks out let's go ahead and get the user and I'm gonna have to zoom out because I can't see anything when I'm zoomed in let's go ahead and get the account information so to get the account information we're just going to call account.get I believe was the method so list sessions here let's just find did I just click on it get account okay here we go so here's the code we're just going to call account.get so if you can't see that if it's too zoomed out I'll just paste it in here and you'll see it in a second so right after we get the response if everything checked out well we're just going to go ahead and call account.get so that means we have a session now we can actually call this method if we weren't logged in we wouldn't be able to just call this method like this so we'll just say we'll just call this count details and what I want to do is I just want to go ahead and set the user information so we're going to set user to Account Details and once the user is set this information should be updated so once we log in we just want to go ahead and redirect our users so let's just import navigate from react router Dom navigate like that from react router Dom and I just realized this is supposed to be a named export that's why I didn't Auto fill that in for me oh use Navigator okay use navigate this is what happens when I have to try to talk and type and do this late at night so let's bring this in let's do const navigate and we're going to use the use navigate hook and now we can just redirect our user so we'll just do navigate and we'll send the user to the home page once the account details are set okay so let's test this out I actually want to get this user information from the header bar in a second which we're about to create so let's just go ahead and hit OK we'll hit enter check the email and password oh that's right because I I'm using Dennis at Dennis ivey.com I really regret using this email now because it's going to manually make me type it in password one two three let's go see how fast we can do this look at that we're in so the reason why we're in this page is because we are we actually have a user session so remember this is a protected route so we logged in and we redirected our user and the only reason why we're there is because this user object now is not null but it's full of a user session so we set those Account Details which is going to be that entire user object and we set those inside of that user session so there's still a few things that we want to take care of so what I want to do is first of all I want to get this user information inside of my navigation bar and I'm going to do that after I persist the user in I was actually going to reverse these steps but now that I realize I have to keep typing in this password I want to make sure we persist a user so what I mean by that is if I refresh this user is no longer here so the user is still in a session the session is still available in fact the session right now if we go into authentication we can see that the sessions should last 365 days I believe and we can change this so I mentioned this earlier when we were doing the intro so our session is still available in fact we can even go and see user sessions in here somewhere I promise you it's somewhere there okay so we have the user session but the problem is we need to get this account so when we reload user is not true and we don't call this handle login function so what I'm going to do is just go ahead and create a function that gets the current user on load okay so let's go ahead and underneath handle user login or actually just above it let's just go ahead and do const uh we'll just do get user on load we'll make this an async function so we'll get the user on load and in this function we're going to go ahead and call another try catch and in this error we're just going to do console dot error and we'll console out the error itself and normally I would love to just make a request through here but apparently I can't do that where I would just be able to write a function here um for getting the name and kind of spacing out but yeah you can basically load that in but I can't do that in this case so we're just going to go ahead and call this on the use effect hook here so we're just going to go ahead and make this request so we're going to call this exact method so we can just get Account Details we can bring this in here and we're just going to go ahead and set the user account information we'll set that user account information and then we're just going to go ahead and set loading to false and the reason why we're doing this is because we're going to call this function inside of use effect and we don't know we no longer need to set loading from here because this function on load will go ahead and check if we have a user if we do it's going to go ahead and update that user account information and then go ahead and set loading to false so now this should actually persist our user inside of here so let's go ahead and try to log in well actually we're in here because we got the user because we technically still have a session so if I refresh it look at that we're still in here that's exactly what we wanted that's perfect so what I'm going to do is actually get the user information we're going to create a header here I want to list out like a welcome message that says hello and then the user's name and then we'll add in the log out button we'll throw in the register functionality and we're going to start finishing this up here so we're going to just close this out really soon so for this let's go ahead and create a header and this is going to be just inside of components here so we'll go go ahead and create a new function this will be header Dot jsx react Arrow function component exported we're going to generate that header and in here let's go ahead and let's see we'll give this an ID of uh what did I call this header dash dash wrapper so that's the CSS class for the the CSS that I gave it so that's the ID name make sure it's an ID not class because we've been using a lot of classes and we're just going to say at this point normally you'd want a header in every page but we only have it when a user is authenticated because we only have a login page and then a register page which won't have this header but for now let's just go ahead and do this we'll just say if we have a user then let's go ahead and render the username so we're just going to go ahead and do this we'll use a fragment here and we'll get the user in a second so we're just going to go ahead and we're going to pass in a welcome message so we'll just do welcome and then the username so we'll just do user.name we'll pass in the username and then in the else statement we're just going to go ahead and I guess in theory you just link to a login page we'll just throw in a button and we'll just say log in for now even though you won't see this but I did want to throw in that else condition to kind of give you an idea so typically that would just be like a react router link right there you just send the user to the login page okay so we have our welcome message and then what I'm going to do is just go ahead and pass in let's see um I just realized I'm using react feather so I can just go ahead and import the login icon here so I'll bring login we want to just go ahead and bring that in like that or actually sorry that's going to be log out not login logout we'll just have the log out button and we're just going to add an event handler to this at this point we'll just go ahead and do class give this a class of header hyphen hyphen link we'll bring that in right there and let's just go ahead and get the user so we'll just do const user and this is going to be use auth and we're going to get this from our auth context so I think that's it for the header itself and we're going to add in an on click function that logs out our user that will be from the auth context so what I can do now is I can go to the room itself and let's just bring in this header so the header is going to sit let's see we'll actually just make a quick import okay we got the header and that's going to be down here inside of room container just above the form okay let's see should have a header here um I think I put this inside of the form is that where no room container uh let's see this is kind of weird oh should be inside of container then there we are okay perfect so that's the styling we see welcome and then the log out button for some reason the name is not being output so what I'm going to do is just go ahead and check this let's see on load what's happening to our Account Details why are we not getting this user console.log Account Details let's check this out so let's see I want to see what that user object looks like okay so first of all we have an error we have a class instead of a class name this is inside of what page I'm assuming our header is that what we did last name let's just get the small errors out we have a promise okay I see what's happening okay okay so we're setting a promise inside of this user session so we'll just do the weight if we save that that should actually give us back an object here we go so we see Account Details and here we see all the information perfect and then we see welcome Dennis Ivey so let's bring in log out we'll create a new user we'll test this with another user and we'll go from there and we'll just throw in registration in fact let's throw in registration or let's test a second user once we add in register so logout is going to be easy I'm not even going to refer to the documentation at this point I'll just go through the source code because this is going to be very simple so we have handle user login we have get user on load this is all inside of auth context let's just do const handle user log out which you don't think we need to make this an async function but it is what it is at this point so on logout let's see what do we want to do so at this point we'll just do account and we'll just set delete session and we're going to delete the current session so we're passing a string right here and we'll set user to null I guess what I guess we could throw in a way to just to make sure that this works before we set null here and then we can just pass in this method down through the context data and then inside of the header we can just go ahead and grab handle actually we'll just paste that in because I copied it handle user log out and then on click we'll just log out the user so let's try this okay so we log out I refresh it I can't go to the home page then we just go ahead and do Dennis at Dennis ivey.com password one two three the most secure password out there we log in and all right let's uh let's debug what happened okay upright user user role guest missing the account scope okay user roll guest missing I have not seen that error give me a second let me come back we'll we'll solve this and I'll talk about what what just happened here okay so I figured out a few things here so first of all this error is nothing to worry about I just realized once I looked over here this is an error that we're canceling out so what's happening is on load we call get user onload if we are not authenticated this method was still run so what's happening is we console out the error line 25 in auth context like it says right here I should have read that so it's just this error saying hey we couldn't get the account so that's nothing to worry about the second one the reason why the name wasn't showing up when we log in I guess I already added in a weight well we didn't have a weight here so if you don't have this make sure to add this and make sure we have a weight right here so put that there and then I just updated it I gave myself a new email so we're just going to use this one that autofills here and now when I log in so it's that same error I can now log in and I should see Dennis Ivey account number two log out log back in and we are good to go so again the account name wasn't shown in this header because we were here let me just slow down it wasn't shown here because what happened is login was returning a promise and not the actual account information same error that we had with getuser on load when you say call await before account and that will take care of it okay so where were we now that we have that resolved so we're able to log in and log out all that's taken care of I just want to make sure that we're all set here and let's continue on to the next section so at this point we can log out a user uh what I want to do is go ahead and actually register a user so we have that login user method we have log out we put the user in the header so let's go ahead and create a register page so we just want to register a user from the front end so let's go ahead and do this we'll go into pages and we're just going to create another page for registering so we'll just do register page I know that you could just do like a component for login and register and then change that component figured we'll just do a page this will be pretty simple to do okay so we'll just use this method here and what I want to do here is first of all we'll bring this into the app.jsx component here and we're just going to go ahead and create a path for register so we want to bring in that component so let's just go ahead and import register page and we'll bring in the actual route okay so this will be register and we'll change this to register page so inside of our login page so we don't need our header anymore we just added in that login functionality or logout functionality we shouldn't need the app right config anymore the room page we'll get back to that a little bit later alt context we will need this so inside of a login page what I want to do is I want to ask a question at the bottom of this form so I'm just going to go ahead and copy actually I'm going to copy something real quick we're just going to go ahead and underneath the form we're just going to ask this question so we're going to say don't have an account yet register and then we're going to link to the register page so that's it that's underneath the form but still inside of this form wrapper div and then we also need to import the link so we'll just do link right here and let's just check this out so if I log out we can just go ahead and click register and this is our register page so let's just double check let's go into register and there we go okay so we're in this page so let's start building this page out some of the functionality is going to be pretty simple similar to the login page I'll just uh copy and paste where I need and then anywhere where we need to add in something new we'll just go ahead and bring that in okay so inside of the register page we're going to bring in our state so we're also going to throw in our credentials so we'll go ahead and just take this um credentials state right here we'll move this over so they're side by side we'll bring this in we'll bring in use State here and we want a password one and a password too so we all we want to give people the ability to confirm their password so throw in your password and then throw in the confirmation just to make sure that you create an account with the right password okay so we have the credentials we want to go ahead and use the handle register method that we're about to create so let's just minimize the handle user login handle user log out we'll just do cost handle user register create the function make it an async function and we need to assign that okay so we have the function for now we'll just leave that blank and let's just go ahead and throw this in right here so handle user register inside of the register page we can just go ahead and get the method here so we'll just do const handle user register and that's going to be from use auth so from the use auth hook I was supposed to import that but let's just go ahead and import that manually import use auth bring that in from auth Context okay so we have the handle user register function from here we just want to go ahead and handle all the input changes so we'll go into the login page and we can just grab this right here and copy this directly so the reason why this is cool is because we can actually make this Dynamic so it doesn't matter what credentials we have we just get the name which is going to be email or password one or password two and then we just modify the create credentials so that's why it's cool we can reuse that let's go ahead and just take in this entire login form let's just copy all of this and we're just going to add in a field here and change up a few things so we'll copy this bring this into handle user register paste that in and let's see so we have our email enter your email we update the email itself on submit we're going to do handle user register and let's see what do we want to send with it we'll also pass in the event and credentials now we have our field wrapper of email and I just realized in our login page we were supposed to update a label so let's see right here this is supposed to be password this is in the login page so in here we have an email and then password and then we're just going to change the name here to password one and this will be password one and then we want to go ahead and just duplicate this and this should be password two so for the label we'll just say confirm it's a confirm password but the name will be password 2 and the type will still be of passwords so we'll just say confirm your password and this will be password 2. we handle the input change we submit it everything should be pretty good at this point and what we're going to do is just say already have an account and we're going to tell people to log in so instead of don't already have an account we'll just say already have an account and they can go to the login page from here Okay so let's just see the page looks like we have some errors let's just see what's going on probably one of the Imports okay account missing odd context okay that's the I'll just try to refresh this okay go back to login so I hit login okay okay what is happening here register components okay the air above error occurred in the register component odd context that's not in the register component router okay oh am I missing the link that might be it so I might be missing the link from react router Dom that wasn't too helpful maybe the error was in there but I just didn't notice it so just import a link from react router Dom we don't have to throw in six there that should work okay so here is the login page again the error is coming from that check and I can probably just change that to like a warning so let's just do that so it's not in our way here let's just do console Dot warning on load because that's annoying to see it's throwing me off here I think I can just update it like that oh wow this is a was warning not a console.info maybe I thought warning was an option okay well it'll be just uh info for now okay so here we go we have our login page if I start typing stuff in well I guess I'm not canceling that out but we have password one password two and then we can go back to the login page or the register page okay so on submit what's going to happen here is we're just going to go ahead and pass in our credentials which are going to be email pass email password one password two uh that's gonna call this right here that's good now inside of auth context let's go ahead and build out this function so we want to go ahead and take in the event we want to take in credentials and we will just go ahead and prevent the default so e dot prevent default and let's see what we want to do in here so inside of this function the first thing I want to do is just go ahead and check if the two passwords match so we're just going to go ahead and check password one and two so if password credentials.password1 credentials at password1 is not equal to credentials dot password two well if this isn't the case we need to throw an error and we just need to alert the user so we'll just keep it simple we'll just use an alert method and we'll just say passwords do not match why can't I type okay passwords do not match okay we're going to yell at the user and we're just going to return so we're not going to redirect them anywhere we just want them to see that alert so let's just try this I think this should work at this point so we're going to go ahead and register Dennis at let's just say email.com that's not an email we'll just do this for password one and then just do this one a little bit longer there we go passwords do not match and we're back here that's exactly what we wanted so if the passwords do match let's just go ahead and run a try cache so we're going to need to create a user we'll do try catch air and we will throw the air so this is the console dot error and we'll just do error and then in here what we want to do is go ahead and create the account so we're going to go ahead and set up response and we'll call a weight so it's an async method and to create an account what we want to do is just call account dot create well that's pretty self-explanatory now we also need that ID method so remember when we're creating messages we had to actually generate an ID for that specific user so we're going to import the ID class here so we're just going to do ID import ID from upright like that and we're just going to first of all call id.unique so we're going to throw in those credentials so that's the first part we'll do ID dot unique it's going to generate a user ID the second parameter is going to be the email and password object here so let's see so id.unique throw in a comma credentials.email and then credentials dot password or password one there we go okay so we create a user and let's see am I supposed to throw in a second password no okay so we're throwing in the username too so we'll just do credentials.name and that's going to be the last parameter here so credentials and I just realized we didn't add in a name for a user we want our user to actually have a name here so we're going to set that up let's go ahead and just throw in that field real quick that's going to be simple we're going to take in this email field and we're going to require that the user throw in a name first we don't want unnamed users this will be name type is text value is name and then enter your name credentials dot name we want to update our state so we'll just go ahead and throw that in right here okay so that checks out I will go back to our auth context so in here we're just going to register the user and let's just see what happens so let's just get the response first of all I want to check this out because what I'm going to do right after is I want to log in the user so we'll just say register once the user is logged in I don't want to force them to log in I just want to automatically log them right in what did I paste in here oh response okay so let's just check this out register so we have a name I'm like too zoomed in so it's not letting me see it so we'll just do um Peter Pan eater pan at email .com password will just create a password password one two three and then password one two three submit that passwords do not match really just do that password one two three let's hope this matches all right there we go so our user was created so if I go back into my dashboard we should see Peter Pan perfect awesome so that works so the next step here is just to go ahead and register our user so all I'm going to do is just go ahead and get the user account so we'll just go ahead and call account dot get and then we'll set the user and then we'll just redirect them so once the user is good to go no errors occurred we'll just go ahead and repeat some of our code we can just remove registered we set the user and then let's just call navigate and send the user to the actual home page so we'll just take actually I guess we can just write this out right here navigate and we're redirecting the user back to home page so let's see at this point we can do Ted lasso that'll be the name so Ted and also just started watching that show not the biggest fan of it but hey it was a decent email.com password one two three password one two three yeah should be redirecting me why does this not work line 74 let's see account okay uh it should have canceled Out My Account Details okay um I know it okay so let's see if it registered the user if it registered then it's just the login method so oh I account dot get okay so account create we create the user account right after we create oh that's what it is we have to create an email session so we haven't created a session so we try to get that too early got ahead of ourselves so we're just going to go ahead and call wait a count dot create email session and this is where it's going to pass in credentials.email and credentials dot password one I guess I could have just had a function that just logs a user in and then just started repeating that but uh we're this far into it so let's just work with it um okay password one there we go yeah account create email session we get the detail because we have the session uh we set the user and then we navigate and redirect that user uh let me think of another character Ted lasso uh James Bond let's just do that so James Bond James at email.com uh password one two three apparently James Bond isn't that secure password one two three log in there we go all right we have login logout user registration what's next on the list we're almost done here okay so after we register a user so what I want to do is I actually want to create uh I want to start actually knowing what users created what and I want to make sure that users can't just write messages and then delete anybody's message so I want to make sure to fix this up here a little bit so what we're going to do is we're going to go back to our room so let's close out all context app.js we don't need this anymore we should be done with these pages and let's go into our room page and on create we want to send some more data in our payload so at this point we have access to our users so we're logged in so what we could do is we can just go ahead and do const user from use auth there we go got the import so we have that user so when we create this payload we now have a user ID user underscore ID and we're just going to pass in user Dot ID like this and we also want to get the user name so we can just do user dot name actually what I call I think it's called a user name like that let's just check real quick um databases production collections messages username so it's one word like that so we just we're missing a comma there so now I'm sending this information so let's just see so if we're logged in as James Bond we're going to go ahead and just delete all these messages actually I'm going to leave these because I want to throw in a little condition here so we'll just do uh either got a mission for me I'll be honestly I think I watched like one James Bond movie so I don't really know anything about him so we have this question and we don't know who it's from so let's go ahead and update this message here so we'll modify the message here so that information should have been sent with it so somewhere in the database we should have it if we look here let's go into messages ID here we go we see James Bond's message uh username as a string that didn't save it I didn't do that okay username user dot username okay um this isn't making sense give me a second what am I doing wrong here okay user.name yeah oh yeah so in the user field is just user.name so the username is username so let's just um change that and we'll send it then if we go into our messages there we go we see this message and now we see James Bond okay so we have the ID value which is much more important because this value eventually should be dynamic let's say James Bond changes his name we want that to update in the message but for now we're just going to store that as a string value and then we'll uh and maybe future tutorials actually go through how to get that value because I have tested it with that there's different options for how to do this okay so inside of the actual message header let's see so I'm going to add a condition here and I just want to check the user information so let's see we have our message header and in here we have created at and then okay so we haven't added in the name yet so just above create an app let's just go ahead and add in a paragraph tag we'll close it off here and we're just gonna start typing in our message so we'll just do and see so if we have a message name so message username so we're going to check this condition so we're just going to do username so if we have this then let's go ahead and output this user's name we'll just throw in a span tag span and this is going to be if I can finish this up message dot username username because that's how we store it in the message and then if not well we can just go ahead and pass in Anonymous user and Anonymous is one of those words I just I can never spell if I do it slowly I can do it but in tutorials it's like an Anon oh mouse or something yeah and not not a yeah that's that's why I don't type it in so we're just going to do that um and I guess at this point I don't need the quotes there let's just check this out so there we go James Bond and Anonymous user perfect so that's working uh for some reason the time stamp I don't like the way that looks I think what I did in the demo app was actually take this tag right here and I put this in side of this paragraph tag so we have the span and the paragraph tag or the span and the small text inside of the paragraph tag so there we go that looks a lot better and let's see after that uh what I want to do is also just give users permission to delete their own messages okay so we're gonna change something up here real quick so when first of all we're going to check user permissions so let's see uh inside of each message I think we console out the messages there so let's just see something so if we look at the array of messages we have these documents you'll notice that there is this permissions array here so permissions gives it just tells me all the permissions of who can access this specific document and what can they do with it well at this point we're just letting anybody mess with it so if we go back into our databases into our messages collection for our permissions we just set up the uh okay what did I do it goes back we need to go back into settings so what I set up here was permissions for anybody wow I'm like a little bit loopy now okay so here we go we have permissions for any user and I probably should just actually here I can refresh I didn't save this so we have permissions for any user to create read update and delete messages well what we want to do is as we send a specific message we want to give only users that uh we want to give only authenticated users the ability to create and read a message but only the creator of that specific message the ability to actually mod a delete or update that message so here's what we'll do let's go ahead and delete this any user so now only authenticated users will be able to mess with our collections here so at the collection level we're going to say okay give users the ability to create and read messages so that's fine now there's also this section that says document security so when a document when document security is enabled users will be able to access documents for which they have been granted either document or collection from missions so that's something we want if the document security is disabled users can access documents only if they have collection level permissions so we do want to set this and we basically want to say we're going to have collection level permissions and document level permissions so if I go here I still have the ability to read anybody's message and I can still create a message so those are my document level or my collection level permissions so I can still see these messages but when I create a message let's go in here and we'll find this create message method create document so in here the last parameter I can throw in here let me just see how I did this in the demo because that's a lot to remember in this tutorial when we create this what we're going to do is we're going to create a permissions array along with the payload so we're just going to do let permissions and we can set multiple permissions permissions and this is where we can even give me a second permissions this is where we can even give like admin user permissions and so on so at this document level we can change up maybe if we just have permissions we can give another user access this is where we can actually assign this so This permissions array will be the last item in our create document post request here so when we're sending this or we'll recall when we're calling this method this is going to be the last item here so what we can do here is we can actually import let's see we're going to import from app right and I already have the start of this query I believe it's it's roll and what was the other one role and permission okay so we have to import these two things so we're going to give our current user as they're creating this role a user because they have the ability to create can also assign uh document level permissions to a specific document so in here we're just going to pass in a few of these permissions so somewhere here just bear with me handle submit okay so what we can do is we can just go ahead and do permission Dot right so right is going to be create update and delete so writing to the database and we're just going to say okay the person that has the permissions is going to be the role of a user so we can also give permissions to a specific team and we're just going to do the user Dot ID so the current user that just created I know it took longer to explain that than it should but I'm trying to remember this and best summarize this the list of permissions we're going to send along is going to be right here and the only permission we want to assign right now is going to be for the current user so we want this user to have not just create and read function abilities we want this user to have also delete abilities so let's go ahead and go back somewhere here we'll save it and let's just test this out so right now when James Bond says hi we're going to see that this is created and if we look at the permissions now we see this user so that's our current user that's James Bond's ID this user has the permission to update and delete and because they already have the collection level permission to create that doesn't need to be listed in here so now what we can do is with this trash icon we can check those permissions and then either render this out or not render this out so if James Bond tries to delete this hold on a second that wasn't supposed to happen okay let's see uh Anonymous user so let's try to delete this message I'm supposed to get an error let's delete this one okay so if I hit delete okay so user is not that's where it's supposed to be in my console but um yeah so it's working it's saying hey you don't have permission to delete this it doesn't even matter if James Bond created it because this message right here I believe was created by James Bond and we shouldn't have permission on this one either so what we're going to do is just go ahead and just check this and we're just going to go down to the message itself let's see so wherever that trash icon is we're just going to ask a question right here okay so I'm gonna need to reference some of my code here so we're going to ask a question so we're going to say so if message Dot permissions if message permissions dot includes and we're gonna we're gonna go ahead and pass in delete so that's the delete permission and we're just going to do actually let's just go ahead and do this let's let's just copy the message so we'll take that and it was somewhere in here so if the user has this specific permission delete we're going to go ahead and render out the trash icon but this parameter right here needs to be the user Dot ID value so if we have it then let's go ahead and render this out so now we'll take this trash icon so there's no need to even show it if they don't have permission and let's just fix this indentation let's check this out all right so James Bond has the ability to delete this one right here why does this one have the ability I guess we gave permission to that one oh that's right because well we'll see okay so we'll just do one two and then let's log in as Dennis send the message and there we go so Dennis has the ability to delete his messages and James Bond can delete his own so Dennis cannot delete James Bond's messages okay so let's see we added that ability to delete our own messages and that's it for this tutorial wow okay so uh that was really exciting I am super excited about upright I do have another tutorial coming out on my channel I'm assuming I'm probably gonna make some more with Brad here insanely excited about this technology so uh look forward to more videos and thank you for watching hope you feel proud of yourself for accomplishing this I'll see you in another tutorial take care
Info
Channel: Traversy Media
Views: 42,441
Rating: undefined out of 5
Keywords:
Id: t7S0I78sloI
Channel Id: undefined
Length: 141min 13sec (8473 seconds)
Published: Mon Jun 26 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.