Let's build a DISCORD clone with React Native (p2) šŸ”“

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
what's up nudges developers welcome back to a new live stream and today today we are going to continue our discord clone that we have started a couple of weeks ago uh everything is going to be done in a react native with stream chat sdk and this is going to be a tutorial for beginners and i'm going to explain like step by step everything that we have to do so um if you don't know a couple of weeks ago we have built the first part of discord and where we have set up installed uh and configure stream chat sdk to provide us with the most important functionalities for a messaging application like discord such as private messaging groups and also a lot of features that are specifically for chatting applications like message replies message reactions threads uh sending urls sending emojis uh and a lot more features um there so that was in the first part and if you haven't followed it along uh check it out on the channel page or follow the link that you see here uh i highly encourage you to start from there because it's uh in three hours we are doing so much better uh and yeah you're gonna see in a moment i'm gonna demo what we already have uh but the plan for today the plan for today will be uh first was gonna start with authentication and today we're gonna implement a proper authentication with amplify with amplify authentication and we are going to synchronize a stream chat user with our user from our backend this is a question that i've got asked multiple times regarding stream chat you know a lot of people i know that had some issues but in fact like it's quite easy to to implement it uh the only thing is to to know like where and how to to implement all them all the calls so today we're going to do that we are going to first initialize our back-end with amplify and after that we're going to set up our authentication our very simple minimalistic database that will handle like token creations and synchronization with stream chat after that we're gonna get into private messages and here we're gonna implement features like starting a private message with any user from the application and for that we're gonna have to create a screen that will list all the users and like when you press on it you're gonna be redirected to the to the private messages with that user after that we're gonna get into the channel management and here we're gonna implement features like creating a channel uh adding users to the channels maybe we're gonna uh if we're gonna have time we're going to implement something like kicking users banning users uh and so on uh in general the whole management of the channels so that's the plan for today and this uh live stream is sponsored by stream chat sdk thank you very much stream for making this possible if you don't know stream is the number one uh platform to implement uh chatting and feed applications and yeah like at this point like you already know and saw how easy it is to build chat applications with stream and uh yeah like at this point i don't understand like why would you spend like half a year or even more on creating your own backend and coding all the features that stream chat sdk provides by default so yeah once again thank you very much stream for uh sponsoring this video and uh you guys follow the link in the description below to sign up for a 30 days free account and by the way stream also has a free account for makers it's called maker account and that's specifically for young projects and startups that are not yet at that level that we can afford uh paying the subscription so if you are in that case you can apply and get your free account from stream from getstream.io all right so uh getting back to our build for today uh if you want to follow along which i highly encourage then you're gonna need a couple of steps uh first of all you're gonna need the asset bundle uh vr i will include a couple of pre-made components in order to speed up our development uh we're gonna have like demi data and so on and you can get it at assets dot no just dot dev slash discord also you're gonna need an expo environment because this project is using expo and lastly the stream account that has a 30 days free trial you can sign up following this url on the screen uh this is live this is live let me finish the introduction and we're going to have a a chat with the live chat so the starting point as i said this is part two so if you want to start from the beginning you can follow this video here but if you want to uh start from the same point today you can clone the repository that i have provided here and you're going to have all the code that we implemented in the first video that's the lazy route if you want to take it after you clone it it's important switch to the part one branch because part one branch will contain the code that we did in the part one of this series after that install all the dependencies run the project and we are gonna be ready to get started and implement all the features that we planned for today so uh let me as well go ahead and show you a bit the application that we have managed to build in the previous in the first um in the first part but while i'm doing that everyone in the live chat hello everyone i want to know where are you joining us from today how how are you doing guys so uh first of all our application is greeting us with an old welcome screen and here we have a simulation of a sign up screen because we are not actually signing up a user with any back-end we are only signing up with stream chat sdk so here anyone would be able to to sign with the same username because we are not validating anything so full name vadim and here something like this login will you work uh why are not working okay that's the demo effect every time when you're trying to demo something is not working so what's going on here and handle the exception that's awesome let's have a look let's have a look uh oh yeah yeah one second so um we have our application on stream.io so let's go and check it out and here is our application and the thing that um i had to do because i was testing around uh before is to enable the development tokens we did that in the previous video but i disabled them so where is it authentication come on dev no it should be in chat overview yes here i'm gonna scroll a bit until i see then disable authentication checks save and now i'm gonna be able to showcase the application login it's gonna work it's gonna work so first one is by dim here as well by dim login and here we have our home page initially we don't have any channel selected so we are greeted with this message and then here we see all the public channels on the top at the moment we have only one public channels and all the private channels on the bottom the thing is that we didn't manage to implement actually the private channels uh so that's what we're gonna do today and here in the public channels we already saw people chatting and you can yeah like you can send messages you can tag people for example you can tag people you can add uh photos here for example this one select and then send you can add gifs you can reply to too few wait a second so let's select the channel again i think it's um so in general this is the application as you can see here a lot of people are already talking um yeah we are ready to get started and start implementing the first features but before that uh let me see what people are seeing in the chat hello from kenya hello nathan estonia hello stan very nice informative session we're just getting started so a lot of things are gonna come shortly okay so guys for our backend because that's um the question that i've been getting asked a lot how would you connect stream chat sdk with um with an actual backend with your custom code with your backend being it your custom node.js backend or your amplify firebase or anything like that the thing that we have to do is in app.esx when we connect the client and it's actually in the authentication in the screens sign up screen whenever we connect the client with stream chat this is the stream chat client we are sending at the moment the dev token and this is uh intended only for development purposes uh if you want to deploy your application to production then this token should be generated by your back end this token is should be a jwt token and inside that token the payload of a token should contain a property called user user id and that user id should match with this id that we are sending here so by sending a token that was generated by our backend and that inside it contains a property user id when we send this request from the front end then stream chat sdk we will be able to decode our token and we'll be able to check if the user id that we provided in the token is the same as the user id that we are providing here and only then it will authenticate properly the user because in that situation the connection is secure and then the person who is signing in is actually the person who who pretends to be so uh now the question is okay the question is why do we need to do it on the back end uh to generate the the token we need to do it on the back end because when we generate the token we need to use the secret key provided by stream by the stream chat using that secret key that you should never expose to anyone stream chat will be able to decode your token you might use that secret in your front end but in that situation uh and it's gonna work but in that situation you have security issues because you are exposing the secret in your front end so uh in if you're building websites that's super easy to to to take it if you're building mobile application it's a bit harder but still it's not advisable to have uh secrets in the client-side code so for that reason we need to separate the the concerns of generating the secret uh on your back end in order to to authenticate the user and uh connecting with uh with stream chat sdk from our front end by simply providing that token and the id i hope that that makes sense but i think uh when we will actually implement it it will make more sense so the first step that we have is we need to have a backend for our uh application so for the backend of our application we're gonna set up um uh amplify project and with amplify project we're gonna set up authentication and later on whatever stuff that we need so i'm gonna go to my account hello from india hello from senegal hello guys how are you today uh in our aws console let's go to aws amplify and let's press on a new application if you don't have any application you will see a big button create new application and from this drop down let's press on the build an application not host an application because that's for web for application name let's do discord confirm deployment and now we are going to wait until amplify sets up our project so we will be able to access it through amplify studio ui so come on hi from brazil hello gabriel um hola yo soy vadim i need to learn more spanish that's the constant state of mind so uh the good thing is that yeah like we finished initializing our project and in the next page let's go ahead and press press launch lounge studio to launch amplify studio ui and here we are greeting with a welcome message okay from this page from amplify studio we this is the place where we manage all our backend infrastructure uh and what we're interested at the moment is to provide an authentication mechanism uh to have our users stored in dynamodb so that we will see how to connect dynamodb users with stream chat sdk so you know authentication let's go in the setup authentication and here we can deploy right away but the only thing that i will change is in the password protection i'm gonna make my life easier to to have less rules for our passwords so after that is done i'm going to press deploy and now here we see that our application is being deployed like with the new changes here with authentication so we so we're gonna have to to wait a couple of a few minutes for our cognito resources to be generated we actually speak portuguese oh my god that's my bad i don't know why i thought it's spanish this time i'm drinking tea i'm not drinking coffee because as you can hear my voice is gone and yeah i feel a bit sick i've been feeling sick for the last days but that's not a reason not to to build applications and to build projects hello from venezuela thanks so much for your projects abby helped me so much alejandro thank you very much alejandro i'm pretty sure you're speaking spanish right or no okay i'm not i'm not going to assume the languages because most definitely i'm going to be wrong yeah we are waiting right now for our application to be deployed and after that we can uh hopefully that made sense but that's horrible all right david hello from argentina how is going to be hello in your language let me search oh okay it's ola so we have a lot of spanish-speaking subscribers marooks hello marox from algeria perfecto let me search what nintendo means i don't know i didn't reach that word in duolingo yet okay so good enough talking our application has been deployed so our next step would be to copy this command from here press on the deployment successful and here we have amplify pull command let's press to copy it and let's go in our application open a new terminal and from here paste our command to pull all the changes yeah are you sure to log in yes let's login successfully logged in and back here we need to choose a couple of options for everything to be configured so default editor in my case that's visual studio code uh the application but we are building it's a javascript application and then choose the react native here source directory path let's leave it by default as src src distribution as well build command start command and do planner modifying this backend press yes and then enter okay that has successfully pulled and uh if you're interested what was generated we it was generated one file in our src directory which is called aws exports and we say ws exports contains all them ids and settings for our services in our case we have only authentication and that's why we have only this aws cognito settings when we're gonna add more things this file will contain more configuration another thing that was added was the amplify folder and here we have a back end and here is where all the code for our backhand leaves uh we will rarely have to touch it and yeah like we're gonna get there uh the next step would be to install the necessary libraries and for that i'm gonna go to docs to copy them from there and let's go to getting started choose here react native react native and let's go to the setup full project let's scroll down a bit and where we have installed amplify libraries select the expo copy back in our terminal let's paste it and enter do you always use the ui base code for all your react native applications if you meant if i'm not using any ui libraries and i'm coding everything myself uh in most of the cases yes that's true i don't know like i feel more comfortable uh creating my own components uh making sure like to create them reusable and so on when i have when i'm working on a bigger project however on when i'm doing projects on the web i tend to use ui libraries but mostly if i'm developing for web that's some internal tools and for that like i don't want to spend a lot of time uh customizing everything and i'd rather use and i don't want to spend a lot of time building everything from scratch that's why i'm using a library that provides all the buttons inputs and so on but because my applications usually are facing the end user i want everything custom and fully flexible so that's why most of the times i use my everything myself so after this is done let's go back and start configuring our uh amplify back end so for that let's open up.tsx and here let's import a couple of things first of all we are going to import amplify from aws amplify after that we're gonna import the uh settings the aws exports file basically these aws settings uh here so let's import aws config from this directory then go into the source directory and there you will find aws export after that having these two things we put them together by calling amplify.configure and we send their aws config see that it is deprecated and actually it's going to work but let me try to destructure it will it work like this yes probably the the default export like this uh is the old way of doing it and it's deprecated default is deprecated so let's try to do it with uh destructuring it so we have here aws config and we can refresh our application but nothing will change um yeah we might need to to actually re-run the server but let's see all right so our application is running we don't have any errors that's good it means that it was configured correctly we installed the libraries correctly sorry and now the next step would be to implement authentication you're going to be amazed how easy it is to implement authentication so the only thing that we have to do is import authentication from actually it's from aws amplify react native but not authentication but with authenticator with authenticator hook go here where we have our export default function application let's comment out the export default because we are going to export them here so let's write export default and we're not going to export default application right away but we're going to wrap it inside the this higher order component with a woof anticater now we first will execute the with authenticator which will manage the authentication state and all the authentication screens and only after we possibly authentication we're gonna go to our application here so what's wrong there with authenticator we might have to no actually we we don't have to restart restart it so right away we are greeted with the signing to your account screen so what we can do here go to the sign up screen and here create a a new user for the user name let's provide a valid email because we set up the username to be in form of email for the password define a password email let's do the same and phone number doesn't matter uh because we're not using it for verification now for the username let's repeat our email and let's grab that confirmation code that we received um yeah on our email so let me check it here it should be five six five three two zero okay come on five six five three two zero confirm okay it worked and we are back to the sign-in screen which means that we confirmed our account and the last step would be just to sign in uh in our application and only after doing this we are gonna see everything that we have in our application and of course in our application by default our navigator will render this welcome screen uh but we don't need to do that so from the source screens no from the source navigation index um i'm going to to what for the moment i'm going to delete this uh sign in screen and i'm gonna leave only only these two stack screen root and stack screen not found so now we are right away uh here and uh yeah the problem is that we don't see any uh chat rooms yet because we didn't authenticate with stream but that's uh the next step so we still have a lot of things to do the good thing is that now uh if i reload the application i'm not gonna see the authentication screen again and uh what else what else uh probably i'm gonna show you also how to sign out because that's uh that's an important one and just let me think where to where to put it probably in the navigation drawer navigator uh where we have here channel list here custom drawer navigator i'm gonna add here at the bottom a text field called logout and on press it's gonna call logout and let's implement this function here const logout equal like this and i'm gonna have to give some styles there so style yeah simply color white uh font weight bold come on where are you and and what else i don't see it height 50. actually saw it once but now i don't oh it's here log out so i don't need this flex one it simply should be there log out yes and i'm gonna add actually some margin ten when the when this displays the error we're not going to see the logout but if i'm going to refresh here is the logout button and i can press on it and yeah let's go ahead and implement the logout functionality for that we're going to simply have to import the authentication module from uh react aws amplify and in our logout function we simply do dot sign out we call this function and let's try to press press on this logout and we are back to the sign-in screen and if i refresh the application we are still gonna see here so that means that everything behind the scenes when it comes to authentication is managed uh by uh amplify using the amazon cognito i'm gonna sign in back again if you're interested on how you can customize the authentication experience uh i have done a very very in-depth tutorial on authentication screens that takes you from doing all the screens from scratch yourself until implementing amplify authentication with custom screens custom themes custom colors and so on so if you want to check that out also check it on the channel where i'm going to try to leave a link somewhere here so sign in yeah because i made a mistake here okay we are signed in let's check the chat for a bit can you make a beginner friendly tutorials uh if you want to get started with rack native the most beginner friendly tutorial that we have on the channel is the tesla clone you can check it out like it's very simple uh i tried to to make it very simple but like other projects as well i'm trying to to walk you through all the steps that you have here spotify application tarou yes we have already done the spotify clone check it out on the channel you have to build an android application with rack native and expo but i don't need i don't know if i need to use a ui library or build a ui from scratch it depends on the requirements like if the ui is not the most important part and you're just developing a proof of concept go for some ui libraries but if you have more experience and you need very custom ui event you'd have to do it from scratch how can i join your course i'm the waiting list forever yes regarding the course uh this week i've been working like crazy on the course and i managed to finish the biggest module so far which is is covering the api and it's covering very in-depth with all the features of api um also covers graphql apollo client to query and cache your uh your backend back-end api and a lot more like authorization authentication um lambda functions for our api and so on so that was the biggest one and uh i'm gonna come with some updates very very uh shortly like probably at the beginning of the next week or monday expect some updates about the course i'm very excited about that i've been working like more than half a year uh on it basically mostly every day so it's it's something that i already see them the end result and it's it's very powerful i see that a lot of people already uh get a lot of value out of it and uh are managing to build full stack applications which is the goal of this course like to to teach you to to be independent developer to be able to take a mobile application from zero to production to market developing both the front end the back end and also making sure that everything is secure performant and cost efficient so yeah if you're interested the link to the course is in the description below join the waitlist and very shortly i'm gonna send an update and back to our video so as i said let's have a look at this actually i'm gonna show you in the documentation of stream because it makes a bit more sense there uh no uh so the way we are we have been using uh the connect user user method from the stream api from the stream client was using that dev client now as i said before we need to provide here a jwt token that would contain that would be generated on our back end and it will contain the user id that we provide here so uh because it needs to be done on the back end and we are using amplify our goal will be to generate it in a lambda function a lambda function is a simple function that is running in the cloud which serves as a backend logic and where we can um yeah we can define like what should that function do uh hook it up to our api endpoint and then with a simple request to that server we will invoke that function that function will generate for us a token uh by encoding the user identifier and then and then we're gonna receive it here and send it to the stream chat and this way we're gonna make the connection between the two first of all let's see how does an authenticated user look in our cognito user pool to know like what data do we have here to get that we can do user data is equal to a weight authentication dot make sure to import authentication from aws amplify where is it here and we will call current authenticated user now if i do console.log user data we will uh why i do not see it oh because we are not calling this connect user okay let me grab it from here i don't know in the update yes sec somewhere let's i know let's do it here i cannot do it here const fetch user and i'm going to call fetch user in this use effect let's import authentication and in our application when it mounts it's gonna uh show us the current authenticated user so back here we see the data about our cognito user amazing uh what is important to uh to see here is this sub which stands for subject and this subject is the unique identifier of a user so we are going to use this subject uh as the user id and we're gonna send uh first of all we're gonna send it here to the user id we're gonna send the user sub and inside the jw token that we're gonna generate we're gonna encode the user sub as well so that they will be the same and they will match okay um so our next step will be to um to add an api because it's going to be much easier to call a lambda function through an api uh without having to manage all the authentication headers and so on but uh i expect that you already have an api so i'm just going to show you the part that we need only for this token this can be done in your api as well so for that let's call amplify here in our terminal add api let's select graphql authorization mode uh wait wait a second what's happening here for me okay here is the graph color that will be will create select a setting to edit or continue name discord authorization mode api key and configuration disabled well uh the only thing that i don't like from here is the authorization mode api key because whenever we have authorization mode api key we will not be able to get the user data that is doing a request so for that reason uh we are going to select from the next option authorization modes because we need to uh change it to the amazon cognito user pool that means that our api will be users will be authorized to the api using their cognito user pool so in that situation we're going to have access to their data from our lambda function configure additional authentication types no and we can continue choose the schema template let's choose a blank schema do you want to edit the schema now let's press yes and it will automatically open it if it didn't open for you that also might be the case then go ahead in the amplify directory backend api the name of your project and then here you have schema.graphql what i'm going to do i'm going to delete this public rule because i don't need it to be public and if i leave it it will ask me to generate a key so we don't need that what we need to do is to define a query that we will be able to run in order to generate them um the token so on the graphql we're gonna add a query on the type query and here we're gonna specify the query name get um get stream token this guest stream token will return a string so let's say string and it's required and we will not pass any parameters here now in order to link this query to a lambda function so whenever we call this query we will execute the lambda function we can add the graphql um i forgot the name the add function here function and for the name of a function let's say get stream token but that's not it we also need to assign the environment variables to this name because our function will have uh will end in the environment name so for staging it will end in dash staging forever will and in dash production get stream token yeah that's okay so we have basically said whenever we run this get stream token query execute this lambda function the problem is that we didn't add the lambda function yet so let's go ahead and do amplify add function to generate this guest stream token lambda function that will be responsible for generating tokens let's select lambda function provide an aws lambda function name we called it get stream token make sure it's the same name as here [Music] without the environment because the environment is going to be added automatically and for the runtime i'm going to choose node.js and for the template i'm going to choose the hello world lambda do you want to configure advanced settings i don't think so i think we have everything that we need no actually we need to set up environment variables because we don't want to hard code our keys inside the lambda function so it's better to send them free environment so let's go ahead and say yes do you want to access our resources in this project from your lambda function no do you want to invoke this function on a record no do you want to enable layers no and here do you want to configure environment variables yes we do and here enter environment variable name so let's call this uh stream stream underscore key key and let's go ahead in our stream um dashboard let's select our project in my case this is disk or clone let's go to that chat and here overview if i scroll down a bit i'm gonna get to the access keys so the key in my case is this one so let's copy and let's paste the value and we need to add also the secret so don't press i'm done yet but add new environment variable and this is going to be stream secret now the environment the value for this value we will get from that click to reveal from this secret so let's add it enter and now we can press i am done so now as we can see we can access the following resources from environment variables environment region stream key and stream secret do you want to configure secret values this function can access secret values this function can access no probably we don't need to and here it asks do you want to edit the local lambda function now let's press yes and press enter to continue so our vs code open automatically our lambda function here if it didn't go ahead and open amplify backend functions and the get stream function and in the source openv index.js and this is a current level function so it's a normal function of only difference is that it runs in the cloud and it will receive this event with all the data that that it's we're gonna send there and the structure of this data there is a documentation on the structure of this data if you're interested on amplified docs probably functions i don't remember exactly graphql server in lambda calling graphql api from no no no calling dynamite b calling it's this one somewhere here well i cannot find right now exactly the documentation for this event but one of the things that uh this event will receive is the identity of a user that is um doing this uh query so but actually let me go ahead and just deploy it like this not to confuse you even more and then we're gonna discuss later so new generated token let's return a just a random string so that we can see uh if it's working properly now let's go ahead and deploy everything not git deploy but amplify push dash yes and this will not yes but yes and this will create all the things that we have configured at the moment here they will create it in the backend in the cloud for example our api in the function an error occurred yes because in the schema.graphql we should use double quotes not single quotes i always make this mistake so yes we're gonna wait a couple of uh minutes uh until it deploys the first time and then we're gonna uh yeah continue with our features uh i'm gonna be back in just one minute i need to clean my nose uh so hello hey i know you must will you ever return to the tick tock series you never finished implementing a scoreboard i don't know i don't know if i'm gonna uh to be honest if i'm gonna return to the tic-tac-toe um because like with these clothes like there is no exact stop line that you would say okay i've done everything because you cannot do everything so it depends on like balancing what most of you guys watching will enjoy and will take uh as value and with balancing with uh time like and and and the projects and other projects uh that are important on the channel uh as well balancing it with the course because like the more detailed and more in-depth stuff uh it's is for the course and for the people that want to take their career to the next level uh so yeah that's uh a quick response so our function has been deployed and what can we do now let's go back to our aws console here let's refresh this page that shows our project and i'm going to check the api here category and let's press on the view in upsync it will open here in upsync and we can check the queries at the moment we have only one query getstream token as you can see so let's select this one and let's run our query we see a request fail with status codes 401 this is unauthenticated because we didn't log in with our credentials for the client id select the one that says client web not just client username let's do like this the one that i used to register in the application here login will it work yes and now if i run i see the answer get um guest stream token return as new generated token that's the value that we return here now the question is where will we see this console.log event we will see this console.log event if we check the logs of our lambda function but first let's find our lambda function uh to do that let's go back to our amplify project and here let's select functions we see the view in lambda you can open it up here and here you will see all the information about our lambda function including the code but don't edit the code here because we will overwrite it next time when you deploy the application uh what's interesting here is for example monitor and in the monitor let's press on the view logs in cloudwatch cloudwatch is the service responsible for logging and our lambda function will send all the logs all basically console.log events we'll send it here so here in the log group if i go down i will see a couple of log streams so select the latest one and we will see here not in the first drop down but in the second one we will see the info event basically what we say event and the event contains like this was a query the field name is getstream uh what is interesting is this identity and the identity is data about the user that is doing this uh query and that's why we needed the authentication and the amazon cognito authorization mode for our api because now from our lambda function we can get this sub which is the unique identifier of a user and we can right away encode it how we're gonna encode it we're gonna do that based on the um using the stream chat sdk uh for node.js and if we go to here to the documentation for the node.js there varies client and users token and authentication or even like in the first one back end here we see the first step is generating user tokens so to generate user tokens we simply uh create a client by passing their our id and our secret and with that client we simply do create token and provide their id of a user as simple as that our stream chat is coming from the package stream chat and the thing is that by default we're not going to be able to import stream chat here because we didn't install it in that project like all lambda functions you can think of them as separate independent projects and very independent projects because as you can see this getstream function in the source it has a package.json and here you can specify the dependencies that you need so our dependency will be stream chat and for the version you can actually like navigate there and do npm install but i'm gonna do it actually manually uh not to have to go there so npm stream chat let's check the version the latest version 6.2.0 let's go with this one uh and i'm going to add 6.2.0 here dependencies yeah i forgot the comma so make sure to add this dependency to our package.json in the function getstream getstream token and now here we're gonna be able to get the stream chat by doing require we're gonna require the stream chat sdk and here we're gonna call stream chat is that how it's done stream chat yes now now we need to create the client so let's create the client but i'm not going to create it here i'm gonna create it inside this function so client is equal to stream chat dot client right no stream chat dot get instance and here we need to provide the key and then the options where are we taking them well we could um hardcode them here but we specifically said that we don't want to hard code and if you remember we sent them as environment variables to our lambda function and to double check that you can go to the lambda function go to the configuration and here environment variables we see stream key and stream secret to get the environment variables we will take them for example stream key is equal process dot environment dot stream key and the same for the stream secret where i can easily in one line destructure them from there stream secret is gonna be the structure from the environment now i can pass the stream key as the first argument and the stream not chat but stream secret as the second one one second okay now using this client const token equal let's see here client dot create token and then the name so it's client dot create token and then here we need to put the user id how do we get the user id well remember in this event when we uh console logged it we have here dot identity and inside identity we have this sub so our idea will be event dot identity identity dot sub but in some cases this value might be missing so we could do if event question mark identity question mark dot sub is null then we will return i don't know an empty string or we we could throw an error actually we could throw new error but i'm gonna keep it simple and return empty string now this token is generated and we can return it from our lambda function okay that's everything our lambda function should do it simply should initialize a client but the difference between the client on the back end and the client on the front end is that on the front end in the tsx when we call client get instance we are providing only the api key not the api secret that's the idea because in the front end we should not use the secret that should happen in our back end and here it's safe because as well like we're using environment variables and so on so let's go ahead and deploy this new update to our lambda function and give it a go and see if we didn't make any mistakes i love this man's voice uh the thing is that i'm a bit sick today so yeah but i'm happy he's looking good thanks well i'm gonna be back in one minute guys i need to do something important okay i'm back come on updating the lambda function usually doesn't take a lot of time yes it is done and now we can go ahead and run try to run the same query one more time one more time so let's run the query and we already don't see that string but we see an actual token so that's amazing however if you see any errors to debug it again go to lambda function that you can find by going to your amplify application here function and you can right away press here viewing cloud watch this is going to be where your logs will will be stored you access the latest log stream make sure like check the time uh and here you will if there is any errors you will see them in one of these log events if you have double check what's the problem and then go back and see like if you have some issues here or if you didn't provide properly the environment variables and so on but because we are uh in our case it worked that's good and we can close probably everything and and what should we do next well we have this context authentication context right and here we is where we're saving the user id and set user id well you know what um most probably as well here because it's authentication context is where we will handle the client connection with um with stream chat basically the functionality that we have at the moment in the sign up screen with connect user uh so let's keep this one here and also the authentication context now what do we have to do well when this thing mounts so we're gonna use a use effect we will call um connect stream chat connect stream chat user so let's get this one here connect stream chat user is going to be a function let me do const and here uh sync now in this connect stream chat user i'm gonna bring the logic from our connect user function here so let's get it from here bring it to our connect stream chat user and here we will need a client a client uh our client is inside our app.tsx we have this client and we are providing it to the chat client um because chat client is below our authentication context our authentication context will not have a client and will not be able to access it using the use chat context because it's above the chat but that's how it should be uh let's send the client to of context here as client uh and this way in authentication context besides the children we can also get the client okay we have client connect user uh for video as i said we don't need username we need a unique id identifier of a user and to get the unique identifier of a user we're gonna use the const user data is equal a weight authentication and let's make sure to import authentication and then call the get come on current authenticated user now from here the sub will be user data dot attributes dot sub we can console even warn this to see it on the screen let's save and let's reload uh authentication context what's happening possible not this one yes it's this one so it means that we are getting the sub correctly all right so this sub is gonna go here for the name actually we don't have uh the username because we went with a very default authentication and we didn't added any custom fields which you can do in amplify so for that reason actually i'm gonna destructure the sub and the email from the user data attributes so for our name i'm gonna simply pass email because that's the only identifier of a user that we have by default it's email and id for the image i'm gonna keep that one but for the token let's just simply add the token that we saw here for example where here this one so let's copy this token and let's use it here this token was generated for specifically for us and um yeah let's see what else do we have to do here channel channel watch and set user id to the sub to the this user identifier let's have a look now uh now that we are not using development tokens anymore we can go to our dashboard chat and overview let's scroll down until we get to the authentication and let's disable them i mean let's enable authentication check by disabling this option settings successfully updated and now we should be able to to connect to create a user in stream chat is decay based on the user from our cognito so if i refresh pod hello how are you doing thank you very much for being here this is a warning and it's coming from something else this is the user but we are simply console logging somewhere which i don't know where uh probably in the app.esx fetch user yes i don't need it anymore authentication and i don't see any error but what i want to do is remember the sub of a user we can copy it or just note it down and check it i'm gonna copy it and let's go to our stream chat sdk and here in the chat explorer we will be able to see all the users and we can even search by user id and right away we see here a user that was created uh two minutes ago basically now uh last active is online uh has all this data about information the name is this one so what that means it means that we have successfully authenticated a user and connected our database user and our cognito user with the stream chat sdk so again let's repeat what we had to do and i'm going to give some hints on what you have to do if you are not using amplify the only the only step that is required to generate this token by the way we have to dynamically get it but i'm going to get there soon so the only thing is that instead of development tokens that should be used only in development and never in production instead of that we need to generate a user token a jw token for that specific user on our back end we need to do it on our back end because when encrypting and creating this token we need to have the stream chat api secret key in order to be in in order for stream chat sdk back-end to be able to decode that information basically this is a token that was encrypted using the secret and using the same secret amplify not amplify but stream chat sdk backhand can decrypt it and check if the id is the same here because if i would provide here a different idea like 123 you're gonna see an error so let's go here let's scroll down wait a second i cannot oh here error user token does not have a user id or is not matching with user dot id so our user token uh the user id there and the actual user id are not matching because here we encrypted our sub but here we are passing one to three if i remove it we're not going to have that error anymore because they match so that call of um [Music] generating this token on your back end is very simple like it's a one line of code basically here you can see it cost cons token equal server client dot create token and this server client is the same client that we know how to implement using the get instance but instead of just providing the api key you also have to provide the api secret that's the only difference between client the service client and the client client and here you can see in different like javascript ruby python php and so on perfect and yeah then you return it to your mobile application this token and you can connect the user to stream chat and this way you connect them together all right but as i said we need to do one more step here because we need to dynamically get this token so how we're going to do that well we're going to uh where is source we're going to have to run the graphql query that we ran here v query get stream token we will run it in our application to do that in our source amplify automatically generated for us a graphql for folder where we have here queries so let's import this get stream query in our authentication context and a couple more steps uh so import get stream token from graphql queries then we're going to import the api module from aws amplify and also the graphql operation now with these three things here we can go ahead and do const token response is equal to a weight uh api dot graphql because api has rest and graphql we need the graphql and here what do we want to do we want to run a graphql operation so let's call graphql operation and which operation the getstream token operation let's save and let's console.log this console log the token response so let's see what do we have here here is our token response it has an object with a field data and inside data there is get stream token so if i'm gonna do const token equal token response.data.getstream token and if i'm gonna console this one should work yes it's here now we will take this token and we're gonna provide it to our connect user but before that let me check if token is not defined then i want to alert alert failed to fetch that token let's import this alert from react native we don't have rack native here like that and here i'm gonna have to safely access this data like this and we need to stop execution by returning right not to to go here okay i'm looking i'm just trying to figure out if we managed to to implement everything that i wanted and now if i'm gonna go to the to this one i see the public channel and i can start chatting here and others will see this new message and my name will be mail which means that i have successfully created dynamically an account on stream chat in our in in our application okay that's probably it regarding our uh our authentication with our database do you follow guys how how is it going so far do you have any questions if not we're gonna have to move forward and before moving forward i'm gonna simply commit everything because it's quite a lot of things here set up amplify authentication and connection with stream sdk perfect all right so uh my next step that i have planned is to properly separate our public channels from our uh from these channels because by doing this we it doesn't look very good because they are displayed on half of the screen both so for that reason i want to add a very simple two buttons here or two tabs on the top and you would be able to switch from public to private channels so for that let's go in our navigation drawer navigator and here in the drawer navigator where we have our custom drawer uh what we're gonna do well first of all let's uh let's add these two texts so besides public channels i'm gonna copy it and paste one more time uh and if i want to render them in the same row i should put them into a view so let's put these two texts here the view will also have some style styles dot tabs and now this is going to be private and volvo one public let's import the view from react native and let's implement these tabs styles because i want to display them in the same row so flex direction row uh and then justify content i want space evenly now yes i see them here on the top for the group title let me actually uh do it like this so font size i want it a bit bigger 18 would be enough 16 probably good and font wait i want bold yes now uh we need to keep track of what chat list are we currently looking at for that we will need a state variable so let's do tab and set tab it's going to be our use state initially it's going to be the public tab so we can we can display the styles conditionally so for that let's add them into an array and add the second conditional style which is going to be color if the tab is equal to public then the color that i want to set is white otherwise it's light gray save here it still looks the same but if i'm gonna change it to private here come on private and also let's remove it from here from group title the color okay what's happening we are light gray simply gray i don't see most of the texts what happened let's white or gray color oh yes because we are we still see yeah everything is fine i think is it gray no is it is it light gray come on oh but valver1 yes of course valver1 i didn't add them i was expecting it to update but i didn't add the styles for it so let's do it like this okay light gray come on what's happening text private why both are white oh here i need to change to private oh my god i'm doing so many mistakes okay now it's better valver1 is with gray and this one is uh highlighted and now uh to each of these texts fields i'm gonna add a one press event and in the on press event i'm gonna set tab to here to public basically i'm going to update the state and on valver1 to private and now i can move from one to another okay the last step would be to delete this title and conditionally render this channel list or this channel list depending on the tab so we can do if tab is equal to public i want to render this one with public filters this channel list otherwise i want to render this channel list save okay here we have public if i go to private i see let's start chatting because there are no rooms there you can play around with these tabs i don't know for example border bottom width of one and border color and gray yeah maybe or let's do border both border bottom and border top with one and also padding vertical five or ten i don't know i'm not a designer in this situation it doesn't look very good so i'm going to leave it how it was because because it was good so now we have this nice uh switch from public to private messages but the problem is that with private messages where we have log out you know what i'm gonna do text align center here perfect and i'm gonna actually extract it to [Music] styles dot log out so log out sv styles great so as i said our next step will be to start private conversations because at the moment there is no way to start private conversations so how are we going to do that well for that we first need a way to display all the users that we can chat with basically a directory of users so let's go ahead and create a new screen called user or yeah let's do it like this user list screen dot esx in this i'm going to generate a very simple component that will have just a text user list screen for now and let's go back to our drawer navigator and scroll up until we see this screen let's copy it and we're gonna add one more here called user list let's include user list screen and for the title i'm going to do users now here in the private messages we need to have a button to to actually start a new private message right so let's go again in the drawer navigator uh where we are rendering the public no the private things so before the channel list let's add first of all we need them the fragment because we will have to add a button here so that button that button actually um we can define in the components not to have to repeat it multiple times so in the components let's do new file button.tsx react native functional export and this button will receive two things the title of the button which initially by default i mean is going to be button and we're on press event that by default will be an empty function now instead of this view we're gonna render oppressable instead of this title wait a second instead of this title we're going to render the property title and the on press event for the pressable will be the on press event that we receive here basically a very reusable pressable component has no corresponding closing tag okay because here is a closing tag okay now let's do rack native functional export not export direct native style and here we're gonna have like the style styles dot container and style dot text container for now let's just do background background color just to see it and we're gonna use the colors that we import from the constants uh dot light dot tint let's keep it like this uh have a look at how it looks we need to improve a style sheet by the way and then we can update the styles so let's import this button in the drawer navigator and let's render it here but then that was imported from make sure it's imported from components button this button will have a title of i don't know how is how would it be start new conveyor station probably is too much but the on press is gonna do something but we don't know at the moment what exactly is going to do now okay here is on the top we start new conversation so let's go to the button and add more styles for example some margin of course like 10 some padding inside to have more space than and that's already better align items center and for the text we're gonna do color white font weight bold and that's probably good i'm gonna also do border radius five to smoothen off the corners of this button okay with a button we are done we have it pretty good here whenever we press and we start a new conversation we need to redirect the user to to redirect the user to the user list channel we are going to redirect it using this props.navigation.navigate but instead of always calling props.navigation i'm going to do const navigation equal props basically destructuring right away here and i can remove props from here so navigation dot navigate to users list so if i press start new conversation it's not working because user list i messed up the name start new conversation and we are on the page users awesome so on the page users list what do we have to do we have to query the users from our application from let's go to uh get stream documentation to see where we can find this information so chat messaging docs and for react native let's go to the client and here come on for client and users there is a way to query users so to query users we simply call client.query users and then you can also provide some filters there but it's pretty simple uh so we are gonna need um to import the use effect because we are gonna run this when this page mounts and i use state in order to uh to save the users that we will receive from uh from backend so in way use effect what we are going to do this is effect will be called here we are going to fetch users fetch users and let's simply implement this function const fetch users equal to async and here we're gonna do const response equal await client but where do we get the client well we can get the client uh using a hook called use chat context and this chat context will contain this client so we can call now client dot query users and we're not going to provide any uh no we actually need to provide an empty filter let's do console log response to see what do we get here let me refresh cannot have the drawer navigate where do we have this one while rendering a different component channel screen cannot update drawer navigator to locate the bed set state call inside channel screen channel screen channel screen do we have something here this one is is it coming from this one yes it it was actually coming from that one set options with a title never mind we're gonna see why and the other one like if again like you are you want to it's not a bad problem like this one error no credentials or application id but if you are annoyed by this i'm going to show you real quick how to get rid of it so in web.tsx where we are configuring amplify let's uh override this amplifi aws config by putting it into an object destructuring all the values and we're gonna destruct uh override the analytics and uh lead ticks is it like that enabled equal false let me double check if that's how you do it [Music] it's a very let me check let me check if i refresh it analytics yes thank you it's a lytics enabled false did it solve it oh it's not enabled false but it's disabled disabled true and now we shouldn't see that error anymore the annoying error yes everything is clean um so let's go to the uh start new conversation here and right away we see the response with all the users from our application well let's go ahead in our user list screen and instead of rendering this text let's render a flat list flat list where the data will be well we need first of all the data so for that let's add users set users equal use state like this initially it's going to be empty array so let's call set users with response dot users now in the flat list for our data we're gonna send users from our state and for our render item well we need to create a new um we need to create a new component for a one item that will render the user var so the file will be called user list item.tsx and let's do recognitive function export back to our user list screen in the render item it's going to be equal to this and we have a function that we will receive the item and we will return the user list item that was imported from the component and let's send their user equal to this item that we get let's save and let's go ahead uh start new conversation and here we don't see anything but if i'm gonna do react native style and here a style for the name with color white and give it to this style equal styles dot name just to see them style was not imported so let's import okay we see user list item user list item user list item because that's what we get here but if we look in the log this is the information that we know about the user so one of them is the image another one is the name then it also shows if a user is online or not uh the role if it's banned like there is a lot of things that you can get from this object and decide how you want to render that list of users what i'm going to do is let's start with simply rendering the name so i'm going to grab a user from our props user and render it here as user dot name okay all of them have a name now and the other thing that i want to do is render the image so let's go ahead and do source equal uri user dot image and for the style i'm gonna say styles dot image and also style for this row or root for the image let's do a width of 50 pixels an aspect ratio of one to have it squared and after it is squared we can do border reduce 25 to render them as a circle start new conversation can find variable image yeah because we need to import it from react native so here start new conversation we have all the images and the names perfect in the root what do we have to do here to provide justify flex direction row then um align items center to render them on the middle of a line and for the and also some padding here 10 will be enough probably yes and for the image margin write 10. okay for the name we can do font weight bold yeah that's probably good vadim how are you doing it it seems but like you have a cold uh yeah i have it but i don't know i've got my tea and we're going strong we do not miss any fridays right okay so what's next what's next we have we are rendering all the users in our um from the stream chat backend that we are querying here so the next step will be what are we doing whenever we press on a user well we want to start a conversation with him right because that's the usual thing that you want to do to handle the press events on the user list item let's import instead of a view let's import repressible and replace it here on press we can actually implement the functionality of onpress here in this user list item but i think that in different pages where we will use this user list item but one press event will be different in one page you want to start a conversation in another one you want to delete him i don't know so for that reason i'm going to receive this on press event as a property and let's send it here now from our user list item let's say that on press is have a function that we will call start uh channel start start a private channel with this user so let's define it here const star channel and what do we have to do well in order to start a channel there are two ways to do that channels creating a channel one way of creating a channel is to simply provide a channel id and in that situation you would be able to add users to that channel later or another approach would be to provide a list of members but the thing about creating a channel using a list of members is that later on you will not be able to add or remove members created this way and this is a very good scenario with one-to-one messaging and the cool thing is that whenever a stream chat behind the scenes will make sure that there is only one room with a combination of these users so if we already created it it's not gonna overwrite it it's not gonna create it again it's gonna just uh give it us uh back so uh that's what we're gonna need to do so channel uh channel channel the type is messaging because it's one on one messaging that's good uh the members who is gonna be the members one of them is gonna be our user id because it's us who should be in that channel so for that reason i'm gonna grab it from the authentication context by calling user id equal use of context so let's send you our user id here and the second one is going to be the user on which we clicked where uh which user did we click well we whenever we press we need to send where the user so let's call it like this and send the user on which we pressed uh that's why we're gonna receive it here in parameters and we can say user dot id for the members shall we give it a go no but after creating it we can right away navigate to that uh to the for example if i go to the public to the channel page uh to be able to start the conversation so we create it and then navigate it right away to do that we're going to need the navigation so const navigation equal use navigation and let's call navigation dot navigate and where do we want to navigate to the channel screen is this how it's called i'm gonna go to navigation drawer navigator and here is channel screen and we need to pass where the this channel as a chat now let's have a look if it will work so let's go to the private here let's press on start new conversation and let's start with tony for example we are right away redirected here and i can say hey tony now if i can go gonna go to private conversation we already see a conversation with tony here automatically being added and i can start a new conversation with david for example the problem here is that i still see that hey tony and it was a weird problem but finally i managed to to understand how why and how it it appeared and it seems that in our channel screen where we render our channel we provided the key with channel data dot name but when we generate a channel with a second method by providing a list of members in this situation the channel will not have a name so instead the key will be the channel.id now i can say hey uh david i can go here i see our hey david and if i go to barber one i see hey tony and if i go to the start new conversation with user i can say hey user yes that's that's how we start new conversation how we manage them here okay what do we we don't need the navigation here channel screen oh because we removed it okay so how do you how do you feel guys so far nice amazing okay so that's regarding our private 101 conversations that we can start with anyone from our application very noise what kind of noise uh tarun can you please uh ask me these questions on discord or on some social media and i'm gonna get back to you afterwards because it's not related to to today's project i see you i see the question so oh you mean very nice okay thank you so uh let's commit everything get add git commit why did we do private messages all right now the next step the next step what i want to do is to get into more of a group messaging that we have going on here and to add some some management possibilities for example this is a channel this is um an actual live stream channel so i'm gonna switch the type of these channels to team channels because i want us to be able to see a list of users that is in that channel to be able to invite our users and so on in order to see a list of users we can also query the users of one channel and i am thinking of adding a little icon here on the top right in the navigation that will redirect us to the list of users or to some settings page i don't know for now it can be simply a list of users to do that let's go into our screens let's actually uh start with defining the screen so new file channel members dot tsx let's do channel member screen to keep it consistent and here we have native functional export perfect now in our navigation drawer navigation let's add these uh channel members and the component will be channel chair channel members where is the channel members screen and the title channel members okay we have a screen but how we're gonna navigate there well as i said i want to add an icon here so for vet i can it's gonna appear on our channel screen here we are on the channel screen and let's do it here so besides the title you can also specify the header right just head the right which is going to be a function and here you can render something what i want to render is expo vector icon because we have already vector icons installed in our application and here let's search for users let's take it from phontos and this one so we're going to import it like this and we're going to render it like this in the header right of our channel screen okay i see it there i just want need to change the color to white and what else probably that's good enough like i would add some margins there can we provide style here probably not probably i would have to add in it into an actual pressable because we need to handle the press events so the font was amazing repressible and here for the style i'm gonna do styles dot icon let's define i have the only thing that i want to do is add margin right then yes to to have more space there for the color gray will look better or light gray yes this will look better okay what should happen when we press here well we need to navigate to our channel members but how we're going to do that because here we do not have the navigation object well we can get the navigation object by instead of providing an object to our options to our options property we can provide there a function that will send us the navigation object and also the route object and this function will return an object but make sure to put this object in this uh round brackets otherwise like it's gonna think that it's uh an actual function so now if i do it like this uh on the on press event on this pressable i can do navigation dot navigate to the channel members to the channel member so if i press here can find variable channel members yes because it's a string if i press here i'm to the channel members page if i go here perfect but the only issue is that at this moment i'm rendering this icon even when i don't have any channel members selected so i'm gonna conditionally render this pressable only if the route dot params dot params dot channel exists then i'm going to render these channel members route because remember in this channel we always send this channel parameter object is possible undefined yes that's why we need to add it like this save okay now we don't see it but if i'm gonna go to one channel even this one and now i'm gonna press on channel members i'm gonna be redirected there to be honest i would structure it a little bit different but maybe we can do it later yes well let me add it here okay so um another thing is that we to this channel members we also should send the channel because we will need the the channel to send to to make the query to get all the members of that channel so channel route params channel perfect now in the channel members screen we should do const route let's take the route using use route hook and here let's do const channel equal route dot params dot channel like this route params.channel now we will also need again a use effect and a use use state in our state const i'm going to save the members and here set members which is equal use state empty array now in one use effect we are going to query the members of this channel how we're going to do that well we're going to call a function fetch members because it should be a sync and let's implement this fetch members here const patch members a sync function that will do const response equal first of all we await and then channel dot query let's see how to query them properly from the documentation for example channels and here should be somewhere querying members to do that is query member and we provide an empty filter because we want to query all of them now let's do console log response and in our logs let's go ahead open in the private let's open one of these channels go here and i see that this channel has two members first one and the second one but it's a bit different the structure of a member and a user because one member has inside the data about a user because besides the data about the user a member also has information about what channel role it has when it he joined when he was updated and so on so that's why we are referring them to members and a member is also a user okay so let's do uh set members with response dot members now i'm gonna use the same flat list that we have in the user list screen uh let's copy it from here and add it in the channel members let's import the flat list from react native data is going to be members and user lists should be imported and for a user as i said we don't pass the whole member object we only pass this user because that's what we need like name online and so on so for the user i'm gonna pass item dot user and for the on press i don't know what should happen nothing at the moment we just want to see them so if i go to a private channel let's reload it and i go here channel members signed by demon user awesome if i go to david uh it's the same one virtually is missing keys for items yes it's missing keys like this flat list we usually don't provide the key extractor because we usually work with objects that have an id the problem is that the member object itself does not have an id it has a user id so at the moment flat list doesn't know how to extract the key where to get it from so we need to provide a key extractor which is a function that will receive an item so the item and we should return the key so item.user id that's how it's called user.id probably let's see okay let's go to tony let's see uh my user is twice does that mean that i don't have to to add myself let's check it again so in a private conversation oh this error is happening because it didn't finish loading it didn't finish connecting with the server and we're trying to query them the chat rooms with an undefined filter so to fix that and not to have it in the navigation index here we can check if user id then return activity indicator and do we set this user yes we do set it so now if i'm gonna go to tony check the users yes now i see only two of them and if i'm gonna go to david and check by users it's still with tony what's happening drawer navigator it's not updating yes we need to call fetch members whenever the channel changes so let's add the channel to the dependency list now it's with david if i go to tony tony check us it's with tony if i go to user check it it's with user yes we need to call this fetch members every time our channel from the params changes so now we can look at the channel members the thing is that here in republic if i look at the channel members i'm not gonna see anyone because this is uh actually a public chat room that anyone can join even as guests so it doesn't have actual members and for that like it's i haven't decided yet like how to properly manage them because there are a lot of options and it depends on specifically your use case on how you want to manage this public groups or group chats so in a moment like we're going to go there now we what we have a users users yes that's good okay okay okay so um now probably our next step uh regarding our private conversations we are uh pretty good on this one we are managing it pretty well now it's time to manage as well the public public rooms the group charts where we will be able to invite a lot of people so that's also a bit more challenging but let's go ahead and uh and implement it as well the same way as we have in the private like start new conversation let's also have in the public start new channel so in the screens let's create a new file new uh new channel screen dot tsx uh let's call react native functional export and let's go to our drawer navigator and where do we have it in the custom drawer container for our private one we have a button so let's copy it and add first of all the template van by button and van by channel list for the public one start new channel navigation navigate to new channel and we need to provide a new channel screen here so new channel and the title will be new channel the component as well new channel screen that is imported from our screens now if i'm gonna go here to the public i see start new channel if i press i'm redirected to a new channel perfect here in the new channel like what we have to do let's do react native function style what we will have to do here is simply render a text input with a placeholder channel name uh placeholder channel name uh what else with a style of styles dot input and also let's do placeholder text color to light gray sorry oh i don't feel very good one second guys i'm gonna be back in a second all right so for the styles um well we need to import this text input text input what i forgot text input oh it was imported from our library can find stylesheet as well let's import it here okay uh we have it there and after the text input i'm gonna provide the button from our buttons the title will be create channel and we're on press as well create channel function but we implement it right away here so const create channel like this thank you very much so let's go ahead here start new conversation public start new channel and let's define some styles for our input input and also for the page itself i want to add some styles.root and the page will have padding 10 the input as well will have some height 50 background color i know some gray or dark gray i don't like it i don't like the background color the border uh with one and border color uh gray and padding five and border radius five now probably it's better and some margins to have margin horizontal 10 to be in the same as here okay so we have this form uh the last thing that we need to do is to bind this text input to a state variable so let's do it here the state variable is going to be the name set name is equal use state initially empty string so let's bind the value with that name and we're on on change text or on text change i always forget it's going to be set name now if i'm gonna write something no it's not correct on change text now if i'm gonna write i need to provide the color of the input to white color white yes okay so what should happen when we press create channel we should create a channel of course uh to do that we're going to need the client so the client how can we style an app so that it is more responsive uh like what what specifically do you mean responsive like if you properly define the styles with flex boxes and things like that then your application will scale on all the screen sizes the important thing is not to for example if you have an image and you want to display it full screen you will not do like with is equal 300 pixels and you will look at your phone and you'll see oh yeah it's full screen no that's not going to work because you define a hard-coded value that looks good on your phone but it will look bad on other phones so try to use like i know with 100 percent like relative uh sizes and also flexbox will is is going to help you what i want you to do here is to take the client from use chat context because we need to do con const channel equal client dot channel and here we need to provide the channel type so what's the channel type it's gonna be let's let's try that team channel type because with a team channel type we're gonna be able to like it's not going to be a public channel first of all in comparison with a live stream one so that's what we need team and then here we need them here we need a unique id if you want to create a new conversation you can leave out by the parent and provide the list of make sure to await channel creator watch before accessing channel functions if i don't provide the idea will it assign a random one that's what i'm interested [Music] let's have a look at the documentation channels creating channels and we are channels creating channels and we are interested in not the first one yeah the first one actually we need to provide the channel id and after that we're going to be able to query them [Music] we could use that name for the channel id but that's not very recommended because the channel id should be unique so if someone else will use the same name as your channel i'm not sure what what's going to happen but definitely not something that you would expect you would probably join their server and then let's provide the name of a channel that the user provides in the options this is the display name of a channel okay let's try um and yeah but after that we need to do a weight channel dot create and wait channel dot create so let's try a public start channel and for the channel name new channel create channel something is happening we don't see anything uh rejection id is zero what i'm gonna go in the explorer and in the channels no i don't have it why create invalid chat id new channel letters numbers and are allowed okay i cannot provide a space there that's why actually in order to provide a unique id and not to mess with the name i'm gonna use um like a randomly generated number i'm expo uuid uh so let's grab this package uuid that's gonna generate for us unique identifiers uh not random but unique and they are time based and that's what we need let's install it and then import it like this import v4 as uuid v4 and for the channel id we're just going to simply call you u idv4 like this and this will generate a unique identifier let's give it a try public why don't see the button where is the button don't specify an id but the second parameter it's either i specify a null id because i need to pass the second parameter because i need to get to the third one with options there but let me try if i'm going to provide null where is my button there drawer navigator what happened to you we have button and channel list okay now it's here start channel test create channel probably it's not gonna work when using members-based id specify at least two members why this is optional only if you provide the list of members because if you don't provide an id then stream expects a list of users and this is where when using members based id specify at least two members but we didn't specify so i'm gonna have to use this uuid before let's see if it will work let's try to restart our metra server stopping the server and i'm gonna start it with dash dash vendors dash clear let's go ahead and restart actually press run on ios simulator come on okay so this is an error a very common error after we implement amplify so if you get this error saying just haste map module naming collision get stream token the following files share the same name like the one that is from the backend and the one that is from the current cloud backend basically why this is happening is that in amplify amplify automatically kind of duplicate some of the files one in um in this current cloud backend and one in the backend and metro has issues because they have a same name so the solution would be to ignore the second one to tell metro to ignore the second one uh the solution to this problem i have it somewhere here come on react native issues so [Music] so we need to install um for expo we need to install metro config in our application and then add a metal.config.js file in our root directory for react native cli we simply have to edit the metroconfig because it's already there so to enable this code there so let's install metrocon expo metroconfig save dev because we we need it only in development and after that we need to create a metro.config file in our root directory in root here let's create a file metro.config.js and paste in this code only this code no they import as well so import x exclusion list and here we specify that the current cloud backend just don't take it into consideration and this will solve the naming collision now let's close our server and run it again but it now it's very important to start it with dash dash dash clear all right let's give it a go building while it's building i'm gonna be back here i am and it's still building vicente is saying hi first time seeing your life congrats for the channel and the good videos that you have thank you very much and hello welcome here okay so it's running again um yeah we we're at this starting a new channel test let's create let's check where logs crypto get renova is not supported the should i just get simply a random random react native expo install recognitive get random values imported before uuid since your id might also appear as a more safest is just to import react need to get rendered as a very first thing in your entry point you must be using at least okay we need one more package for this to work all right npm install react native get random values and we need to import with strategy vector uh random values in our app.tsx let's do it at the top here after that react native gesture handler okay now let's go ahead start a new conversation no public start a new channel test create channel let's see in the logs i think it worked because i didn't see any errors and if i'm gonna go to the explorer and refresh i see the newest one with a random identifier and the options config here should be where config name not in the config in there what created by should have information about the name of our channel but it means that it uh automatically created it so that's that's the good part uh the problem is that if i'm gonna look here we don't see this channel here why because of the filters that we are using so if i'm gonna go to the navigation drawer navigation here we are rendering in the public screen where we have public here we are using the public filters and if i'm going to check the public filters the public filters specify that the type of a channel should be live stream well i would say that first of all i'm gonna add the type to these filters let's say private filters will contain besides the members it will also contain type and it should be only messaging because otherwise it's going to return all the wall them channel types not only the the 101 channel types come on where i am drawer navigator so type messaging private filters let's send them properly here instead of filters and other one is here for republic filters uh like i don't need only live stream probably i need everything except messaging so let me try to add operation because um the filtering works based on the same logic as how mongodb filters work and i know that in mongodb to check if something is not equal to query based on uh negation for example not equal we would do something like this so here i want to get all the all the channels where i am a member so for that i need these members in i need to specify that i should be a member of that channel to to see it in my feed but the type of channel should be anything else when messaging will it work public i don't know if it still works because the problem is that i'm not a member there so let me try to query to a comment and see if we get any channels with this filter type not equal to messages query channel filled with error for channels match your query but cannot be a return because you don't have access to them did you forget to include members in yes okay that's uh that's good it means that it will work once we will add ourself in that channel how we're going to add ourselves in that channel when well when we create the channel let's add ourself right away so we create the channel and then we add ourselves here so from the documentation in the channel let's do updating channel members adding and removing channel members await channel odd member well it's that simple let's do a weight channel dot add member and the member will be user id that we will get from the authentication so basically add our self there user id equal use of context it can be possible and all but it won't now uh the one last step for the new channel after we created we want to navigate so navigation equal use navigation not navigation state but simply navigation and advanced let's do navigation dot navigate to their channel screen with this channel right the one that we just created so let's start a new conversation new channel create channel possible unhandled rejection why let's have a look can i serialize querying channels no that's something different wait a second what's happening here so public oh here it is start new channel uh maybe the navigation name was wrong it's channel screen as i see here so it should be channel screen okay let's start a new chat another i don't know memes create channel and it's here hi everyone let's send and i can check the members and at the moment uh in the members list is only uh it's only me it's only myself but the good thing is that now in the private i see only the private messages and in the public i see the public channels uh here and specifically the public channels that i am a part i am part of okay that's good but i need a way to be able to add members to add users to this channel right how we're gonna do that adding users adding users to the channel well when you go to the channel go to the users here should probably should probably be a button to add users right so that's going to be where first of all let me do git add git commit git commit minus m and that was our group channels now in the source screens channel members hmm in the channel members screen uh what we're gonna do well here in this flat list i'm gonna add at the top of this list to add something on the top we can do list header component and i'm going to add a button that we have and the title of this button will be invite members invite members okay list header now we need a screen for this invite members uh thing so let's do invite members screen dot tsx this invite math let's do rack native functional export and we invite members we need to add it in our navigation uh but you know what i'm i was thinking to do first of all let me show you the issue and then like i'm gonna show you how to solve it so now now if i'm gonna go to the memes uh i'm here and i want to go to them um to this channel members and now to be able to go back oh i need to actually slide and select memes once again there is no back button here and in order to add automatically the back button i am thinking to group all the screens that are related to one channel and the screens that are related to one channel is that channel screen is the channel members and also they invite channel members they're all related to one specific channel so for that i'm gonna add a new navigation which is gonna be a stack navigator so channel stack dot esx and here let's import create native stack navigator uh like this let's do const stack equal create native stack navigator and here let's do const channel stack equal to a component that will have the stack dot navigator and inside it it will have the for example this screen but it's not going to be a drawer screen this screen but it's going to be a stack screen uh a channel screen like this header right you know what i'm going to extract this to a separate component just to have it easier so that's going to be here const um header right button or just head and right and it's going to be like this equal to them okay we need route here route so header right let's rename it better members icon members i can route equal route and also navigation navigate equal navigation pressable we need it here well i will add it like this so if route param channels return null and otherwise return our component here repressible so pressable come on import from react native uh navigation we take it from the paragraphs from the props navigation phone 2005 we it from vector icons and styles we define them at the bottom let me copy them oh my god to the channel stack and i'm going to delete everything except the icon because here in the channel stack we need the icon for this members icon oh oh my god so whatever stack screens do we need uh to take from the drawer uh then channel members shouldn't be here it should be here and it should be a yeah stack channel member screen uh let's see right now if it's gonna work channel json string if i cannot serialize cyclic structures so user we are on the channel going here again channel members screen oh we're not we are never we didn't export this one yet so export default channel stack and in the drawer navigator where we have this one uh instead of a channel screen we're gonna say channel stack and we're not gonna have probably a header right the title what's the problem with channel stack did i made a mistake channel stack stylesheet we need to import stylesheet from react native here uh channel stack yes because we didn't return okay my bad now we are returning this tech navigator and we need to hide the title here so header header shown no actually it's interesting so here we see that one but here we see route pram's channel route params channel well okay that's interesting because we um you don't need to create a separate stack i think i wanted i i specifically wanted a separate stack for for this one but it's not just about the screen the buttons themselves but now i'm thinking why do they went this route now the problem is that here i don't have the route channel screen channel screen main or chat it's going to be channel screen chat it's okay it's okay so whenever i press on one channel here that's gonna be the drawer navigator so in the on channel select i need to navigate to the channel screen but not on the channel screen but directly but one more nested screen so here is going to be screen chat van params or i think it was params but i might me i might be wrong so if i go now it's on my chat now evaluating no come on navigation to veer then inside this channel screen to the chat and here i don't have the icon why uh because params most probably is not correct so navigation nested nested navigation graphs no no no react navigation and here let's say nested so navigating nested screen this one but the data how do you provide params that's how i did params screen params channel in channel stack options we have chat and header right members icon with the route from the chat so let's do console log route real quick key chart params undefined why parameters are undefined in the drawer navigator on channel select if i'm gonna navigate to something else just to see if it's at least working if i'm gonna go here no it's not working does anyone see the the issue there screen channel members navigate to the channel screen uh so channel list on select calls this on channel select and this function will do navigation navigate to screen and params i don't get it okay okay wait a second it navigated correctly there but now it's still undefined you can add it manually what do you mean okay here we have it params channel paragrams channel but why don't display it members i can console log route route dot params dot channel oh it should be inverted oh my god come on my dim now now it works better and from the drawer navigator uh here in the options i don't need the function anymore so i can do header shown false to have only one header there so now i can swipe left choose one go here come back i'm still here i still can go there and that's i think much better there is a way to add the hamburger menu as well and you can manually uh open it but still like you can open it just by sliding from the left so what i wanted to do here okay i spent i probably spent like 20 minutes only to fix this issue but now there is this new channel no we can go to the channel stack and we will provide one more channel stack for our one more stack screen for our channel and that's gonna call be called invite invite members let's do invite members invite members okay and now from our channel member screens we have here a button with the title invite members so we're gonna add them on press and on press we are going to call we need navigation here so let's grab it const navigation equal use navigation and we will do navigation dot navigate to our newly added um page invite members so let's go ahead here select a public one memes go here invite members we can go back invite members perfect uh in the invite members i think we will also need the channel so let's pass it there all right now let's go to the invite members and here what we're gonna do um let's again query all the users from our application we can also add some some filtering to make sure that we are querying all the users that are not inside our channel that we are trying to add uh so i'm gonna take that query from where from the screens user list screen and here we have a user fact fetch users and let's grab all of them the client user state and so on and let's bring them in the invite members here let's import use chat screen use state use of context and use navigation now we can as well render them here basically the logic of querying and rendering it's kind of the same the only difference will be in what happens when we click on one of them make sure to import them all of them expected what did you expect so let's select a channel from here members i see two of them invite members and you know what i want to do is to provide some filters i think it's members but no never mind never mind it's good now whenever i press on one of them i want to select them and for that i am going to have another array of const selected user ids i'm going to keep only the user ids in the selected so set selected user ids equal use state and empty array now whenever i press on it select user on press is going to be select user and it's gonna select user it's gonna receive a user and uh we are gonna either add it in this array or not so but let's first start it so set selected user existing users and we will modify these existing users by adding the existing users and then adding the user dot id their advanced now uh let's say user list item going to send where a property is selected and this is selected will be true or false depending if this selected users dot contains or includes the item dot id now let's go in the ease selected in in the user list item and get the is selected uh four way is selected i'm going to add a simple where is it a simple icon check check check check probably probably this one is going to be good so let's render is if is selected is true then render this and design but by default is selected will be false to work in our places so let's import and design and for the name let's do i don't know green okay let's select one chatroom uh i don't know this one okay it's working oh my god uh the only thing that it should be at the end so and design [Music] i'm gonna put it into a view style margin left auto and everything in bad view we need to import okay and now will it work invite members yes now it's advanced okay perfect and um we need a button right we need a button uh as well let's do it as well as the list header component list header component and that's going to be a button with the title invite and the on press is going to be invite users you can hide this button if no selected users are selected by checking the length and only if the length is a trophy value means that different than zero it's going gonna appear there so now if i'm gonna go to public invite members text strings what's happening there okay invite user i need text strings okay i need to make this one to cast this one public memes let's go here invite members and i can press but if i press two times i want to deselect it so for that reason i'm gonna have to check if selected user ids includes user id then we need to remove it otherwise we need to add it so like this and to remove it it's pretty simple we're gonna do set selected user id we're gonna get existing users and we're gonna filter the existing users filter and we're going to keep only the user that is different than is different than user.id now if i'm going to press it doesn't work includes let's see set selected user id existing users filter where what the user shouldn't be on the channel already what do you mean invite members why this is not working console.log here better worn yeah it's coming here but it's not filtering properly filter means keep only the ones that are different all of them are different user id user id oh my god existing users maybe i need to create a new array out of them uh use already existing use oh it's not okay in that array i have ids so i just have to do id is different and i don't need to destructure it probably so now if i select more i deselect it works perfect the user list shouldn't contain any user that already joined the channel yeah that's that's what i wanted to do but then i decided like not to do it yes stream does let us query the channel members so we could to do exclude already uh existing channel members yes uh maybe i can uh come back to this a bit later but i'm gonna be back on one minute and we're we're going to continue with this feature all right so uh let's think uh [Music] okay when we press on this invite we call invite users but we didn't implemented it yet so let's see how to invite members uh updating channel members ad members simply like that okay that would be will be easy await channel we have a channel here right or we didn't get it yet so we need the channel from our use const route equal use route route like this and const channel equal route.params.channel now we using this channel we call add members and we are going to add all the selected user ids after that this is going to be a sync after that we're gonna do navigation dot go back let's have a look so in this memes chat i am only uh alone here as as usual so let's invite tony and you know david invite uh maybe didn't refresh yet but if i'm gonna go again they are here amazing so it actually works oh my god i can't believe it it's that easy it's that actually easy so as as we said yeah we we can exclude that channel members so we can exclude the existing channel members so i could do something like this const existing members equal channel dot query members and here like this now i can do console.log existing members and just for me to see them so invite members where do we console log that thing console log route i don't need to do that oh it's a promise so let's do a weight invite member screen and wait invite members okay we have members and they have this user id um i can do const existing member ids equal existing members dot map member i'm gonna take simply the user id m dot user id now this should be an array of simply the ideas of the users that are there let's have a look invite members existing members map is not a function existing members oh existing members dot members yeah this is their way of users and i think i can uh right away query here members instead of in because i can provide in i know that's possible existing members ids this will return only the members but we know uh wait wait a second id or yes id in existing members but if i provide not in then i should receive all of them except this david and tony are not here my email is there but i guess that i have two two emails so if i don't have this uh thing yes i have two emails with the same and just like that just in these two lines of code we managed to filter them the members and only query the members that are not yet part of of a channel of a channel yes that's really amazing like we have here channel members uh like we could implement features like um selecting here channel members and deleting them that's that that's also very easy and we would do them in a similar way with a selected user guys do you want to join and let's try to test it out and chat with each other for that i'm going to move this one to tunnel and you should be able to scan this qr code with your phone and if you have expo going on your phone it's going to open this project right away on your phone and you can enter and we can start playing around and testing and seeing how it works i will try also to um to send this url in the in the chat so here in the chat i pasted the url as well where you can scan this qr code and we can play around a bit and see so my case it didn't work from the first time but i need to wait until it downloads everything damn i'm pretty happy with this application like it's it's i would say production ready uh it's it's a it's a fully fledged discord clone that would scale with with amount of users that that will join it's super performant because behind the scenes stream sdk is optimized for these use cases so i don't know should we deploy this application for our use case i don't see a reason to do that but maybe so let me sign up with a new account just to check how it works the whole flow one moment and i'm also going to be there uh uni saying just sign up for the waitlist is there a way to ensure a spot i'm willing to make a deposit dying for the program to open up this is amazing content thank you very much i'm interested are you new here or you've been following uh for for a longer time regarding your question uh just keep an eye on your email and you're gonna receive uh an update if you are on waitlist with uh more specific dates about when uh the launch is planned i i'm trying i'm planning the launch uh in april uh but i cannot promise is gonna be like in the beginning of april it can be like in the second or third week because i have still a couple of modules very important modules to film and after that i'm gonna have like a first good version of it i'm gonna be proud to share with you guys so that's uh that's the plan i'm still trying to sign up here and if you're gonna uh keep an eye on email you're gonna manage to to get in the only thing is that like the the the batch will be as well like time limited and you'll be able to probably i'm gonna run this campaign for one week and then like we will get back to working with with people that will join and yeah okay where is my email so so guys did anyone enter there okay the sign-up process is too uh too long hey nas hello how are you doing the thing that i want to improve here is to actually provide that hamburger icon to be able to open the drawer so in the navigation open draw open drawer i'm new here in regards to commenting but i have been watching for a while i will keep a very close eye on my email and sign up at the moment i get it awesome doing amazing brother i'm eating and watching you oh that's so nice but we are we are almost advanced uh but it's crazy like we we managed to be like a discord cloning just two episodes and like it's contains uh everything starting from actually let's uh let's do a demo because we are almost at the end uh the only thing that i said i wanted to do is with this open drawer in our navigation where is our navigation navigation uh channel stack because here we have that header right and probably we will have a header left header left um but before jumping into implementing the actual thing of displaying my icon i will try to replace the navigation here with that drawer to see if it's at least working uh so navigation open drawer will it work because it's in a different context so i don't know hello on press open drawer okay i need the chat list here yes it's working so i can safely create copy this one and rename it hamburger menu i'm not gonna have this if statement i'm just simply going to return it or for the icon let's see what i can we're going to use here hamburger not like that three lines how is it called grip lines not grip lines what's our name for this hamburger menu because i cannot find it searching hamburger menu it doesn't matter this one will work so let's import and design and let's import this one as well unexpected error y and uh whenever we press on this thing we're gonna open our navigate our drawer like this and let's give this hamburger menu to our header left component and it actually needs only the navigation not from here from the hamburger menu it was menu simply yes actually that's true good to know and last reload will be covering deploying on apple's app store google store in the program i'm full i'm a full stack web developer so i'm not used to deploying for mobile applications yes that's actually the last modules that i have to prepare when record and this they will cover deploying to app store and google store uh vary in detail so don't worry we're gonna talk about all the all the details there because uh yeah as you can imagine like deploying a mobile application is quite a process i would say like there are a lot of things that you need to know and that are difficult at the beginning um especially with apple and ios there is a lot of thing to to take care and i'm going to cover not only the development side of how to build application and ship it where but also the marketing side for example you will not be able to deploy an application if it doesn't have screenshots or if it doesn't have other stuff like that so i'm going to cover all these steps that will take your application from code until it's in the hands of the users the hamburger menu is working perfect we can add users here invite members and yes we can invite all of them invite what's the problem there wait members okay we have an error stream chat error update channel failed with our canada members to the distinct channel they don't belong to please create a new distinction with oh the thing is that with a private messages here i shouldn't be able to invite members so that's a thing that we have to check only in the public channels we would be able to invite members let's invite everyone okay we have more who so many people awesome hey can you share the color and icon theme you're using if you're talking about vs code i have a video on the channel that is covering the vs code extensions that i'm using and where i also include them themes and icon pack and so on uni saying holy this program is going to be 10 out of 10 can't wait again going to rewatch this tonight and build along thank you for being so helpful amazing i would recommend uh to start from the previous video from the first one that one is three hours this one is three hours and in six hours you have like everything that we have done so far okay six people already saw a message i'm wondering if you can send messages as well uh so um i'm gonna [Music] add everything to git and i'm gonna commit everything so you have a source code source code as well i'm already tired my voice is has left me for a long time so what have we done here uh adding members to group channels so guys um if you have any questions now is the time uh leave them right now or you can leave in the comments and i'm gonna try to come back and help you and answer with your issues if you have war with anything that you are stuck with thanks again for watching till the end if you found this video helpful and valuable to you please subscribe to our channel because that's helping us a lot here to grow the team and to grow a channel in order to bring much more valuable content in future for you including project tutorials and other specific tutorials that we are launching on the channel so um take care guys stay hydrated write clean code and while in the weekend you can check out this video or this video they're both amazing and you'll learn a ton and that's it for today uh i'm gonna head out bye you
Info
Channel: notJustā€¤dev
Views: 64,655
Rating: undefined out of 5
Keywords: vadim savin, not just development, notjust.dev, react-native tutorial, react native ui design, react expo, react native live coding, live coding, react tutorial, whatsapp clone, build a whatsapp clone, whatsapp clone react native, whatsapp clone tutorial, chat app, react native, javascript tutorial, real time chat app, socket io, react native chat app, discord clone, build a discord clone, discord clone react native, discord clone tutorial, react discord clone
Id: TlS9n58OwLY
Channel Id: undefined
Length: 215min 53sec (12953 seconds)
Published: Fri Mar 18 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.