Build A RealTime Chat App With React & Appwrite Cloud

Traversy Media · Intermediate ·🔧 Backend Engineering ·3y ago

Key Takeaways

Build a full-stack real-time chat application with React and Appwrite Cloud, featuring authentication and real-time capabilities

Full Transcript

[Music] hey what's up everybody welcome to this tutorial where I'm going to be showing you how to build out a realtime chat application with reactjs and an awesome new platform that I've recently fallen in love with called aight 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 to a database handling things like user authentication which we all know can be a real pain to build out from scratch aight makes this insanely easy and things like realtime 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 aight and reactjs on the front end while building out a uh pretty cool little chat application so if you haven't heard of aight yet it's a backend as a service platform and it comes on the scene as an open source alter alternative to uh something like Firebase so it's making a lot of Headway in the markets it's getting really exciting seeing this platform takeoff so before we get into an introduction of what aight is and how it works uh 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 realtime capabilities so uh 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 we'll just say hey there and if we send this we're going to notice both users got that message so the senders 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 so 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 cred operations authentication and the ability to send messages in real time okay so let's talk about aight 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 uh before we do that though I do want to arize 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 backend with scratch using something like Python and Jango I know a lot of people use expressjs with JavaScript or nodejs and then there's the PHP larva developers and all the other backend Frameworks that come with it so I'm in that world I totally get it um so a backend as a service and my best description and summary of it is kind of like what it sounds like it's a backend 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 in SDK that allows you to build out the backend really fast and focus on the front-end development so you can build out applications faster and not have to uh deal with all that backend stuff and building things out from scratch so it really can make your life a lot easier there's pros and cons to use in it we won't get into that but that just kind of summarizes what it is so for aight so this is the aight website let's talk about this so first of all aight as I mentioned before it's an alternative open source alternative to something like Firebase and with aight we have something called aight Cloud that we can use that's currently in beta that uh 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 aight Cloud it's 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 uh 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 uh as we mentioned earlier you you get a database this is a realtime database that we can uh 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 uh aight 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 um and then a lot of other realtime 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 aight 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 aight Cloud again normally you can set up a local instance of this but we're going to use aight Cloud so first of all uh we have our project so you can create a project here I already created My Demo we'll actually walk through all of this uh 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 solam right here so we see the user we can even modify the user if we need we can go ahead and actually update information 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 uh different type of user permissions that can all be created uh in your console and then also through the STK here and we can see usage of each user so we can see how many sessions we have how many times and where users logged in uh all that kind of data for the user along with authentication mechanisms so um right now we're doing email and password signin we can do magic URL Json web tokens phone numbers and all these off 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 attrib 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 aight 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 uh 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' would 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 will find the final source code to the project itself so I'd recommend checking it out beforehand uh just review it and use it to compare against your code as you're coding Al here uh 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 Al and at some point we are actually going to need to go into this CSS folder and just take the CSS from here uh 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 so make sure you check out that link because we will need it so uh 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 um I prefer Vite as of late so we're just going to do npm create and then we'll just do Vite 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 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 and install so I'm going to do this from VSS 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 Vite 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 Vite 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 uh control all we're going to delete all that save it remove everything from index.css and that should remove the styling then we'll go into app.jsx we don't need the Vite or react logo we don't need the Ed 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. jsx and I have a code snippet where I can just type in react Arrow function component exported so ra a fce this is called es7 react Redux uh code Snippets and it's an extension with vs code that you can use and it just gives me the scating for my component so you can write this out from scratch I prefer that code snippet so uh 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 uh we'll add in routing and authentication later but for now we're just going to have one page as we uh 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 backend and then we want to configure our application with aight so let's go ahead and go into aight so app.io uh 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 new project and we're going to call this uh tutorial so that's going to be our project and we do automatically get a project ID we could create this manually but it's just going to autogenerate 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 host name that we're going to use to interact with our application and production or local environment so right now it already prompts us to add in Local Host later on if you're deploying on forell whatever that domain name is uh we're just going to go ahead and add that here so for now we're just going to interact with it through Local Host and we don't need the port number so we 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 app right and how to configure it so let's go ahead and just copy this to clipboard we'll go back to 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 app right 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 app right config so we'll just do app right config with the capital C.J 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 app right 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 uh 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 it 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 are comparing this to an Excel table uh these would be like columns inside of an Excel table if you were creating like models if you were using a backend like python or even nodejs and express uh these would be attributes in that model so we're going to create that let's go ahead and we're going to create 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 th 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 um we'll just kind of see what we need as we go so for now we just have the body and and we do want to connect this to a user later so we're just going to do user ID and we're going to store a user's ID value so we can get a particular users 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 hardcode 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 uh really neat 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 uh this was created in the console so why I'm creating this is I want to be able to actually query uh 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 we have these documents now in theory you think oh I can just create the database and make requests here well 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 uh 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 um 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 ER that I was having this issue so what I want to do is actually remove these permissions run into that eror 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 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 if you 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 Lis listing a particular document so we can actually use this rest API we're not going to do this right now there's a 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 uh 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 oh we're in create document so let's go to list sorry got ahead of myself there we're going to go into databases. list documents that's the command and we pass in the ID and and the collection those are the two required parameters to query our database so let's go ahead and take this database as 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 will 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 aight config file so we're going to do export const and we're just going to call this projector ID so we're going to need a few of these values and that will be a string uh we're also going to export the let's see the database ID database _ ID so this will be our production database and we're going to ex export The Collection ID so we're going to do collection collection undor 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 do 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 app right config so it just goes ahead and adds that import uh we're going to want to add in some state so we're going to do 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 effects we're going to do 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 await and we can access databases Dot and let me fix this indentation we'll do list documents and what did 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 going to 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 within appat because uh 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 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 app 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 user name 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 we 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. 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 map and we'll pass in the message itself useing 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 we're just going to set the key to message. 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 um and with my styling I'm going to have a div with a span tag for the message body so we're going to do spam and we'll just do message. 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 amp so we'll go ahead and pass in a paragraph tag and we'll just say message dot created at and that's going to be an ugly timestamp 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 uh at this point let's just go ahead and uh 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 just kind of fast forward through 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 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 uh 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 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 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 hyen 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 hyen 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 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 um 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 uh we need the database ID so you're going to start seen 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 um it's more of a theme with how app right 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 it's just going to be 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. create document and here we go so we're going to run this and then this part is 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. 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 aight 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. unique pass that in and then we need the 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 value so 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 use 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 and I'm going to wrap in a div and I added the div for styling so we'll just do um 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 1,000 but it's going to be a thousand for now we'll leave it there placeholder we'll just say say something I guess that's a good prompt I don't know why to me when I see say something it almost sounds aggressive it sounds like a street fight me okay so uh on change as users are adding in messages what 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 just going to do set message body and that's going to be the value of this field so e. target. 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 TDS stuff this part you should be familiar with um 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 hyen 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 Das BTN D- rapper 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 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 goes good so we should get back the instance of our object when 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 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 see that's a 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's how you do it let's see messages okay so let's test this out we'll just say one send two 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 uh response here so right now we're just adding this response to the beginning of the raid 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 or in guess I'm taking ownership with aight but in the aight documentation uh inside of list Let's see we have list documents the third parameter is going to be all the queries that 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 an 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 order descending and we can specify the attribute that we want to order it by and I want us to order this by created at I believe that should work so if I save this now if I refresh it uh I guess that didn't work give me one second figure out why that didn't work so query. order descend created at let's see am I getting an error let's just check this out okay so invalid permissions order is not allowed oh okay so I just realized something I believe that next okay so we're creating okay I added this to the round 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 as you know what I'm not even going to try that let's just you get the idea we can reorder that uh we can also limit queries so right now let's see we have 1 two 3 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 uh 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. 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 um 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 will create so we'll just do delete message and we'll just make this an async function message ID create that Arrow function and we're just going to call databases. 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. map messages that should be message and I don't even know how that worked technically I think that's supposed to throw an air 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 uh people know intin Del we 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 we're just going to do onclick 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 do ID like that so when we click on it we're going to go ahead and delete the message I 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 let's see how do I want to do this I think I can just do pre state or previous state and then we're going to do messages. 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. 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 so it's 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 uh 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 2 and what we're going to do is just go ahead and run and install for react feather so we need to install the library or the package npm install react Das feather we'll bring this in let's go ahead and start up our server again and we can bring in import trash 2 from react Das feather so we'll 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 breing in that icon from scratch so we'll just do trash 2 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 and 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 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 uh 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 Walkin the park to do that so this is really really exciting so if we look at this aight lets us 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 or 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 event so I'm assuming create read update well 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 subcribe 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 back tis 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 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. 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. doents and I think that should be good now we also need to import that client object so inside of app config we had the default export as client so let's go ahead and bring that in so we can go into the aight config section where we imported everything and then aight 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 dawn 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 uh 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 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'd 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 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 do collection 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 right 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 up 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 one an event event or a document is updated if you 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 doevents so we're going through the events remember that we just saw that in the console we're going through the events dot 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 or this statement then we want to look for 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 message ID so at this point what we can do is instead of the message ID here we're just going to do response. 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 we would get that response and we would update the messages array uh 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. previous state so at this point we're going to do response. payload so before we just had the response now we need to access the payload and make sure you're updating the state this way by the way so uh I know sometimes people update it like this where you can just do that right there and get messages uh this won't work because what's going to happen is when this user 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 it's actually going to erase your old messages and that's because of when this 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 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 it's being 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 D okay so we're just going to set some basic stuff up here 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 last time we used that was in react router 5 so now everything's going to be a part of routes and we create the actual route here and we can bring in the component 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 EB component and we'll just do room so room will be the homepage so we can get rid of this and we're going to have a path for the login page so let's go ahead and do this login 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 we go back here refresh it login 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 homepage 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 privat routes. jsx and that'll be in the components folder we'll just use our code stimp it 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 dashd 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 be or uh 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 uh the routes down to the uh 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 I actually wrote an article up about this from using react router 5 where we used to create this component here so we basically used to do this right here we 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 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 pass 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 in 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 uh 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 false meaning we don't have anything there uh typically this would be something like null so uh that also works and we're going to say if we have a user then go ahead and pass in 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 Route these so uh let's go ahead and bring this in so we'll just do import private routes and I actually want to put this import above here because any pages that I'm going to be adding in the future um we want those down here so I want to 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 overe explaining uh but at least people can understand it and kind of get through this part here okay so we have that uh 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 homepage 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 homepage 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 so new file utils and then we'll just do off context. jsx okay so we have our o context and inside of our Au 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 uh run some imports so we're just going to import create context and this is going to be from react uh 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 create the off context we'll just do o 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 O provider so const o 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 off provider and I also want to export the O context as default so I'm exporting the O provider as a name to export we'll just do export default and we'll just do o 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 going to return the O context. provider and let's close this out in here we need to pass in the value that we want to pass down to the child components we'll just do 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 Au provider in here we're just going to use uh use State we're going to 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 we'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 um anything from our off 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 uh once loading is false we're just going to 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 off provider so we'll import o provider and that's coming from utils Au context perfect let's just go ahead and wrap this right here so o 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 um 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 off so this is going to allow us to hook into the state of this context provider and use a context uh 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 off 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 O context so typically you'd have to import this use context hook inside of every child component but once we have use o 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 o and it should not user use o like that it should go ahead and automatically import use o and there we go we can just destructure this object here we'll get back the user and now the user us is going to be either true or false or null or uh an object from the off 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 not my private routes in my Au context and we're just going to set up that use effect here and essentially what we're going to want 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 or the child components let's see Al provider what's going on here above air private routes I did start typing something it must have messed with this component use o user o provider oh this is supposed to be off context there we go okay so we're in that login page if I try to go to the homepage it won't work and now if I just update the user inside of my o context we can set that to and now that should work we should be able to go to the homepage 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 homepage so we'll just do use effect and we're just going to check something so now we can just use our Au provider so we'll just do use user and we can use this in multiple areas we'll just do use o 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 get 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 homepage 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 off context just to kind of demo this out let's go to we can close out private routes we can 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 homepage 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 aight 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 o hyphen hyphen container okay so we have our off 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 well 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 uh this is going to be required uh for the placeholder or for the name we want to call this email so for the actual field name uh then we want to have a placeholder that says enter your email enter your email dot dot dot and we also want to set the value here and then the onchange event so there's a few different ways we can do this we can use uh use ref to actually submit the form and pull the values out of this input field uh 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 we'll 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 we 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 CR 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 just 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. target. name and for the value e. target. 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 the 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 hardcoded 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 password then this will be password so let's just console this out and see what happens 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 uh 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 uh let's go ahead and continue here here so at this point um 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 Au 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 log 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 uh login 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 D- LG so a large button and BTN D- main okay so there we go that looks a little bit better and let's go to our off context so we're going to create the handle user login function uh just underneath our use effect here so we're going to do const handle user login and inside of this Au context is where we're going to store all of the uh login log out and register user functionality so we just want to keep that up inside of this context here that's really up to you on 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 logout button or that register form so uh we're just going to pass in the original event we'll pass in the uh credentials so we'll just do credentials pass that in here and then with this form we'll just do e. prevent default and we'll stop the original form submission and at this point we're about to go into the app right documentation but at this point let's just go ahead and write the TR 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 block here or catch not accept except is python so I work with both and we're just going to console the air out so console. a 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 off hook and bring in handle user login here we go and then when we submit this form we're just going to do onsubmit uh 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 event and credentials you can just go ahead and get rid of that then we pass that up to the off 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 let zoom out again make sure this is formatted uh 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 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 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 database 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 o context and first of all let's just import the account so import account from app right 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. create email session and we'll just do uh response and then this will be a 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 uh let's just go ahead and inspect console let's just try to log a user in so looks like we have invalid credentials that's exactly what we needed perfect so now we can go to O 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 uh email will be Dennis at Dennis i.com and we don't need a phone number but we'll just pass in some kind of password we'll just do password two3 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 B for now okay so let's try to log in we'll just do Dennis Dennis i.com uh password 1 2 3 we'll hit log in and let me just zoom out a little bit app right 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 i.com let me just copy this and then password one two 3 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 in kill me later um but yeah this is all the 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 I'm going to have to zoom out because I can't see anything when I'm this zoomed in let's go ahead and get the account information so to get the account information we're just going to call account. getet 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. 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. 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 um 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 do 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 navigate okay use navigate nav vate this is what happens when I have to try to talk and type and do this late at night so uh let's bring this in we'll just 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 homepage once the account details are set okay so let's test this out uh 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 okay we'll hit enter check the email and password oh that's right because I I'm using Dennis Dennis i.com I really regret using this email now because it's going to manually make me type it in password 123 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 um 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 uh 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 onload and in this function we're just going to go ahead and call another try catch and in this error we're just going to do console. 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 forgetting the name I'm 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 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 uh 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 um 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. 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 D- wrapper so that's the CSS class or 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 Norm only 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 um we'll we'll just throw in a button and we'll just say login 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 uh 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 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 log in log out we'll just have the log out button and we're just going to add an event handler to this uh at this point we'll just go ahead and do class give this a class of header hyen hyen 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 o and we're going to get this from our o context so I think that's it for the header itself and we're going to add in an onclick function that logs out our user that will be from the context so what I can do now is I can go to the room itself and let's just breing 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 sh 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 onload what's happening to our Account Details why are we not getting this user console do log count 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 class 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 do8 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 Ivy so uh 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 then we'll just throw in registration in fact let's throw in registration or let's test to Second user once we add in register so log out 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 uh 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 au context uh let's just do const handle user logout actually don't think we need to make this an Asing function but uh it is what it is at this point so on log out let's see what do we want to do so at this point uh we'll just do account and we'll just set delete session and we're going to delete the current session so we should pass in a string right here and we'll set user to null uh I guess what guess we could throw in weight 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 cuz 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 homepage then we just go ahead and do Dennis at Dennis i.com password one two three the most secur password out there we log in and all right let's uh let's debug what happened okay ight user user roll guest missing the account scope okay user roll guest missing I have not seen that air 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 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 constantly out so what's happening is onload when we call get user onload um if we are not authenticated this method will still run so what's happening is we console out the Air Line 25 in off 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 and I guess I already added in a weit well we didn't have a weit here so if you don't have this make sure to add this and make sure we have a weit 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 Ivy 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 get user on load we need to call await before account and that will take care of it okay so where were we now that um we have that resolved so we're able to Lo 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 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 uh 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 log out functionality we shouldn't need the aight config anymore uh the room page we'll get back to that a little bit later all context we will need this so inside of login page what I want to do is I want to ask a question uh at the bottom of this form form so I'm just going to go ahead and copy actually I'm going to copy something real quick uh 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 uh some of the functionality is going to be pretty simp similar to the login page I'll just uh copy and paste where I need and then anywhere where uh 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 two 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 created an account with the right password okay so we have the credentials uh 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 const 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 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 o so from the use o hook uh was supposed to import that but let's just go ahead and import that manually import use o bring that in from o context Okay so we have the handle user register function uh 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 CR credentials so that's why it's cool we can reuse that uh let's go ahead and just take 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 uh 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 the in our login page we were supposed to update a label so let's see uh 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 to so for the label we'll just say confirm so confirm password but the name will be password to and the type will still be of password so we'll just say confirm your password and this will be password two 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 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 off context okay that's the let's just try to refresh this okay go back to login so I hit login okay okay what is happening here register component okay the above error curred in the register component off context that's not the register component router okay oh am I missing the link that might be it so I might be L missing the link from react router Dum that wasn't too help maybe the error was in there but I just didn't notice it so we'll 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. warning onload 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 um if I start typing stuff in well I guess I'm not consoling 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 going to call this right here that's good now inside of off 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. prevent default and let's see what do 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 passw passwords match so we're just going to go ahead and check password one and two so if password credentials. password one so credentials. password one is not equal to credentials. password 2 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 it 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 uh Dennis at let's just say email.com that's not an email we'll just do this for password one and then let's 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 TR cat so we're going to need to create a user we'll do try catch error and we will throw the error so let do console. 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 just going to go ahead and set up response and we'll call await so it's an async method and to create an account what we want to do is just call account. 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 uh 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 app right 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. 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. 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 uh credentials. and that's going to be the last parameter here so credential and I just realized we didn't add in a name for our user we want our user to actually have a name here so we're going to set that up uh 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. name uh we want to update our state so we'll just go ahead and throw that in right here okay so that checks out uh we'll go back to our Au 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 registered once the user is logged in I don't want to force them to log in I just want to automatic ically log them right in what did I paste in here oh response okay so uh 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 Peter Pan email.com uh password we'll just create a password password one two 3 and then password one two3 submit that passwords do not match really just did that password two3 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. getet and then we'll set the user and then we'll just redirect them so once the user's 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 homepage 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 homepage so let's see uh at this point we can do Ted lasso that'll be the name so Ted lasso just started watching that show not the biggest fan of it but hey was a decent email.com password 123 password one23 should be redirecting me why does this not work line 74 let's see account okay uh it should have consell Out My Account Details okay um I know it okay so let's see if it registered the user um if it registered then it's just the login method so oh I account. 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 account. create email session and this is where we're it's going to pass in credentials. email and credentials do password one I guess I could have just had a function that just logs a user in and then just started repeating them 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 email.com uh password two3 apparently James Bond isn't that secure password One two3 log in there we go all right we have login log out user registration what's next on the list we're almost done here okay so after we registered 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 off 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 user so we're logged in so what we could do is we can just go ahead and do const user from useo here we go got the import so we have that user so when we create this payload we now have a user ID user uncore ID and we're just going to pass in user do ID like this and we also want to get the username name so we can just do user.name actually what do I call it I think I just called it 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 we're missing a comma there so now I'm sending this information so uh 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 hey there got a mission for me I'll be honest 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 uh 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 user ID here we go we see James Bond's message uh username as a string I didn't save it I didn't do that okay username user. 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 um 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 in 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 created app let's just go ahead and add in a paragraph tag we'll close it off here and we're just going to start typing in our message so we'll just do let's 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 uh message. username username because that's how we store it in the message and then if not well we can just go ahead and uh 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 an non mouse or something yeah an yeah that's that's why I don't type it in so uh 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 here 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 inide 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 going to 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 consel 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 um 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 uh mod uh 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 uh 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 permissions 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 uh 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 hold on 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're call when we're calling this method uh 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 aight and I already have the start of this query I believe it's it's roll and what was the other one um roll 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 so what we can do is we can just go ahead and do permission dot write so write 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 they 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 fun or 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 uh 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 tried 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 all that's weird 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 uh 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 going to 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. permissions if message permissions. includes and we're going we're going to go ahead and pass in delete so that's the delete permission and we're just going to do uh 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 do 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 aight I do have another tutorial coming out on my channel I'm assuming I'm probably going to make some more with Brad here uh insanely excited about this technology so uh look forward to more videos and thank you for watching I hope you feel proud of yourself for accomplishing this I'll see you in another tutorial take care

Original Description

Fullstack chat application with Authentication and real-time capabilities with Appwrite cloud. Be sure to join the Appwrite discord channel for technical support questions and say hello on Twitter: Appwrite Website: https://t.co/HVsoUClCF4 Appwrite Twitter: https://twitter.com/appwrite AppWrite Discord: https://twitter.com/appwrite Source Code: https://github.com/divanov11/React-Appwrite-RealTime-Chat Read more about Appwrite cloud here: https://appwrite.io/public-beta Timestamps: 00:00 - Intro 1:16 - Demo 2:20 - Appwrite Intro 8:08 - Basic Setup 8:08 - Basic Setup 12:00 - Configuring Appwrite 17:55 - Collection Permissions 19:45 - Querying Database Items 25:15 - Adding Styling 31:50 - Create Messages 40:50 - Sorting Queries 43:45 - Limiting Queries 44:23 - Deleting Messages 50:45 - Adding Realtime events 1:07:30 - Protected Routes 1:12:15 - Adding AuthContext 1:22:00 - Login User 1:39:45 - Persisting User After Login 1:47:20 - Logout User 1:51:00 - Register User 2:06:50 - Document Level Permissions
Watch on YouTube ↗ (saves to browser)
Sign in to unlock AI tutor explanation · ⚡30

Playlist

Uploads from Traversy Media · Traversy Media · 0 of 60

← Previous Next →
1 Changing Your DNS/Nameservers
Changing Your DNS/Nameservers
Traversy Media
2 Create a MySQL database in cPanel
Create a MySQL database in cPanel
Traversy Media
3 Install & Uninstall Joomla Extensions
Install & Uninstall Joomla Extensions
Traversy Media
4 Adding and linking an article in Joomla
Adding and linking an article in Joomla
Traversy Media
5 Create a Joomla Blog
Create a Joomla Blog
Traversy Media
6 Import & Export A MySQL Database
Import & Export A MySQL Database
Traversy Media
7 Use A Custom Font On Your Website Using CSS
Use A Custom Font On Your Website Using CSS
Traversy Media
8 Connect Joomla Site With Dreamweaver
Connect Joomla Site With Dreamweaver
Traversy Media
9 Remove Phoca Gallery 3.2.3 Footer Text
Remove Phoca Gallery 3.2.3 Footer Text
Traversy Media
10 Drupal 7 Security Update 7.19 to 7.20
Drupal 7 Security Update 7.19 to 7.20
Traversy Media
11 Add An Addon Domain In Cpanel
Add An Addon Domain In Cpanel
Traversy Media
12 Pull A Heroku Rails App and Database
Pull A Heroku Rails App and Database
Traversy Media
13 Create a Custom Joomla 2.5 Module - Part 1
Create a Custom Joomla 2.5 Module - Part 1
Traversy Media
14 Create a Custom Joomla 2.5 Module - Part 2
Create a Custom Joomla 2.5 Module - Part 2
Traversy Media
15 Create a Custom Joomla 2.5 Module - Part 3
Create a Custom Joomla 2.5 Module - Part 3
Traversy Media
16 Joomla SEO Tutorial - sh404sef Configuration
Joomla SEO Tutorial - sh404sef Configuration
Traversy Media
17 Font Dragr
Font Dragr
Traversy Media
18 Convert an HTML Template to Joomla 2.5/3.0 - Part One
Convert an HTML Template to Joomla 2.5/3.0 - Part One
Traversy Media
19 Convert an HTML Template to Joomla 2.5/3.0 - Part Two
Convert an HTML Template to Joomla 2.5/3.0 - Part Two
Traversy Media
20 Rockettheme Rocketlauncher   Joomla Site in Under 10 Minutes
Rockettheme Rocketlauncher Joomla Site in Under 10 Minutes
Traversy Media
21 JQuery FAQ Slider Tutorial
JQuery FAQ Slider Tutorial
Traversy Media
22 301 Redirect With htaccess File
301 Redirect With htaccess File
Traversy Media
23 Convert HTML to Wordpress Theme - Part 1
Convert HTML to Wordpress Theme - Part 1
Traversy Media
24 Convert HTML to Wordpress Theme - Part 2
Convert HTML to Wordpress Theme - Part 2
Traversy Media
25 Easy JQuery Widgets
Easy JQuery Widgets
Traversy Media
26 Codeigniter App Part 1 - Creating the Database
Codeigniter App Part 1 - Creating the Database
Traversy Media
27 Codeigniter App Part 2 - Installation and Configuration
Codeigniter App Part 2 - Installation and Configuration
Traversy Media
28 Codeigniter App Part 6 - Login/Register System
Codeigniter App Part 6 - Login/Register System
Traversy Media
29 Codeigniter App Part 7 - Models List CRUD
Codeigniter App Part 7 - Models List CRUD
Traversy Media
30 Codeigniter App Part 8 - Models Task CRUD
Codeigniter App Part 8 - Models Task CRUD
Traversy Media
31 Node.js Part 1 - Install NodeJS on Windows
Node.js Part 1 - Install NodeJS on Windows
Traversy Media
32 Node.js Part 3 - Building a Static Page Server
Node.js Part 3 - Building a Static Page Server
Traversy Media
33 Node.js Part 4 - NPM
Node.js Part 4 - NPM
Traversy Media
34 Node.js Part 2 - Install MongoDB in Windows
Node.js Part 2 - Install MongoDB in Windows
Traversy Media
35 Create a Joomla Quickstart with Custom Sample Data
Create a Joomla Quickstart with Custom Sample Data
Traversy Media
36 Install MongoDB in Ubuntu
Install MongoDB in Ubuntu
Traversy Media
37 HTML5 Web Storage
HTML5 Web Storage
Traversy Media
38 Create a Joomla Bootstrap Template From Scratch
Create a Joomla Bootstrap Template From Scratch
Traversy Media
39 Ubuntu Server 14.04 Setup Part 1 - Installation
Ubuntu Server 14.04 Setup Part 1 - Installation
Traversy Media
40 Ubuntu Server 14.04 Setup Part 3 - Set Static IP
Ubuntu Server 14.04 Setup Part 3 - Set Static IP
Traversy Media
41 Create A Wordpress Widget - Part 1
Create A Wordpress Widget - Part 1
Traversy Media
42 Create A Wordpress Widget - Part 2
Create A Wordpress Widget - Part 2
Traversy Media
43 Create A Wordpress Widget - Part 3
Create A Wordpress Widget - Part 3
Traversy Media
44 Create A Wordpress Widget - Part 4
Create A Wordpress Widget - Part 4
Traversy Media
45 Get Started With Sass on Windows
Get Started With Sass on Windows
Traversy Media
46 Build An HTML5 Template With Bootstrap and SASS - Part 1
Build An HTML5 Template With Bootstrap and SASS - Part 1
Traversy Media
47 Build An HTML5 Template With Bootstrap and SASS - Part 6
Build An HTML5 Template With Bootstrap and SASS - Part 6
Traversy Media
48 Build An HTML5 Template With Bootstrap and SASS - Part 4
Build An HTML5 Template With Bootstrap and SASS - Part 4
Traversy Media
49 Build An HTML5 Template With Bootstrap and SASS - Part 5
Build An HTML5 Template With Bootstrap and SASS - Part 5
Traversy Media
50 Build An HTML5 Template With Bootstrap and SASS - Part 3
Build An HTML5 Template With Bootstrap and SASS - Part 3
Traversy Media
51 Build An HTML5 Template With Bootstrap and SASS - Part 2
Build An HTML5 Template With Bootstrap and SASS - Part 2
Traversy Media
52 Build An HTML5 Template With Bootstrap and SASS - Part 7
Build An HTML5 Template With Bootstrap and SASS - Part 7
Traversy Media
53 Build An HTML5 Template With Bootstrap and SASS - Part 10
Build An HTML5 Template With Bootstrap and SASS - Part 10
Traversy Media
54 Build An HTML5 Template With Bootstrap and SASS - Part 8
Build An HTML5 Template With Bootstrap and SASS - Part 8
Traversy Media
55 Build An HTML5 Template With Bootstrap and SASS - Part 11
Build An HTML5 Template With Bootstrap and SASS - Part 11
Traversy Media
56 Build An HTML5 Template With Bootstrap and SASS - Part 9
Build An HTML5 Template With Bootstrap and SASS - Part 9
Traversy Media
57 Build An Audio Player Using HTML5 & jQuery - Part 1
Build An Audio Player Using HTML5 & jQuery - Part 1
Traversy Media
58 Build An Audio Player Using HTML5 & jQuery - Part 2
Build An Audio Player Using HTML5 & jQuery - Part 2
Traversy Media
59 Youtube Data API v3 & jQuery To List Channel Videos
Youtube Data API v3 & jQuery To List Channel Videos
Traversy Media
60 Using Bootstrap With Ruby on Rails
Using Bootstrap With Ruby on Rails
Traversy Media

This video teaches how to build a real-time chat application with React and Appwrite Cloud, covering authentication, real-time capabilities, and full-stack development. By the end of this lesson, you will be able to build a fully functional real-time chat app with authentication.

Key Takeaways
  1. Set up a new React project
  2. Configure Appwrite Cloud
  3. Create a database and collections
  4. Implement authentication with Appwrite Cloud
  5. Add real-time events
  6. Implement protected routes and auth context
💡 Appwrite Cloud provides a scalable and secure backend for real-time applications, making it an ideal choice for building full-stack applications.

Related Reads

Chapters (21)

Intro
1:16 Demo
2:20 Appwrite Intro
8:08 Basic Setup
8:08 Basic Setup
12:00 Configuring Appwrite
17:55 Collection Permissions
19:45 Querying Database Items
25:15 Adding Styling
31:50 Create Messages
40:50 Sorting Queries
43:45 Limiting Queries
44:23 Deleting Messages
50:45 Adding Realtime events
1:07:30 Protected Routes
1:12:15 Adding AuthContext
1:22:00 Login User
1:39:45 Persisting User After Login
1:47:20 Logout User
1:51:00 Register User
2:06:50 Document Level Permissions
Up next
Indian Express Editorial Analysis by Chandan Sharma - 1 JULY 2026 | UPSC Current Affairs 2026
StudyIQ IAS
Watch →