Build a Poll App with React Native & Supabase (tutorial for beginners)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
what's up not just developers welcome back to a new live stream in this tutorial we're going to build a poll or let's say a voting application in re native and superbase so the application that we're going to build will have the main features of a polling application like creating polls managing them viewing all the polls in our application and also as a user we will be able to vote in different uh polls we are also going to be able to see the results and from more of a backup perspective where this is going to be a full stack application so we're going to cover both the user interface in re native and the backend features using superbase so we're going to start with implementing authentication with email and we're also going to learn about Anonymous authentication because in the polling application maybe you don't want users to create an account just to uh see the polls or actually vot in some of them you might want to only have uh authenticated users be able to create polls so we're going to check and Implement that today as well and for the database we're going to use pogress which is a very powerful uh relational database and super base is built on top of that so for the Tex stack on the uh mobile side we're going to use R native Expo and Expo router and on the back end as I said we're going to use super base actually this uh tutorial is sponsored by super base uh I've been using them in a lot of my projects because it's really easy to build a backend using super base and uh previous week they announced that they become ga uh General available so that you can use them in any kind of production application so if you don't know about super bay yet you're going to learn in today's video super easy to set up a authentication database storage and even do some AI stuff in the cloud with Edge functions with Vector databases so it's a lot of powerful Tools in a cloud um solution so if you're ready let's get started we have a lot to call today and I'm very excited for this [Applause] [Music] project all right uh hello everyone who is joining us live how are you doing guys Oscar thank you very much for joining the channel membership reelio Oscar hello guys so here I have a short uh very short demo of maybe an example of what we're going to have in the end of course we're going to build like different more features maybe we're going to improve a UI but basically on the home screen we're going to see a list of polls that we already have and as a user even as a guest user we're going to be able to go there I already voted for this one so if I'm going to go to to a new one I can vote here and everything works perfectly the second time I go here I see my vote and we're also going to implement updating the vote seeing results which is going to be really exciting on the create poll we're going to give it a title we're going to give it some options and then create poll so later it's going to appear here and also we have Anonymous um Anonymous sign in so for example if I sign up out I'm able to cast votes but I'm not able to create a poll because I'm uh signed in as an um Anonymous user so to create a poll I actually have to go ahead and create an account and sign in so everything that you see here and even more we're going to build into this uh tutorial and um yeah let's uh let's get started let's go ahead and start by initializing a new project uh a new Expo project for that I'm going to open up my terminal let me zoom in so that you can also see I'm going to navigate to my folder where I keep my projects and here I'm going to use npx create Expo app this is a tool to initialize uh Expo application I also like to give it at latest to take the latest version of uh the tool and Van let's do here polls this uh it's going to take a bit of time while we're waiting for things to install um hello guys if you're new to this channel my name is Vadim and on this channel my goal is to help you learn and build mobile applications and we do that using fun projects so instead of talking about Theory we are actually practicing because that's the best way to learn something new is by actually using it to build something exciting so if you are on your journey uh to to become a mobile developer to learn more about react native and everything about around it make sure to subscribe to the channel That helps us a lot thank you very much um anyway our project is already initialized project is ready let's go ahead and open it in Visual Studio code that should be it and um as always I prefer to work with typescript especially because later in the video superbase is going to automatically generate these types for us so it's going to be way easier to make sure that um we are following like the types of our data so uh with Expo the only thing uh we have to do to to move from JavaScript to T script is to rename our up. GS to up. TSX or any GS file to TSX file and after opening the terminal and after running npm start that will start the development server Expo will see that we want to we have a typescript file it will ask us if we want to install install and configure typescript let's just press enter and Expo will take care for everything for us and in a second we should see this screen if you're new to Expo the easiest way to run this application now on your device is going to be to download the expoo application on Android or iOS it's available on both stores and then simply scan this C code using the expoo application or the camera application on iOS and you're going to be good to go and see the application running on your device in my case I have the emulator um on my machine so that you can also see it so I'm going to press I to run it on my simulator it works also on Android emulators if are using for example a Windows or a Linux in that case you're only going to have access to a Android emulator on Mac Osos you can choose between IOS and Android but this project is going to work on both platforms and even we're going to try to run it on the web as well because everything that we're going to do is going to be automatically compatible with web and the only thing that we're going to have to do is test if everything looks okay on on web by the end of a tutorial anyway our application is running and if we open up. TSX which currently is the entry point or the main screen of our application we see uh the the text that is displayed in our simulator if I update it to hello world right away without having to reload refresh any think it's going to update on our emulator oh no I think I connected to a different live stream because not to the one that I that I scheduled so okay not a big problem but sorry for people who were waiting in V room so let me just quickly go ahead and share this one join here okay so yeah now I can see your live comments hello everyone hopefully everyone managed to to join here okay it's quite hot today okay so what's going to be our next step uh I think the next step is going to be to set up and configure exp router uh because our application is going to have multiple screens so let's go ahead and create the export router setup install configure it create a couple of screens and then we're going to next move on to building the user interface so for Expo router I'm going to go ahead and write Expo router docs and Expo has the documentation for export router and I'm going to go right away under the install in ation so installing exper router I'm going to skip the quick start and I'm going to go right away to the manual in instructions installation uh here the first step we already have an expo project let's go ahead in the second step and copy the dependencies that we have to install there first I'm going to copy them from here move to our project let's open the terminal and you can let let's go ahead and stop our development server better because later we're going to have to restart it so with a contrl c it work command see it's going to stop the server I can clear here and I can paste the npx XO install to install all the exper router dependencies I'm going to go back to the documentation and here the next step in the third step we need to update the entry point so we need to set the entry point to exper router SL entry in our package.json so let's open package.json and here under this main let's remove what we already have and update it with export router let's go back we need to specify the schema in up. Json up. Json and this schema is going to be used by exper router to automatically create deep links to our application so we can have have not just polls and then whenever someone will send a deep link to not just polls and then like this it's going to open right away our application so everything is managed here by exper outter now moving on to the next step if we're developing for web uh yeah let's actually install it because it doesn't require a lot of changes uh simply installing rack native web and rack do uh and this one we don't have to change anything because by default the bundler on the web is going to be Metro unless you have a web pack configuration so in our case we is going to use Metro the B.C config is as well uh updated with uh with this one so we don't have to do anything and yeah the next step is going to be to start the development server but to make sure to clear the cach so to do that I'm going to run the same npm start command which behind the scenes if we look into the package that Json is running Expo start so we just need to add DH Dash space-- clear in order to send this clear uh option to the Expo start here let's do enter hello auu hello aab so here is our application started we see that the bundler cache is empty and if I'm going to go ahead and reload my application or press I to rerun it again it should load the new uh application with export router installed by default exper outer is going to display this welcome screen and that's because we don't yet have up directory and the up directory is where exper router is looking for your screens so uh you can go ahead and touch this button but it's going to create WB directory in the root folder and I rather go ahead and create it myself because I want the up directory to be inside the source Direct Dory so let's first create the SRC directory and inside there let's create the app directory I'm going to right away create a new directory here under SRC like components to easier see like that the app directory is a child of the source now as I said exper router is going to look um into the app folder and for every file that we have there it's going to set up out automatically for us a route so we no longer are going to use this app. TSX so what we can do is maybe move up. TSX to the up directory and rename it to index because when we navigate to uh to our application and then slash that's going to be the home screen that's going to be the initial home screen and the file for that is going to be index so if I do index here I can also update the name here to home screen and if I'm going to reload my application I expect to see back the hello world which is coming from our home screen from the app directory managed by Expo router and here we have it it's working it displays hello world coming from index perfect now I think we can go ahead and commit you're going to have access to the source code uh just follow the link to our website to nodev in the description below to get the link to the source code setup exper router okay hello Neo the gift thank you very much no is saying I'm a front end developer because of your videos oh that's so nice always happy to to hear this okay we have a home screen uh what will we have on the home screen itself uh on the home screen we're probably going to have a list of um of available polls so a list of available polls let's start by creating some small UI for that and I'm going to start by rendering a view here after the hello world let's leave a hello world for now we're going to delete it in a moment a view is an empty container so what I want is a simple box inside the box to render the title of the poll so inside the view I'm going to render the text that will say I don't know uh give me a suggestion for a poll I'm blanking uh example poll question so this is going to be our text here uh let's go ahead and give this view the some styles by doing Styles Dot um poll container and also some styles to this text using styles. pole title now the only thing is to go ahead in this Styles and set up the poll container and also the poll title Styles so for the container uh I think I'm going to remove a background color white from from our H page and I'm going to use it on the on the pole container itself I don't know later probably it's going to be a bit different because we're going to use a stack uh yeah maybe later we're going to see it better let's do here um background color I don't know G uh snow not sure if it's working to check I can do red pole container white gain borrow for the container okay now it's a little bit more VIs ible there also uh instead of justify content Center let's try to remove it and this will put all the items at the top of the screen and also I'm going to remove align item Center because I want the child in our on our page to expand to take the whole amount of space there um what I instead would like to do is to add some pting to our page so that we have some spacing around our content I will want also want to add some pting to our pole container like 10 uh maybe some border radius five to make the corners [Music] round for the pole title uh let's go ahead with simply increasing the font weight to bold font size to maybe 16 a little bit larger yeah that that should be uh good for now hello Bruno do you have any ideas about when Expo 51 release date uh not sure actually previous week uh R native 74 was released so probably soon expo Expo is also going to release the next version of SDK that will use the latest R native version will you use the victory native library for the charts um I haven't decided that yet so we'll see because some charts can be actually done manually like with some bars with some views but if we want some donus chart then maybe we can look at some third party libraries okay so we have a examp example poll um example poll and in this case what we actually will have is we will have an array of polls in on this screen because we're going to fetch them from the database and display different poles from our application so initially I'm going to do here a pulse array that that will actually not have any data we'll just have some numbers for the amount of items I want to render because later one you're going to say like when we integrate with super base like we're going to fetch this data so now for every item in this array of polls I want to render one pole container here I could map for them but I could also use a flat list a flat list imported from R native here it was imported from react native and a flat list helps us render lists of data so it has two required properties data and in our case we're going to give this array and then a render item which is going to be a function that will tell flatlist how should it render every single item in this array so for every single item in this array we actually want to render one of his containers so I'm going to copy it from here and put it in the render item and just like that we have a list of poles here if you want to add some Styles some Gap some some spacing between them you can do that on the pole container itself like I don't know margin margin vertical 10 but that is um and that is not the most optimal way to manage spacing especially in lists because margin vertical 10 is going to add 10 pixels to the top of the first item 10 pixels to the bottom of the last one between them as well like 10 from the bottom 10 from the top so it's a bit difficult to do it this way recently in Rec native it was introduced a new property called Gap so if we send to the flat list to the content container style the gap of five then we're going to only have this gap between the items themselves so this is a much easier and better way to manage the uh gaps between different items now what I want to do is probably I'm going to go ahead and clean up a little bit this screen for example I'm going to remove the text from here I don't need the status bar because the status bar in fact shouldn't be managed from here because this is just the home screen we're going to maybe uh it would be better to manage it at more Global level so I'm going to remove it from here and I think that I'm going to remove a whole view because I only need a flat list here so let's make sure not to remove the Styles as well and maybe for this content container style I'm going to reuse that container style from here let's try to do it with styles. container and add the Gap property on this container five so just like that our list is scrollable uh the background color shouldn't be here we're going to delete it in a moment because it only has background for the for the content itself if you want to add the background style maybe it's going to be better to add it on the style of a flat list not on the content container so for example I can take it from here add it here and now even when we scroll we're not going to only the background of the flat list not the content that is scrollable has this gains borrow okay okay what should we do next I think here we are good I'm going to remove the status bar from the top um let me go ahead and explain a little bit about the layout because I would like to already start with layout so as I said before all the screens inside the up directory they will be mapped all the files in the up directory will be mapped to a screen with the exception to some special files one of these special file is a file with this specific name underscore layout. TSX the underscore layout is also a normal component so export function I'm going to call it root layout that should return something if you return null export default yeah make sure to do default so if I simply return null from this layout we are going to see that we actually don't see anything on the screen that's because the layout is the component that wraps around all the different screens in the current folder because our layout is inside the up directory without being nested in our uh folders that makes it a root layout so that's where you would want to do all the global configuration but as I said like it wraps around our screens so that's why when we go to the index to the home screen it first goes through the layout it returns something from here we return null so that basically means that we are overriding and we are not returning anything from our screen itself if we want to go back to the functionality that we had before we can return here a component called slot from exper router and this will simply go ahead and render the the screen the child component in our case the home screen so if you just need to add some Global providers you're going to use the slot without having to Define change the type of Navigator if you want a specific Navigator like a stack Navigator tabs Navigator you can import them from here like stack and by simply exporting stack from our layout we make our Navigator a stack Navigator so later when we're going to add different screens we're going to be able to navigate back and forth to them using a native stack navigator on the platform the same goes for the tabs if I added tabs like this and reload we're going to see we have a bottom tab navigator at the moment we only have a index file but as you add different files here for example example index copy by duplicating it right away we see it here so we can move from one tab to another so yeah that's how easy is to use expir outter because we only think about our files and then expor is taking care of configuring everything for us and I'm going to actually go back to a stack Navigator here for the root I'll remove the slot and yes here we have it if you want to adjust the name of your screen or any other option of the screen you can do that by going into your screen itself and rendering here a stack do screen but be careful or make sure that you're only returning one component that's a rule of GSX you cannot return two components like this so in this a we just simply need to wrap it inside an empty tag like this which is also called a fragment so now jsx is okay because we are returning one component that has inside it two nested ones but that's okay now this stack should be imported also from export router and yeah using stack. screen we can go ahead and provide options here such as the title title we can do polls right away our title has changed at the top and these options they are coming from um react navigation so anything that you can do in react navigation you can do it here as well because exper aor is built on top of rack navigation so yeah configuring the header bar things that you can see here in this documentation to configure with header bar with titles with uh I might take all of them and just show you that it's going to work out of a box you see title header style and everything else actually I kind of like it should I keep it like this anyway let's go to this one let's reload to to update the styles and let's consider the UI for the first screen done and move on we can come back at it later to improve the styles to make it look better actually at this moment I wanted to show you that we no longer have to set the background color because the stack screen has by default this kind of um uh very light gray background color so that's why we don't need to override it but the effect I was going for so let's go ahead and do a git ad G commit come on Mid minus M polls or home screen the list of polls when to use local search params and Global search parameters with Expo remind me to show you that in the next step or actually let's go ahead and uh continue and I'm going to show you that so let's go ahead and continue our build by adding the detailed screen of one of these polls when I press on it I want to go to a another page where I will see also the options I'm going to be able to vote and so on so for that I'm going to start simply by creating a new file called called maybe poll or no let's create a new folder because we I'm I decided to create a new folder because we want the different features about polls like create or the detail screen or update to be together in the same folder and also um under the same like URL like slash PS so I'm I'm going to start by uh creating a new folder called polls poll or polls I don't know and then inside here let's create a file called details. TSX from poll details I'm going to go ahead and Export default function poll details return let's simply return a a view for the page container maybe a text saying poll details let's import The View and text from rack native and just like that we have created a new screen but we also see that we put it in another folder so what does that mean putting it in different folder will simply uh change the url of the screen or how we access that screen on mobile it's a bit uh harder to Showcase that but on the web it's very easy to do that because we can navigate through the URL at the top of a browser browser so I'm going to go back to my uh terminal where my application is running so I'm going to press W to open it in web browser if I go to the home screen or to Local Host 881 slash I'm going to see the home screen with a list of polls if I want to navigate to this poll Details page I need to Simply add the different folder names with like slash very similar to how you would navigate a file system so first we're going to have slash PS and then slash details so if I go here and do slash poles slash details I'm going to get here to poll details and that's how everything works to navigate V we are going to SL po/ details inside uh our application itself if we want to in our application we don't have the top bar URL to to be able to change it so we need to implement navigation by pressing on some buttons uh in that case what I can do is let's go ahead and for this flat list uh there is a property on the flat list called or no let's not do it on the flat list itself but after the flat list let's add a button here from react native button from react native maybe not even a button let's start uh simple uh let's start by uh using the link component from exper router link from exper router and this links link helps us create uh navigate from one screen to another so if I render it after the flat list and inside the link I need to write here poll details uh we need to specify the HRA of a link with the URL where we want to navigate so the URL is again based on the folder and file file names so first we need to go into the slash polls then slash details details now we are at the very bottom of the screen maybe maybe I can I don't think I can style it right where I can margin bottom 10 the 30 this is very temporal like I'm going to update it shortly 50 just to see it so we see this link at the bottom of the screen if I press it we are redirected to the SL pole po false details and from here I can go back because in our layout we specified that this should be a tech navigation but in fact we want to navigate when we press on one of these items correct so here we saw how to use a link as a nor as a very simple textual Link in The Next Step we're going to see how we can wrap different components inside the link because what we need to actually do is we need to wrap our whole View for the pole container inside the link so every single item from here is clickable so the simple logic is going to be to take this link wrap it around here take the closing wrap it around here delete the PO details because don't want to render anything and should you expect it to work out of a box maybe we don't need the margin bottom anymore I'm going to remove it um so yeah in fact it's actually working in fact it's actually working and maybe we just have to put the style on the link and that's it and remove the view yeah actually that's a much easier approach so I'm going to leave it like this okay perfect so now all our uh items they are clickable The Next Step that I'm going to explain you is that Dynamic puff parameters so being on our detail screen how will we know on which item we are currently at for example I'm going to consider that this let's update it a little bit and um the array of polls let's do it with ID let's imagine that our every the data about a poll is going to contain an ID so it's going to be the first one ID one the second one ID two and then ID four or three now I can display this ID by uh by receiving in this render item function we're going to receive here the item so let's destructure the item from the properties and let's render before the example poll questions let's render I item. ID if we do that we should see one two three so whenever we click on one of these items we would actually want to send this ID down to the detail screen how that happens well there are a couple of ways if we go back to the web development one of them would be SE URL search parameters like at the end of a URL I'm going to bring it here so that you can see it as well so having a URL like this you might have question mark here ID equal to two or three this is a URL search parameter uh but a better way would be to go ahead and actually have the ID as part of a URL itself so instead of pulse details we can have ps/2 in this case maybe it's doesn't make a lot of sense but imagine if we are building uh a Twitter clone and we want to navigate to the user profile so the URL might be users slash Vadim not just Dev so this is a much more user friendly URL compared to having question mark ID equal to something so exper router um supports this kind of a dynamic Puff parameter and the way it works is we rename that segment being it a folder name or a file name and we put the variable name of the dynamic path parameter between angle brackets so for our details. TSX we're not going to have details we're going to actually have ID V so let's put it between square brackets and name it ID because the that's the uh that's how we this is the name ID is chosen by us so this is only to be able to access it inside the pole Details page to access it here we are using a hook called use local search perams and we're going to take ID from here and we can render it on the screen poll details and then ID so if I go now nothing is going to happen right uh actually it's happening and it says poll details then details which kind of means that the ID is details that's because if we go back to index. TSX that's the link to which we are navigating polls SL details but we need here a dynamic puff parameters instead of the details to do that I'm going to put this string inside the curly brackets to be able to use a template string with these back ticks I'm going to remove a details and I'm going to replace it with a variable called item Dot ID because we want the ID to be part of the URL so if I go press now on the first one we see p details one second one pull details two third one pull details three and yes this is the dynamic puff parameters now even on the web if we go to puls SL1 it's going to display it here if we go to po123 it's going to be this one perfect um and someone was asking what is the difference between use local search parameters and use Global um Global search parameters uh let me easier show you with an example and that's a very valid question I was actually researching it today like to better understand it so there is another cook called use Global search parameters and let's take the ID but here call it Global ID let's do console log local let's do ID when Global I uh Global ID so in our poll details I'm taking both the local Ser parameters and the global parameters and I'm console logging them both on the screen I'm going to go uh here I'm going to reload the application and let's see what do we see when we navigate throughout our application if I'm going to go to the first one we see local one local ID 1 Global ID 1 if I go back and navigate to the second one we see local one Global two but if from the detail screen we can go to the next page for example if we have here a link go next that will do HRA slash PS and then we'll go to id+ one this would never happen but you imagine like next page for example or go to to another but let's do number. pars float so if now I'm going to go to the first one and we see local one Global one if I'm going to press go next it's going to push me to a new page and we actually see two console logs one of them is seeing local one Global one and this is coming from our post the screen that is rendering the details of the post with ID to but the next one which says local one Global 2 is the one is a console log coming from our previous screen so in the previous screen the local ID is still one but globally this screen now is already rendering something else so I can still go back and see it here now it renders only one once a bit confusing but where is it come on if I go go next go next go next um yeah so local search um it's recommended to be used when you are fetching data on the screen based on a search parameters because you want the screen to always render with data that it represents while the global search might be used in very um few cases maybe for analytics where you want to uh to always know what is the actual the current ID of a page or the last one so that's a short description you can read more probably I didn't explain it I'm not very happy how I explained it so here in maybe in advanced where is it Expo router global so here you can find more information local search params returns with search parameters for the current component it only updates when the global URL conforms to the route as well not very good use Global search Returns the global URL regard regardless of a current component so it updates on every search pram change and it might cause components to update um without us needing it so that's why we saw a lot of changes when using Global search R renderers okay anyway um another thing that you can do here with both local search and Global search is to provide a type as you can see the ID is not sure is it a string is it an array of string so we can specify here that hey the ID is actually a string now VI ID is going to be a type string so when we do this number parts float it's going to work perfectly and I actually sorry I actually don't need this go next okay perfect uh so what do we have so far we saw the dynamic path parameters uh I think it's time to build a little bit the screen that will render the details about one poll and will allow us to vote there so one poll let's define first the data it's going to be an object and it's going to have a question uh re native versus flut I don't know and it's going to have options options is going to be an array of different possibilities for example react native for the wi flatter I don't know something else Swift UI I don't know so having this data let's go ahead and render it on the screen uh I'm going to go ahead and start by rendering the title here and the title is going to be poll do question later we're going to fetch this data so that's why I don't over complicate the the data itself I just want to have something to build the UI and then having the options in this case we can use a uh a flat list but I know with options is a limited array like it's not going to be a lot of items so instead of uh using a flat list I'd rather map through them and render the options like this so to map through an array and render uh something on the UI for for each item we're going to start by putting the corly brackets and accessing our array poll. options then using the JavaScript map function we're going to map through every option there let's call it option and we're going to return something to render on the screen let's start by returning a uh View and inside the view let's render a text and the text is going to be the option itself because the option is one item of this array and we see that it is a string so if I go now to this screen yes we see the question and we see three uh answers let's go ahead and style it a little bit with the Styles let's do const style SQL Styles shit. create we're going to have a style for the whole container for the page we're going to have one for the question and we're going to have one for the option right option container and maybe even option text we're going to see let's go ahead and assign first these styles to our components starting from the root view the style it's going to get is going to be styles. container this text is going to get styles. question and I'm going to copy it from here to this view I'm going to give it our last options container style before I go to the actual writing the Styles I will want want to show you also one thing I'm not sure why we don't have this warning right now but actually we do you might see that we have a warning that each child and a list should have a unique key property that warning is caused whenever we are uh looping through an array and rendering items whenever we are rendering lists of items uh in that situation we have to provide here to the component to the root component that we are run rendering we need to provide here a unique key so a unique key can be the actual option that we are selecting that's going to be a string and we hope that the answers are going to be unique so just like that the we got rid of warning and um react will properly optimize the rendering of this long list based on the key okay now let's go to The Styling the root container needs ping so let's start with a 10 the question itself needs to increase the font size to 20 a font weight maybe not Bal Bal I think is uh has a value of 700 so we can do a semi bold like 600 like this uh color as well dark gray is it going to be too light yeah deam gray or just the normal black one and for the option container what do we want there should we have it with some background color like background color white um to add some spacing around the items I think I'm going to put all of this mapping inside another view that is going to be the container containing all the options so the style of it can now have just a gap of five and it will add the spacing between the options so let's go back to the option container ping five even more 10 is going to be nice border radius five okay that's that's okay uh to adds and spacing for the question itself maybe I should go ahead and add Gap to the parent container to the page and this will add the space between the the question and this one I don't know 20 maybe um another thing that I want to do here on this page is to be able to select different options uh the way I'm going to show if it's selected or not is going to be using a an icon for that I'm going to go to Expo icons and let's find an icon that will represent and the checkbox so I'm going to let's try this one so I'm going to take it from here I'm going to first import it in my component and I'm going to render it inside my options container inside this container before the text okay maybe the color is going to be gray the size probably smaller like 18 and we want to put the text and the icon on the same line for that on the parent container option container we can adjust the flex direction to display as a row and then we can also add align items to horizontally align them on the center it's not very visible but for example if we going to change this one to a bigger icon is going to be very visible how it impacts the aligning and what I want is using a gap property add some spacing between the icon and the text like 10 okay that's good let me check if this fever uh fa I don't know how it's pronounced has also a normal Circle yes it has so what I'm going to do next is I want to keep track of which is the currently selected option from the user and then display a different icon here like a circle for the rest and we check only when it's selected so keeping track of the selected item we cannot do that in a variable because whenever we change the selected Vari option we want to reender an update what we see on the screen that's where a state comes in which we're going to declare with you state imported from react we declare the state at the top of a component uh and we call it uh selected and then set selected for the setter use State and here we Define the default variable value which is going to be mty string we can try I don't know we can try to take this option and add it as the default now we can go ahead and decide what type of Icon do we want to display for every single option uh by checking if the option we are rendering is the same as the selected one so to do that we need the dynamic name here so let's put it in inside the angle uh like the braces and here we are going to check first if option is equal equal equal free equal sign to selected then and only then I want the check to appear otherwise with semic colums here I want it to Simply Be a circle so just like that we see that only the first item shows us selected we can do the same for the color I can remove it and add the brackets I can check if option equal to selected the color can be green otherwise it can be it should be gray so now the icon that is selected also shows with green perfect now the last step is to make sure like when we press on one of these options to change the selected item for that we need to handle the Press events on the container itself and the problem is that a view does not have a on press event we cannot handle that but there is another component exported from R native called pressible that allows us that can be used in a similar way as a view is used so what I'm going to do is I'm going to Simply replace my view that is rendering one of these items with a pressable make sure the closing tag is also pressable and now I can add the on press event here on press event expects a function and when we press what should happen we should update the selected option using the value of the option that we are currently rendering like this so now if I simply click on V one we see that we are select the item that we are currently clicking and it rerenders the component to display these changes perfect uh what's left here um what's left here is probably a button that is going to help us submit our vote uh maybe later we're going to adjust the how the way it looks but for now let's simply import a button component from react native which renders a native button so if I'm going to go and after this view that is rendering the polls basically just before the last view is closing I'm going to render a button with the title uh vote on iOS it looks like this because that's how a native iOS button looks on Android is going to have a background color but anyway I think that's good for now let's just add a on press event and we are going to co send here a function that we can Define at the top here vote we can start by doing a simple console war vote and then also here should be equal uh vote and then let's also console log by select Ed item so if I take this function and send it to the on press of a button and if I press we see vote Swift UI if I change press vote vote re native here so perfect in the next when we're going to integrade the the the beckon with super base which is going to be very shortly uh here we're going to save vote in the database so I think with this we have a pretty good uh pole detail screen uh what you can also do probably that I didn't cover is adjusting the header style for that I'm going to render the top of my component a stack do screen and using options I'm going to adjust the title title the title should be I don't know po or it can also be po question the question itself can be there but I believe that it might be too large like what if it's going to be like really lar a long text what's going to happen then yeah it's going to have a DOT so I'm not sure yeah you decide you want what do you want in the title maybe poll details or poll voting I don't know okay perfect so in the when we will have a back end using this ID we're going to fetch the details about that poll instead of using damid data we're going to use something from the database and when we press vote we're going to save the vote also in the database so let me go ahead and do a g ad get commit minus M poll I'm I'm already PLL Details page perfect how is everyone doing are you following along Shaquille thank you very much beam thank you for your tutorials thank you I appreciate it let me actually pop out the chat watching your infinite render video just came here to say hello from India Ram hello hello I have a question um I have a document for a diet plan 2020 week diet but I'm trying to figure out the easiest way to display that in my flatter application oh I'm not a flatter developer sorry I'd be able to help you in R native if you want okay let me put it here so I can see your comments better and let's continue so what other screen do we still have is the screen for creating a poll yeah we need a screen that will allow us to create a poll for that we're going to Define it let's start by defining the screen itself we're going to Define it in the polls folder that's why we created it and we can call it new this way the URL will become SL pulse Slash new here I'm going to export default fun function create poll and let's render something I'm going to start with a view and with a text new poll let's make sure to import The View and the text from R native oh what happened and last step is to manage your navigation so where where are we going to navigate from well I think it's from the Le it should happen from the screen that renders a list of polls we can render a button at the top we can render a button at the bottom like create new poll or I think another option would be a simple plus sign in the header so later we can think like how it would be even like better like in terms of design but for now we just need functional so I'm going to search for a plus sign I'm going to take it probably from antt design let's import it inside our application index inside our home screen I don't need these comments anymore and I'm going to render this end design in the header to do that also through the stack do screen options coming from Rec navigation we can send there a header right component if we send here a function that will return some JX this is going to be rendered in the header right so let me reload and we see the plus sign there in the header maybe smaller like 20 color uh gray something like that is going to look good and lastly if I press on it I want to go to to the pulse Slash new what happened here create pole no no no that is not meant to be there okay so back to my index the navigation oh my God what am I doing so the navigation is going to help happen with a exper aor link so let's wrap this link around our icon and let's copy that closing tag and put it after the icon and let's provide here the URL which should be slash puls slash new if I do that and press on it I'm navigating to the new what if I do as child here will it also have it yeah it still has it okay so at least we can go to the new screen so let's go head on that screen itself and start working on it maybe we can start by changing the title using stack do screen options title create poll and and let's go ahead and maybe if start with a style sheet we're going to need that for sure sty shit. create we're going to have a container for our whole page and we're going to see what else we're going to needes do container so let's start with a poding 10 nice okay so here we're going to need um I was looking I was uh taking some inspiration from I think it's called straw pole and I was looking at where create pole uh field for it has a title and it has these answer options that we can add more we can delete so let's try to do these two Fields so the first one is going to be what our title let's give this a style called styles. Lael after the title we're going to have an input an input in Rec native is render using a text input component let's go ahead and render under the textt input just be below our label and let's give it a placeholder type your question here just like that we see something there we see a placeholder we can add some text already uh then we're going to have another label below that will say options and there we're going to have multiple text inputs with option one option two and so one let's go ahead and give V text inputs a style as well styles. input which we will Define shortly I'm going to copy this styles. input and give it to the options text input as well and now let's go ahead ahead and uh Define some Styles I'm going to start with uh we have a label label and we have a input oh come on input for the input I'm going to start with a background color white that's good I'm going to start with some podding 10 to add some spacing around it maybe border radius 10 or five make the borders round on the whole container let's add a gap here of five that's good for the label let's maybe increase F font weight over label to 500 that's good and add some margin top to add a bit more spacing on the top compared to to what comes before okay already looking a little bit better um Forest State okay the next step now that we have them displayed we can type the next step is to go ahead and store the value of what the user is writing in this text input to store it in a state variable because later we're going to have actually let's do it right now we're going to have a button rendered at the bottom saying create poll so let's do title create poll and of course a function that will do the actual logic of create Poll for now it's empty later is going to save data in the database so let's actually go ahead and assign the onpress event of our button with create pole if I go to the new page yes we have create poll but the problem right now here is that we don't have access to the data that the user wrote console war create in order to have access to the data that the user is writing we need a state variable so we need a state variable for the text first text input for the question that's going to be a state variable called question we're going to have a setter set question use State empty string this is the initial value now to bind our state variable state to our text input we have to send here two properties one is going to be the value of the text input should always match our state value so now if we're going to try to type something it's going to disappear because it always comes back to this one and by adding the second property on change text which is a call back function that the text input will call whenever the user types something and if we simply send here that our setter set question that means that the text input will call set question with the value of the updated input and then is going to update the state the question is going to be updated and it's going to be sent down as a value so now we can write here here and it works nice perfect so the first uh state was quite easy what about the next one the next one if we have a limited number of options it would be easy as well like we have a state for option one state for option two and so on but we in fact want a dynamic um number of options so let's store all of them in one state variable as an array of strings so options set options equal to use State and the default value is going to be an array where we will keep different the value of different options so initially Let's do let's say that we have two options and both of them are empty strings with why we have array and two options with empty strings now the trick is going to be to instead of manually rendering not manually but uh instead of yeah like rendering the text inputs like this what we actually want to do is we want to render for through our options state which is an array of values and for every option options dot option no options do map for every option we want to render one of these text inputs so I'm going to copy it from here paste it here and we I will actually delete the other one like this so just like that we have two options here because we have two values in our array if I'm going to add the third one it's going to be added there for the values like 1 2 3 4 5 6 7 8 n for the values it's quite easy so the only thing that we need to do here in the text input is to say that hey the value of this text input should be the value of the option which is one array item so just like that this one goes to the first one second one third one updating it is going to be a little a little bit more uh challenging but we're going to do it um so updating it updating it we're going to work with onchange text so let's send the onchange text here which in this case we cannot do set options because onchange text is a function that will give us one string for the text input our set options expect an array of all the options so instead of that let's actually Define it as a function where we're going to receive a text of a current text input what do we have to do with this text is we need to take this text and replace it in in this array based on the index so if we are updating the last option update this one with a new text we cannot do options at index index and the index can be easily taken from the map function as the second parameter so we need to take the index but we cannot do options. index if equal to text because state is immutable we cannot update it directly we should always update it using the setter so in that case what we actually have to do is we have to first create a copy of our state of our array and let's call it updated the copy can be created easily by declaring an array and spreading the options in that array options this syntax is basically hey create a new array and put all the items from our options in that array now updated is a not a state variable it's a it's a an array with all the values from the state now we can go ahead and use updated at index of our option update with the text that the user is writing and lastly we need to call the set options with the value of our updated array now we are taking it from locally defined and sending it to update the state using the setter now if I'm going to go ahead and write here it updates the last one if I write here it Updates this one and all of them are properly updated and yeah that's because we using the index and updating the array item at that index in our state which is of type array I'm going to go back to having two of them and without any value I'm going to use this index instead of uh in the placeholder instead of saying option two I want to say option one option two option three and so on for that I'll put it in the brackets because I want to use a template string with back Tis so that I can use here a JavaScript variable index but not just index but index plus one because index will start from zero but humans usually count from one so I'm going to do option one option two and so on but how do we add one more option here well it's super easy like logically to add a new option we need to add a new string in this options array let's simply create a button here with a title add option and on press is going to be a function we'll simply update the options we and set it to an array where it will take all the existing options and at the end add one more value of an empty string so now if I click add option it adds it there like this and I can update it I can update it here I can add more so it adds at the end so we update the options array by using all the existing options plus one empty value and this empty value is going to be mapped here and rendered as a text input put just as simple as that oh and lastly uh viability of deleting uh options viability of deleting options we're going to do that using an icon uh called I don't know X something like that do we have anything imported already here no no we don't so let's just import this kind of x from Expo Vector icons and let's render the X the X somewhere together with this text input for that we can put them into a common view so I'm going to put the text input inside the view and and after the text input I'm going to render the X I'm going to give it some style because I want to render it uh with position absolute so that it's not render near the text input but on top of it and I want to render it on the right side of our container right 10 pixels from the right to put it in the center I think I can go ahead and give here to The View a style that will say Flex or Justify content Center and I believe it should put it in the center yes and finally I'm going to reduce a bit the size maybe even 18 I'm going to do a gray here and that's it lastly we have a onpress event that should say that should uh yeah delete option based on index when we click on one of these icons we have access to the index of the option that we clicked so knowing that index we need to delete it from the array the way it's going to happen is very similar to how we updated the text so let's take this code from updating the text input here because we still need to create a clone updated the only thing is that we I think we can go ahead and use delete and then delete and then update that index and then set options so if I click on this one yes it works if I do this oh it's a bit weird yeah so maybe instead of that I'm going to use updated. splice method the start where I want to delete is going to be index and the amount of items I want to delete is one so this splice is going to actually update the array and now it works perfectly I delete this one it deletes delete delete delete delete so yeah if I have here like this we see that we can delete specific items based on their ID okay so that was our options we can add add more and lastly we can create it whenever we press create at that point we already have access to the question that the user typed here and all the options that he selected perfect let's go ahead I think we are done with the user interface for this screen for creating a poll so let's do get ad get commit create poll page perfect how's it going so far guys are you following along hello adita how are you doing and someone is saying uh mosan is seeing not coding anymore due to school activities but just couldn't uh resist joining hey you're welcome here take a nice break and have some fun the items have also an onpress event instead of wrapping it inside the link that's true but we actually want to wrap it in a link for example and there are two options like you you're right like it's possible directly there so this is one option for example in the header right here and another option would be Let's do let's copy paste it and instead of doing a link we could use the on press event here and then we could use router dot push and then the URL P Slash new so this is another way using router. push and still going to work so it really depends how you want to render it using a component like declaratively like this or calling a function imperatively like this up to you both of them are basically the same I think this way might be a bit more developer friendly but yeah in this case like it's not a lot of the difference is not huge uh by the end of stream please mention the expected side of application so beginners have an idea uh yeah I'm going to try I'm not sure sure like for that I'm going to have to build it for production but why why is the upside so important it's definitely not going to be more than 30 megabytes I imagine it's going to be around like 10 15 megabytes something like that maximum 30 hello musin so guys I think that we are uh more or less ready from the UI perspective to go ahead and make this functional by integrating with the back end and building our back end and then maybe at then we if we still have time we can update a bit the the UI but let me get some uh no no actually we're going to have time for that let's go ahead and start our super Bas integration so as I said this tutorial is sponsored by superbase and thank you very much uh superbase for doing that uh I've been using superbase in one of my in in one production project of mine as well but a couple of pet projects so I really enjoy how easy it is to to build with super base um it's built on top of pogress SQL it's a we're marketing it as a Firebase alternative nowadays I think it it's even bigger than Firebase um so yeah to get started let's go ahead to superb.com Let's create an account you can do that by connecting with your uh GitHub account and then on your dashboard let's go ahead and start by creating a new project let's click new project let's give it a name [Music] puls uh let's give it a database password I can choose a random from here but after you write the database password make sure to copy it and put it in some kind of noes you might need it later at any point you'll be able to reset it so no worries now let's go ahead and do create new project Let's uh meanwhile let's open the the super base docs the documentation and let's go through the getting started guide these getting started guides have a lot of uh examples of integration with different Frameworks um like R nextjs flut and if we go to the mobile tutorials we're going to see a tutorial for Expo let's select it I'm not going to follow this tutorial like step by step I'm only going to cover some of the things so the first thing that I want to take from here is yeah we have to create uh to create a project later we're going to I have to set a database schema and yeah probably we're going to take it step by step not to confuse so let's wait until our application is set up our database is set up on super base project status it should take very yeah I think it's ready yeah actually it's ready ready so here is our project page page what I'm going to do I'm going to go ahead in the table editor and here in the table editor let's go ahead and start creating tables for our data first of all we are going to have data about polls right so let's create a new table for the name of a table uh let's do polls and for let's scroll to the columns let's add a couple of columns one of them is going to be the question which the type of it is going to be a text and we can even uh open this dialogue settings to make sure that this uh to deselect is nullable field because we want this question to be required let's add another column here options and the options are also going to be a text but not a simple text we need an array of texts so let's open also them gear here let's Des select is nullable because we want the options to be required and let's select Define as array this way our options is an actual array and I'd like a lot of data here but let's continue with this basic configuration and let's save this table it's going to create the table and then we're going to see it here in a very userfriendly interface we can go ahead and press on the insert insert row to already create a question how are you for the options here let's add the array with different strings with double codes good super good and awesome and let's click save this is going to add a new item it automatically created the ID for that poll it created the Tim stamp maybe you can add it even more one more uh what What's the we like I know options rain sunny save so now we have two items in our database with this approach we already can go ahead and fetch this data in our application before we do that let's go ahead and install the dependencies in our application so I'm going to go to the super base documentation for export R native I'm going to scroll down until I see the install additional dependencies and I'm going to take I think we need all of them maybe with the exception of re native elements because it's just used for some buttons that we can override so let me copy everything into a noes and just remove the react native ele element dependency let's go back to our application to the terminal and let's paste the install command so the libraries that I'm installing are super base GS first one Rec native as sync storage and react native URL polyfill let's press enter and 13 packages have been added perfect Next Step let's go to the documentation here and we need to define a helper that will create a super based client let's copy this code of helper using a sync storage let's go in our source and create a new folder called lib for the library and a new file called superbase [Music] dots let's paste the example from here and what we need to provide to the create client is two variables the superbase URL and the superbase a non key what I'm going to do next is I'm going to use the Expo environment variables to easier manage this Keys uh to this superbase URL and a non key which is anonymous key these are two public keys they are safe to be used uh even inside your uh code like this so it's not going to be a problem uh because they are public keys I need to make them accessible at using inside Expo client side code so the variable name the environment variable name should be prefix with Expo public underscore then let's simplify a bit this name by removing your dra native and have simply Expo corpore superbase URL and I'm going to put it inside after process. EnV dot this one I'm going to copy the whole thing like this and I'm going to do the same for the second variable process. env. Expo public superbase and non key now all we have to do is go ahead and create a file in our root folder called EnV take the first name I'm copy pasting it not to have any typos take the second name put it in the EnV and now let's go ahead and find these values and provide them um to Expo environment I'm going to go to superbase dashboard and I'm going to go to the project settings under the configuration there is the API folder and the first one is the project URL let's copy it from here add it for the first super base URL now the second one project API keys this is the anonymous or public key let's copy it and let's add it to the second environment variable okay so yeah remember environment variables from EnV that are prefix with Expo public they will be replaced and used in your native side client code so these Expo public environment variables are only for public keys don't use them for Secrets because they will still be used in your application so it's not a secure way of managing Secrets but in our case we need them as public keys and that's fine so what I'm going to do is I think I'm going to have to restart the server for the EnV file to take effect probably not with clear just like that we see that it loaded EnV it automatically export like set this environment variables perfectly fine and now we're going to be able to use them in our super base file where we C create the client okay good and actually you know what we don't even need this PO fill because nowadays it's already part of uh of Expos DEC so think you are safe to comment it out and not even install it in your application okay so now we have a super based client the next step is to use this super based client to fetch the list of polls in our application what's going to happen in our application poll P not application polls application Index this is our home screen and instead of taking them from this array we would want to fetch them we're going to prepare the ground for it by defining a state where we're going to store our polls set PS equal use state is going to be an array we are no longer going to use this Dam data initially we don't see anything because our state variable is an empty array but when the home screen component mounts we want to start fetching the data from super base we're going to do that using a use effect to start fetching use a fact like this with a empty array dependency list at the end to make sure that we fetch it only when we Mount the component we're going to Define here a function fetch pulse which is going to do yeah console log fetching and after defining this function because it's going to be an async function we go ahead and call it right away in the use effect so now if we look and if we reload this application we see that we are calling this fetching so the next question is now that we have this structure how do we actually fetch the data from the super base well it's super easy all we have to do is go back to our uh dashboard let's go to the table editor here under the schema public make sure you're there go to your uh table you're going to find a button called API docs which automatically creates documentation for your table and how to get data from here you can navigate to the read rows and here you can have you see some examples how to read all rows how to read the specific columns if you only want a couple of uh columns how to read reference data pagination and so on let's go to the first example read all rows let's copy this code by pressing copy and inside our fetch poles let's paste this code we need to make sure to import super base from our folder lib super base where we created this client and then using from we specify a table and then we select select all the columns now we should have a pulse which I might even delete and only work with data and error and I can check if error Let's do an alert maybe not the best way to handle the errors but for now it's going to be good error fetching data this alert is a component that can be imported from rect native and if there is some data let's go ahead and set it as the pulse or maybe console log let's start by console log data and also do set pulse data so if I reload the application I expect to see the P from our database but they are not there if I look in the console log we see that the data that we received from this fetch is an mty array why well that's the security uh the default security of our tables all our data uh is managed by by roow level security these are um policies that we Define to specify what users have access to a specific role in a database this way we can say that all the data is public in the database or all the data is public but only the user that created that item can update it or only the user that created the item can delete it so this way you can really have like some uh flexible policies to make sure that you have Security on your database layer without having to add the security on the API or on the UI itself which is which wouldn't be very secure at the end of the day so by default our tables would deny all the operations unless we specifically say who is allowed to do what to do that let's go back to the table editor we can open the polls and either here through ad RLS which is RO level security policy or through the three dots let's do view policy here we see that okay view policy here we see that the polls table doesn't have any policies yet let's press on create policy under this table and here is where we create a policy you can give it a name you can specify the operations that you want to to allow or deny and you can either allow deny to a specific role for example Anonymous or authenticated or admin or super user or anything like that it's this you decide here the roles and you can even adjust it with additional checks like if it's only after 30 minutes of a tweet being created you allow updating so you can do that on the database layer with some additional checks uh for the first one I will use from the right column I will use the template enable read access for all users because I want all users to be able to read the polls so I will select this one from here and I'm going to click save policy it displays under PSE policies and if I go back to my application and reload it now we should have access to it and the data is uh correctly fetched and rendered in our application so that's how easy it is to create that database uh query the database manage the permissions with super base uh before we move uh forward I want to mention an optional step only if you're using typescript I think you'd want uh to to follow this very quick steps to make sure that your super based client is properly typed because now if I hover over this data we see that it's an array of any which means that super base does not understand like what is going to be the type of this PSE however superbase supports out of a box typescript and and it also generates types for us all we have to do is go ahead on the dashboard scroll down to the API docs and under tables and Views go ahead in the introduction here you should see generate types under generate types there is a button generate and download types this is the easiest way there is another way of using the CLI which I might show a bit later but the easiest way is to go here download the types for your database here we have it downloaded I'm going to grab them from my download folder bring them in my vs code come on yes I want it here or I'll put it on my desktop and I will move move it let's do in the source let's create a new folder called types and let's move the file in the types it should be called sup it usually is called super base I already downloaded a couple of them so I'm going to delete the two and this file contains the types for all the tables with in our case it's pole with the information about the data in one row information for they insert operation update information and so on so what we have to do with this is simply import it in our superbase client so let's import database from types superbase from this file that we imported and give this database to the create client as a generic type here database just like that now superbase is typed it knows what tables he's working with and if we go back to our application index and hover over the data we see that the data now is properly type and it took us probably like 1 minute to do that the only thing like with this approach is after doing changes to your table you're going to have to always come back and generate and download types from here and in a better approach would be to use V super base uh local CLI that can help you automatically generate these types for that you can go ahead and the using the CLI get started install it on your machine let me actually show you that uh I'm going to go to the docs guides SL CLI getting started I'm going to copy this command because I am on my OS you can choose Windows Linux or even npm I think I can use npm with npx that would be even better so npx super base because in that case I don't have to install anything so the next step is going to be to generate types where is it types generation it's in another documentation a bit super based gen types super Bas gen and should be super based gen types so does that mean SL slash link let's try this command not exactly sure but we're going to see clear uh npx super base that's how we're going to access the that one gen types then typescript to specify then d-h linked linked is going to use the linked uh superbase client because you can also run superbase locally super base is actually open source you can run it locally uh cannot read file open superbase config no such F directory oh I think I needed to do super basing it first so npx super base in it uh for Dano Cod set for no no so what's happening here in the super base I need to link it first let me check this documentation this is optional actually so that's why I didn't want you to to do that yeah I need to do super based link project ref and the project ID so npx super base link Das Dash project ref and here the idea of my project that I can find through the dashboard project settings and this is the reference ID enter your database password that's where you're going to need the database password if you saved it if not you can go ahead and uh for the database you can reset the password here through the dashboard so no problem so we have a super base here now I think we can run there npx gen types typescript linked this simply outputs the types and we can write them to a file by adding um the more than sign and then provide the URL where you want to write the types so in our case it's Source types super Bas TS so if I delete from Source type superbase TS and then run this command we see that it automatically generates it for us and to not have to always remember this command what I can do is I can copy it I can go in package.json and I can add a a script inside the scripts called gen types or super types or gen types and then the command is going to execute npx super base gen types blah blah blah so now I can simply go ahead and write every time I change something I can do npm gen or npm run gen types this is ex in this command and updating my types automatically anyway that was as I said optional because you can still go through your um as the easiest way to go for your API documentation introduction and download the file from here and replace it with your types okay perfect uh but anyway we also saw how to link and set up and configure the local superbase CLI let's go ahead and do a g status what's going on there maybe let's do get I don't think the environment variable should be uh committed so I might go ahead and add it to git ignore get status get commit my G add get commit uh set up super base uh Michael is saying it's dope thank you very much when is the watermelon sink part watermelon sink think we're doing it this Friday so we are continuing the this Friday we're continuing the project we started previous week with watermelon DB and actually this Friday we're going to use also super base to synchronize a local SQL database with a remote uh database created using superbase a postgress database bonjour hello there from France hello RLS is for security po is very powerful yeah I really enjoy it it's very powerful no is saying who I'm going to use super base for my next project thank you for sharing appreciate it thank you personal account hey friend what's up I'm good building a voting application hello uh beta is KMP Worth to learn what's KMP okay guys so so far we saw how we can fetch data using superbase let's also see how we can create polls using superbase before I do that I have like this warning with unique key which most probably is coming from these options so I'm going to open application polls New because that's where we render the screen and where we are mapping through the options remember to always add the key here which can be I would not use options here because the option can be duplicated as it also can be empty string I think I'm going to Simply use the index as the key so now it should work okay so what we want to do here is we want to create a poll but the fact is that we don't want anyone to be able to create a poll let me quickly grab another coffee and we're going to continue because before we create a poll I think we have to handle the authentication to allow users to create an account because I don't don't want anyone to be able to create a poll I want only the authenticated users to be able to do that so yeah quickly grabbing a coffee we're continuing with authentication in Van creating updating and more so stay tuned for e e e e [Music] all right so got my coffee and we are ready to continue our build hello from Tunisia hello soile so where are we at we said that we need to create a poll but we want to only allow authenticated users to do that well first of all let's go ahead and yeah first of all let's go ahead and Define uh the screen where we will allow users to log in in our application we can either Define here a folder with called authentication like off um if we want to have multiple screens like login uh for good password sign up and so on I think that's a good approach so let's call it off uh but in my case I'm only going to have one screen for that screen I'm going to allow both sign up and sign in to keep it simple so let's simply do here off slash login dot. TSX from here let's export default login screen return a view I forgot the keyword function I will return a view with a text sign in let's import the view from react native let's import the text also from react native and uh we can go ahead on the web and navigate to slash off SL login yes we see a sign in here but I'm going to show you a quick trick like if you want to get rid of the SL off and only have directly SL login uh because it might be a better URL like your website it slash login but you still want to group all the authentication screens under the same folder what you can do you can specify that one the folder name or a file name yeah probably only the folder uh you can specify that the folder name is an optional puff parameter by putting it inside round brackets like this so if we do that go back to the web and go to the SL login it works uh and it will also work if we navigate to the slash off SL login will not work but if we put the off in the parentheses it will also work and actually redirect us back to the login so that's usually when you want to group things into the same folder into the same maybe layout but you don't want that part to be visible in the uh URL you put it in the brackets okay now where do we navigate there from maybe we're going to navigate from the index from the home screen uh using not header right but header left let's go with a header left also an icon that will help us get here I'm going to use the same link uh to the slash uh login slash login and here I don't know end design user yeah that that would work so now on the left we have this user so if I press I'm redirected to the authentication login now let's go ahead and develop this login screen um in fact I'm going to go into the back to the superbase documentation to the getting started to the Expo example and I'm going to scroll down because we have here a login off screen so let's copy this component from here let's go back to our application let's replace everything that we have with their comp component there will be a couple of changes that we have to do first of all the relative puff to our super based client I think it should be one level up so add that one more double dots and then we decided not to use react native elements which is a external UI library because it's only going to be used here so I'm going to import the button from RE native and that text input also from react native I'm going to remove this import from react native elements because we decided not to install it and we're going to have to update a little bit our our component I'm going to scroll down I'm going to explain everything that's happening here but now let's make sure that everything is working for example for the inputs we need to make them from input to a text input from R native it doesn't have a label so let's remove a label it doesn't have a left icon let's remove a left icon and everything else is going to work the same thing for the password instead of input it's going to be a text input it doesn't have a label it doesn't have a left icon and everything else is working like this and everything else should be working fine if I go to the sign in here is a very very basic signin page we can maybe bring here from our polls new page the styles of our input to make them look a little bit better so I'm going to copy the styles of input bring them to our login screen add them in the Styles and assign them in the two text inputs that we have styles. input and the same for the second one styles. input maybe we can add an title somewhere here like text because it looks like very um let's import text from RE native as well and render a Title Here sign in with sign in or create an account so if I go here can even style it a bit with have a font weight of 500 okay so doesn't matter we're not focused on how beautiful it looks we're focused on making it functional what do we have here we have an important text input that will manage the user email the first one and we have a text input that is managing the user password the second one it also has this secure text entry to make sure that the password is hidden it has two buttons sign in and sign up they are both calling different functions sign in with email or sign up with email let's check what's happening in the sign up first so in the sign up we are calling the superbase do off. signup and simply sending there with email and password I think this code can even be simplified because email email password password the key and the value is the same so it can be as simple as that and maybe even will fit in one line and as a response we are either having an error and in that case we're going to alert it to the user for example if a account is if the email is already used or registered and uh we are getting the session if there was an error creating this user session we are that means that we also have to um to check the inbox for a verification email we're not going to cover verification emails now but uh later you can add the when you go to production it's very recommended to have a way to verify the emails and superbase does it very easily automatically for you but you just have to handle it here so the same thing with a sign in we have off signning with password we are sending here email can be simplified as well we're sending in password if there was an error we are showing it alert otherwise we don't show anything and we just set the loading to false and that's it that's the whole screen super simple one I think is that at the top there is this Upstate event listener which will start Auto refreshing the authentication token when our application is active and will stop that when it's not active by doing that we're going to be able to listen to the onoff state change callbacks and with that decide like if a user has signed in has lost connection or the session has been terminated we're going to check that a bit later but for now let's go ahead uh to our dashboard because we need to do some changes and the changes that we have to do is under the authentication under web providers by the way look at how many of providers they have like you can integrate with all of them for example uh for now we only have a email enabled but you can have with phone number with OTP with apple uh Facebook with GitHub Google and the rest but what I want to do is I want to go to the email and I want to disable confirm email to allow users to be able to sign in without having to confirm email first this is for development maybe in production you'd want to confirm emails but for now let's update that and let's go back in our application here let's try to create an account I'm going to add my information here a very simple password if I press sign in it's going to say invalid login credentials because there there is no user yet with that credentials let's go ahead and press sign up this is going to create the user at the moment is not doing anything because the way we're going to handle that is a bit different but if I press again sign up it's going to say uh it's going to say that we already are signed in user already registered as you can see I think here if is not session should be inside an else if because there was an error and I don't and I saw to yeah user already registered so add the else here for not seeing two alerts when this happens but I can press sign in and it now doesn't show me an error because it manages to sign in properly okay now that we have uh the creating an account let's see in our database the data about this user if we go to the table editor you'll see that at this moment there is is no table with our users the cool thing is that the users is not any kind of other service where it's not um anything complicated the users are also stored in the same POG database we can create connections to them we can do a lot of stuff the only thing is different the only thing is that they're not in the public schema the public schema is for the developer find tables but if we open this and go to the off schema this is a protected schema specifically for authentication if you scroll down you're going to see the table users if you open you see the same table with information about the user authenticated this is the email this is the password encrypted password of course uh last signed in and a lot of other information and also is anonymous which we're going to cover later but this user is not Anonymous so the the user has been saved in the database after signing up um the next step is to go ahead and manage a bit uh this user information and what I want to do is if a user is signed up I want to I want him not to be able to go to this screen I want him to be to go to the profile screen so for that yeah for that firstly yeah let's do that let's first create a profile screen where we're going to display some basic information about the user and most importantly a log out or a sign out button that is going to be a page under under yeah here let's say profile. TSX in the profile we're going to do a export default function profile screen and let's return here A View with text saying user ID is equal to something let's import View and text from rack native and and when are we going to get here to this profile for now in the in the index.ts I'm simply going to change here from redirecting to login to redirecting to profile later we're going to decide it dynamically so if I press on this item now it's not going to navigate to authentication it's going to go to user ID so in this profile how can we get access to information about the user we can do that uh using using using what let me check also in this documentation I'm going to find this use effect this use effect that gets the session and the session has the user so let me actually copy this us effect with the state and add it to the profile screen I need to make sure to import use State I need to make sure to import uh session session should be imported from super base they use effect as well from react and the super based client from our lib super base and what's Happening Here is when this component which is our profile screen mounts we are uh using super base. off get session and then after we get this session data we are setting it in state now inside this session there will be the session. user. ID we can in fact actually con so log this session to know more information about the user so if I go now to the to this page yeah cannot read user of session because the initially session is null so I can I should add here the question marks like this if I go there now it displays the user ID and in fact it's going to be the user ID that you can see in your off schema in your user database it's this one 9B ends with 9B 9B and console log session in the log we should see the access token we should see when it expires the up metadata if it's confirmed or not if it's Anonymous is Anonymous phone metadata and a lot of details so perfect um the only thing is that I will need this user and session information in multiple places in our application so what I don't want to do is I don't want to always come back to a screen and copy this state with this use effect with a get session uh I didn't talk about the onoff state change but this is basically a callback like we subscribing to authentication updates for example if a user signs out or if his um refresh token expires this we are going to receive it and the updated session and we're going to update it here so I don't want to always have to come back and copy all of this code just to get the user I want to have a reusable way to get this information and I think for this scenario the best approach is going to be to create create a react context and expose the user or session information to the whole application so we can simply consume it and decide like what we want to do I display user information of the screen or decide if user has access to some features or not for that I'm going to declare a new folder in the source called providers and let's start let's define the off provider. TSX this off provider is going to help us Define a react context for our authentication data so let's start by defining the off context using Create context function from react we're going to initialize it with an empty uh object right now and let's let's go ahead and Define this provider so we're going to actually export it by default function of Provider uh this provider is going to render the off context that we created here the off context. provider that's how we make we provide values or we yeah uh let's close it oh should be closed here and it will close automatically so by doing this of context provider and by sending here some data which I'm going to do in a moment everything that we render here inside this of context provider will have access to this off context in a way it serves like a global state so what's going to be render here well I want this component to be very reusable so I can wrap it around anything that I need access to it so for that reason I'm going to get the children property from here I can type it using props with children and then simply render the children as a as the children of our off context provider like this and I'm going to put them in the different rows so it's easier to see oh no please keep it like this oh it doesn't want it to keep it like this but anyway so now everything that we're going to render inside our off provider will have access to this context so where are we going to use this off provider we need we need the whole application to have access to information about user so I'm going to go in the application in the root layout in the first layout you see and I will wrap the whole stack inside that provider first let's import of Provider from our providers and wrap our stack inside of Provider now stack is the children property of of provider provider and of Provider received the children and it renders it inside our context provider meaning that all the screens in our stack and also the nested screens everything will have access to our context provider now that's where we're going to do all the fetching about the user the session and so on so I'm going to check the profile screen and this use effect with them state I'm going to copy them from here and actually cut them from here and move them in our off provider component we need to make sure to import the state the use effect super based client and also the session here come on import session super based GS and now I will export through this context provider for the value I'm going to export some values for example I'll export the whole session I might also export just the user to make it easier for us to consume it user is going to be session do user but be careful with the session can be null so I'm going to add a question mark here and say it's either session. user why doesn't understand that it can be null because this specified it here it can be null and it still thinks that it's a it's a session that's a bit weird but anyway so yeah this is a session this is the user now the last step is to go ahead and consume this uh this this context that we Define here uh I will also go ahead and type it properly to have typescript types for it of context I can do it like off context and have a same name because one is a type one is a const that's access acceptable is going to be equal the type as we see here should be an object of two Fields session and user so let's define session of something and then user of a type the session we saw that it can be I session were null and the user I'm going to import a user type from super base the user is going to be either user or null so now I need to properly type this create context using that time that we just provided that we just created and we need to specify here default values session null and user null this is the default values lastly uh what I like to do whenever creating uh context providers like this is exporting a helper hook a hook that helps us easier use this context because without the help helper hook what the way we need to consume this is using the use context hook imported from react use context where is it use context import it from react and then providing the actual context there like this but if we have to always do this it becomes complicated not complicated like we need to import two things so it's two lines of more code like every time we use it but if we create here and Export a constant called let's call it use off and this is a function that will do this for us then by simply importing and calling use off we get access to this off context so it's a little bit easier way to get access to this context and we can test it out inside our profile inside our profile we can take the session using use off and just like that this use off is imported from the providers and the session should be here and display the user information we can also import just the user and have it even simpler whenever we don't need information about the session but about the actual user if I go now here it works perfectly now what should I do with this so this is our off provider it gives us information about session and set session in the profile screen I want to allow the user to be able to sign out so let's add a button with a title sign out when I press on this button I need to sign the user out super simple to do using superbase do off do sign out so if I'm going to go ahead and press on this sign out we see that right away the user ID has disappeared from here and if I go back and try to go here on the profile there is no user ID so here comes the next step Here Comes guarding guarding means some users um we need to protect some screens some screens in our application should only be accessible to users who are logged in for example the profile screen I don't want a user who is not signed in to be able to come here because there is nothing to see on the profile screen the way we use guarding is usually we have somewhere in a provider the information whether the user is signed into or not in our case it's this user now with X for router we can simply check if the user is null that means he's not authenticated uh I'm going to cover an edge case here but a bit later so if a user is null simply return a redirect component imported from Expo router and redirect the user to the slash login so now if I'm going to try to go to the profile screen it will automatically redirect me to the login and because that's what it gets into it's in the right direct here so I can go ahead and sign in with my account but not Dev sign in nothing is happening but if the next time I'm going to go to profile it correctly goes me to the profile if I press sign out automatically navigated to the to the login so this is guarding uh protected screen screens that we want only authenticated users to to to to see you can do Vis guarding on a layout level as well for example you might have a folder called protected and put all the other screens that you want to protect for example the profile you can put it here and by create creating a layout in this protected file TSX export default protected layout uh function protected layout Let's uh return I'm going to Simply return a slot because here I don't want to change or add any anything I want to Simply return the screen for example the profile screen so now in the protected I I can move the logic of protecting not from from a screen to a whole layout meaning that all the children of this folder protected uh I want to protect them so I can do that here like this I'm going to take the user if you there is no user user should not be here in the protected otherwise render what you wanted to render and now from profile I can even remove it from here this check all together because it's not at a screen level it's at a whole layout level so if I go now here it redirects me to the sign in and if I go now it throws protect Ed at the top uh and it allows me to to be here if I sign out go back so yeah sometimes you want to only protect some specific screens in that case add this redirect logic to your screen itself but in a lot of cases you might want to protect a whole bunch of screens at the same time so now if you have like other screens here like I don't know profiles search. TSX and maybe even a nested one like uh tubs then both the search profile tabs anything that starts with protected is going to go through the protected layout and it's going to guard the whole group of screens so that's how you do the guarding at the layout level and when you do this guard you should do it on the authentication screens as well because I'm pretty sure you don't want authenticated users to be on the sign up or signin screen so I can either again go into this login screen and do that here or I can do it on the whole of uh layout. TSX export default function of layout I'm going to start by by returning the slot to Simply render what it wants to render the screen slot imported from exper router uh what's Happening Here protected profile layout slot profile sorry um and I will do the same logic as we did in the protected layout I'm going to do it in the off layout but this time I'm going to say if there is a user you can either check it like this probably it's it's okay like this then redirect to the slash profile so by going here whereever going to we let's see right now if I go here and redirected to the offscreen now if I sign in sign in I'm redirected to my profile if I click here it's profile if I sign out I go back to offscreen so everything works very Sim seamlessly with a couple of uh if statements so the whole icon that we render on the home screen in the title is actually redirecting us to the SL profile because we assume that hey maybe the user is signed in but we are safe that we can redirect V knowing that the profile is a guarded screen and if the user is not signed in it's going to redirect him to the login in protected layout is going to check hey the user is not signed in go to the login that's how we end it up here then being here in the authentication login the layout file after we log in after we log in what's happening is uh after we log in we are calling super base of sign in with password we're signing in with password but our provider has this call back has this listener on off State change whenever that happens it updates our value in state of our session and this updating state will go ahead and render our components and it will reach back the layout where we consume the user from state from our session and it's going to affect this redirect to be return instead of a slot so if I press sign in it goes through the provider back to the layout uh to the redirect to the redirect protected here and it renders the profile oh what did I do there off layout okay perfect so with that we have a full authentication system in place git OD git commit authentication not only did we cover the super base authentication which in fact was not that complicated uh because we simply call the sign in with password and we provide the email and password or sign up with email and password we didn't have to set up anything additionally it was already there so we saw that user being creating here uh we spend a little bit more time on explaining how we can protect different screens and how we can manage this navigation between one screen to another okay so now that our user is sign in we can go ahead and create polls because we want only signed in user to be able to create polls uh how is it going guys so far if you enjoy it make sure to subscribe to my channel if you haven't already because we saw from analytics that 99% of you guys watching this video are not subscribed yet so if you don't believe me let's go together in analytics I'm interested if it was changed come on YouTube yeah look it's even worse than I expected watch time from subscribers not subscribe 99.3 so there is 99.3% chance but you're watching it and you're not subscribed to the channel it takes you couple of seconds but it means a lot to us so thank you very much for for the help what's going to be our next step yeah next step I think is going to be creating the pulse because actually I want to also protect this uh screen of creating a poll to allow only authenticated users to come here because if we are signed out and we try to go here I don't want that so in the PS new uh will'll do the same logic as in this if user is not there return that so in the polls new at the top I am going to do this and I also like to have all the return return statements here together so I have States other Imports then functions and then roring statements because this will avoid situations where you are conditionally rendering some uh use effects or hooks which react doesn't like so now if I'm going to go here it's going to redirect me to the authentication on the authentication I might go into the login screen and add here a stack do screen because I want to update the title title login so if I press here it's still off because we are okay I know why because here the login is part of this slot and we can I do it through this layout by saying that hey most probably like I'm going to go back and have a stack do screen here with option login and even if we don't see it most probably in a lot of cases if you have the login the sign up the forget password all of them here you're not going to have a slot here but you're going to have a stack meaning that you will allow us to go back and forth from sign in to sign up page now we have two uh headers so actually I'm not going to I'm not going to uh not going to do that right now I'm going to Simply go on [Music] the root layout where we have a stack there is another option to adjust the stack screen um options for that I'm going to go on the root layout where we have a stack I'm going to expand it from a self closing tag to a opening and closing tag and inside it I'm going to use the stack. screen but when adjusting it through here we need to provide the name and the name in our case is going to be off now for the options title login okay now it's better login P perfect why are using gxpo uh because it's the best way to build Rec native applications copying the same style name in different files wouldn't that cause issues when building your project for production not at all because this is not CSS this is simple JavaScript objects so you can call them however you want but at the end like it's a simple JavaScript object P to a component so it doesn't collide with the names of other components perfectly fine fine uh what I was doing I was going here okay I was trying to create a poll it doesn't allow me because I'm not sign in but if I am going to sign in it's going to go to the home screen to the profile I can go back and I can go to the create poll now it allows me to go here because I'm already signed in so let's go ahead in web let me check the get status get add do I have that search I don't need the search screen so get OD get commit I didn't do commit for authentication I think I did but anyway here we have so next step is going to be to create a poll uh let's go ahead in the polls New and here in the function create pole which we call when we press this button maybe can do some checks maybe you can check if uh uh there is no value in question we can maybe have an error State error set [Music] error use State like this let's if there is no question let's set error to please provide the question so if I press on this one it's going to set the error but we need to actually display it we're going to display it maybe after the button error if I do provide it and press again I want to First reset the errors when we when we go in this create poll so set error to empty now if I provide something and create again it disappears if I delete and click create it appears again and maybe you can do the same validations for the options to make sure that there is at least one option one valid option or at least two valid options so maybe you can do const valid options equal options. filter I'm going to filter only the options that are not empty strings and then I'm going to check if valid options. length is less than two then we're going to set error to this one uh please provide at least two valid options and after setting the error I think we need to return not to go to the next step so now if I do create poll shows me the first error if I do question create poll please provide at least two valid uh options and I think it should work even if we create poll it works if I don't have one uh if I have only one it raises the error and I think it will also work if any two options are valid because we can take V those and use them for them skip them the ones that are missing and use them okay after the validation here we need to actually create these options in the database let's go ahead and see how we can do that by going to our superbase dashboard going to our table let's select the public schema where we have our tables let's go into the polls and under the API documentation we can see how we can insert rows you can insert one row you can insert many rows at the same time uh or even upserting which means update if it already exists so let's take this inert row or maybe copy let's come here in the create poll after we do the validation let's do super base which should be imported from our library super base from polls we need to insert and because our super based client is typed it says that the value in the insert is not correct because the value should have a question that's our table remember it has a question and option so question can be question but because we have a same key and value I'll remove it and have shorthand same things with options just like that we are creating a poll with a question and the array of options now you can check here if error then you can alert do alert failed to create theb poll maybe for development you can also console log error to see what's going on if data I don't think you need to do anything here and if everything worked uh I will return here to make sure like if it's an er error it stops here but otherwise I'm going to do router imported from export outer then back so basically go back if I go with this approach if I go with this approach option 2 3 1 4 Create poll fail to create the poll why let's see it says that message new row violation roow level security policy for table polls again that's coming from the uh security of our table which does not allow anyone yet to create an insert data let's go ahead in the table editor polls and here under the three dots view policies and we have a policy for select but we don't have a policy for insert let's go ahead and click on create policy and I'm going to use also a template enable insert for authenticated users only with this policy you see that insert in the Target Ro we are targeting only the authenticated users so we are not going to allow anyone to insert but only users who are authenticated let's create save and now try to create theb poll again if I do that I come here if I reload the first screen we see uh the a new item being added here I just realized that we are not displaying correctly the the information but we're going to do that in a moment so if we look in the database of our table polls we see the question with four answers I think it would also we said that we want to skip the options that are not added so instead of sending the options I'm to in the insert I'm going to send here the valid options which will be only the ones that are nonempty so if I do create poll now it should have only two values yes the first and the second perfect um also based on that raw security level we're going to be protected on the database layer for only authenticated user being able to add something there and I'm going to show you that for example if you don't have this on the database layer and only on the user interface for example here if I am signed out creating a poll is also protected on the UI but imagine if someone bypasses that or if you made a mistake and you forgot to add this protection in the polls new at the end here I'm going to comment out this redir meaning that I am allowing a unauthenticated user user to try to create a poll he's going try to do that and when creating a poll he's going to see fail to create the poll if we look here we see that security policy does not allow him to create the poll so he has to go here sign in and then the database will allow him to write so this way we are sure that we are protecting not only on the UI but also in the database layer create poll now it works and now we have more items I'm going to move back here okay let's go ahead and do a get add get commit minus M create polls can the options be saved as Json what options uh Robert is saying I just submitted a polling up to the store last night congratulations send us a link would love to see it um let's uh go go back to to the fetching because I just realized that we are not displaying the title of a PL like the question of a poll here but a damy text that is happening in our application index and here instead of a example poll question I think what we want to do is say item dot but the item polls doesn't understand that it's an array of yeah here is the think without proper typing like I'm not going to have uh out proper autocomplete so yeah I know that there is item do question but types screen doesn't tell me that and it renders correctly if I want typescript to tell me that let's check where we're taking it from we're taking it from use State the UST state is defined as an empty array and if we hover over poles we see that it's uh an array of any because we didn't specify what is the type of every single item in that array yes the data here is typed because superbase knows it but our state variable is not typed so what we should do here is we can import the database type import database from types super base and save it this state or let's find here type poll equal database and if we're going to look at this database we see that the database has uh has what has a field public then tables polls and then row so we need to get there to get there we need to access database uh we first have to access the Public Public is our schema our database schema public then we need to access the tables then we need to access polls then we need to access row and now I can use this poll to properly specify the type of my state which is an array of poles now if I check here it works properly and I'm going to have proper type suggestions item do question uh in order not to have to access it like this all the times uh I used to create in my types a helper helper functions to easier access different tables I'm not going to do that in the superbas TS because this file is going to be overwritten every time we update our database and we generate new types so I'm going to create a new types here let's do db. TS and here let's uh find this Poll for example let's import the database from the super base and I'm going to export type Pole so it's a simple helper type that gives us access to this one when this one is going to automatically be updated and regenerated it's going to affect this pole type now I can go ahead in my home screen press import here and it imports from types database and I can remove the one above types SL DB I don't think I need the ID actually here so I'm going to only leave a question so now we are properly rendering it here when we navigate to the detail screen when we navigate to the detail screen that's going to be inside our polls ID this is the screen where we are uh rendering the details of one of these poll with their options so for that we're going to have the following things we're going to have a poll State set poll which is going to be of type it's going to start as null but the type is going to be pole pole which is the helper function imported from types DB we're no longer need v d data uh we're going to check here if po is not defined that means that I didn't uh find it where it's still loading so I can do here return I will assume that it hasn't loaded yet so I'm going to Simply return an activity indicator to show a spinner so if I'm go there we see the spinner for the activity indicator now we simply need to fetch that pole using super base and set it in state I'm going to do that here in a use effect and I'm going to do it based on how we fetched data on the home screen let's copy the whole us effect from here in the ID because it's very similar how we fetched all the polls let's import super base alert and here the only difference is that we need some conditions uh the conditions can be applied here after the select so we need a condition equal where the first parameter is the column name and the second one is going to be the value that we want to compare with so we want to find the poles where the ID is equal to this ID we're going to have a problem but we're going to see it later uh so let's try let's try actually first and see that problem then let's do here single in order to take only one item it's not erroring error let's try to set it in state but I believe it's not going to work because it should be a number not a string that's a bit weird because ID is a string but ID of our pole is an integer so as expecting it to actually not work but in fact it's working anyway if you have some issues we simply have to convert from a string to an integer here by using number dot pars int like this so if I go here it works as it was working before it also F feates the option we can select and shortly we're also going to be able to vote okay so this was the let's check if we're rendering everything poll. question poll. options selected yeah everything looks perfect maybe the set selected should be empty at the initial and I think everything else looks good let's go ahead and do get OD get commit fetch poll details now our next step is going to be to handle the user votes give me one second and I come back and we continue for [Music] okay I think I need some oxygen in this room so let me quickly open the window okay so with polling we are done we managed to create to fetch a list of them to fetch the details of a poll that's perfect now it's time to handle the voting after we select and after we press vote we want to save this vote in the database for that we need a table in the database let's go ahead and go to the table editor under the public schema let's create a new table the table is going to be called votes and let's create some columns well the vote is going to have ID created add it's going to have the option that was selected right and this option is going to be text and it cannot be null if you vote you need to select an option and the vote will also have two relation relationships a vote is first of all created for a specific poll so let's create here a new add the new column poll underscore ID with the type of our the ID of a poll I remember that the type is integer 8 uh so we can also say that what is nullable like this let me make sure that you see it properly by doing it like this so poll ID integer 8 and we dis selected is n is nullable now this PO ID we can enforce a strong relationship not a soft one using a foreign Keys a foreign Keys let's add it it will create this uh relationship between the vote and the poll I'm going to select this relationship is going to be with a table from the public scheme and the table is going to be polls here we need to select how do we want to connect based on two fields on the vote we're going to use web pole ID and it should match or link to the poll that has the same ID as this one this poll ID uh if we provided a different column type superbase will automatically update the uh the PO ID type to match the one that we are referencing and lastly we need to specify what should happen when a referenced item for example what should happen with a vote when the poll is updated or deleted when it's updated there is either no action Cascade which means that update this one as well and updating means when it the ID of a poll is updated I don't think the ID is going to update anytime so we can simply say Cascade or even restrict uh but removing is interesting because what should happen when we remove a poll I think logically would be if we remove a poll let's remove all the votes automatically so that's a c casade uh option Cascade means that when removing the referenced item all the items that are referencing to it is going to be automatically removed and this is very helpful when working with data because you don't have to think about okay I deleted a post now I have to go delete comments delete likes delete shares delete analytics and so on no you just specify what you want to happen then you delete the post it deletes automatically all the relationships that you set to be deleted because you can also say that you don't want the poll to be deleted if it has some votes that's also possible but I'm going to leave to Cascade let's save and this is it for the foreign key of our poll now the second relationship of a vote is yes we are voting to a uh for a in a poll but we need to know who is the user who voted so let's add here another column user uncore ID I think in this case we don't even have to specify the type I can check it check out the is nullable and I will go ahead to other forign key as well this time the schema the table is not going to be in the public the table is going to be in our off table and the table itself is going to be users let's select the uh the field from our from the votes table which is user ID and the field from the off users table which is the ID super base will automatically update this type to match the IDE of a user and what should happen when we update user ID I don't think we need yeah I I think we need to Cascade if somehow the user ID changes we need to also change the ID the user ID in the vot to make sure that we are still referencing to the same user but if the user is removed here you can decide because if a user is removed maybe you don't want to remove his votes because that would mean that in future like very old polls will have different results change the result as users delete their account maybe you want to keep them but maybe set to null so in this case there will be a vote but we don't know from whom because that account was deleted yeah I think with set to n probably should be a better approach here or maybe no action and in that case it's not even going to replace it it's going to have an ID but we're not not going to find that user in the table so we know that hey this was an ID but we don't know more information about him because he already deleted his account so let's press save and in this case user ID yeah it's like that let's go ahead and save because I think that's the only columns we need for the votes I'm going to click save after you do V hopefully it's going to work if you are downloading the the types from the API docs go ahead and download the updated version because now the types of our table has changed so what I'm going to do if I look in the super base here we see that we only have the table polls and if I scroll down there is nothing else if I go ahead and run our script that we created earlier npm run gen types which is using the superbase CLI we're going to see that our superbase TS has tables polls but if I scroll down it also has table votes with relationships as well perfect I like it so thinking with database. TS you can also Define um helper type for the vote uh and simply change here from polls to vote is it correct votes yeah votes yeah next time when we need to type something with a vote row we're going to use this Helper but what we have to do remember by default um nobody is allowed to write or read something from the votes so we already know that so that means that we can go right away in the view policies of the vote of the votes table view policy let's create a policy I think we want to enable read access to everyone so let's click save so anyone can read the votes but we want to create another policy to enable only H to enable only authenticated users to be a ble to create a vote but later we're going to see how to allow Anonymous authenticated users so we're also going to check that but for now let's select enable insert for authenticated users only save policy and we have insert and select perfect let's go ahead in the table vote under the API docs there will be this insert rows we can copy it from here go to our code inside the details where polls ID we have this vote function let's add the code for creating a vote in the database uh our function now became a sync or if it didn't update update it manually so yeah what do we have to do we are inserting in the votes table we are inserting some Fields what are the fields well I remember that we need to select the option that was added and our option in the database is the selected State variable so it's going to be this selected string next one the next one is going to be poll ID we need to link this vote to this specific poll we can take it from our state poll. ID same thing with user ID we need to take it from somewhere where well remember we created that easy way to get access to the user using the use of hook imported from our providers so let's take the user and for the user ID I'm going to use user do ID user ID is user ID now we see that insert is no longer red which means that we provided all the required fields and I can go ahead and test if I go to how are you and do awesome vote not sure what's happening because we are not handling the error but we can check if we have some data yes we see that the time stamp to the poll ID one this is the user which is me uh and yeah that's the only thing that we need to know where what did the user vote for after that happens we can check if error maybe you want to do an alert uh alert do alert failed to vote else alert alert thing thank you for your vote so if I do one more thank you for your vote and we see one more payer perfect perfect perfect perfect and I can go to another one and do the same vote thank you for your vote and it's going to have option free for the poll with ID 4 if you go back to a poll that you already voted maybe you want to see what did you vote for in that case we're going to need to store the user vote in a state variable user V use State initially is going to be null but here we can type it using the vote helper type from our types and let's go ahead and in this use effect where we are fetching the pulse maybe afterwards like after after setting the poll in the state let's also fetch user vote also here or maybe in a separate function but also in the same use effect fetch user vote equal I sync I'm going to copy everything from the above and say I want to fetch the votes table where and I'm going to filter by two Fields I will look only at the vote where Poore ID is equal to the ID of a poll that we can take from this ID and also I want to check only the field only the votes where user ID is equal to user. ID this is going to give me only my votes for this specific poll after that I can do set vot user vote using data make sure to call fetch user vote right here as well and and and and also when calling set user vote we can if if there is some data if it found something we can update the selected field using data dot option so that it displaces the selected now if I go back to the first one error fetching user vote y unexpected token what unexpected token let's console log error the results contains two row hint message Jason object multiple or no row returned so if I do single it gives an error if the result has more than one row and actually in the first instance I called multiple of them what I can do is before calling single I can do dot uh limit one and only get one item there so if I go to the first one oh come on I'm going to have to control z a bit until I get back the Styles and Dot limit one so give me only the first one and take it from there using the dot single all right seems to work what's we here is well what's happening aror fetching user vote the result contains zero rows I don't think I need to actually check the error yeah I'm not going to check the arror for the user vote because it might be that there is no user vote there if it is good for you I'm just checking if data then select it and if you already have a vote I think it would be better if we update it instead of um instead of creating a new one so if I go to the polls uh API dogs update super base update equal okay do so we have upsert upsert insert R let you user insert T you can also insert in bulk and do upsert absur matching rows absur okay how does this work more exactly absur dat upser would be like uh update if it exist or or create update if it exist or create if it doesn't so on the table depending on the columns passed to on conflict allows you to perform a insert if a row with corresponding on conflict com doesn't exist or if it does exist perform an alternative action depending on ignore duplicate primary key must be included in the values to use upsert yeah I think you know what I think in the vote when we do insert it's automatically going to do upsert now didn't it say no it's going to do m if I do upsert but also include here viid but only if it exists so ID user vote. ID or or undefined because if it's not there I will do undefined and I will let it create a new one will it work what do you think we can only check I'm going to go into the vote we see what do we see here for the item one I'm going to delete and I'm going to leave only one vote for the first poll I'm going to go here and I'm going to change from awesome to good vote fail to vote because I don't have permission you know that's also true uh if I do console do log error we're going to see if I change and the vote we see that we don't have permission to update it's still going to work for for a new question for example here if I do vote no uh details no null value in column ID of relation vote violate relation n value n um maybe maybe maybe uh it should be like this const new vote equal to everything with the exception of this one and if there is a user vote only then add it to the new vote. ID equal to userv vote. ID and then use this new vote here wet so let's at least like where create should work create thank you so if I come back it's here the update is not yet working because we need to allow users to update information so I'm going to go into the polls view policies and I want to go to create new policy and I want to up enable update but wait it's not about policy it's about votes so back to the table vote policies let's create a new policies for votes and I want to enable update for users based on email no enable insert in policy with no no no no no based on user ID something like that so let me check what's happening if I select this delete and we see that the differen is in this using so I'm going to copy it from here because I want the same condition based on user ID but for update so for update instead of email I want with user ID user ID this will allow only owners of the vote to update his own vote enable enable update for users based on user ID save policy and I think now it's going to allow us to to change the vote and to update it thank you and if I go back it's updated and in the table it should also be updated with the same ID but now it's good if I go here ahead and change it to awesome thank you it's going to be changed to awesome here so this way we are firstly we're are creating a vote if it doesn't exist we check here 222 and later if it exists if I come here it exists I'm creating it and it says thank you and it's updated here perfect I think after creating the vote where where we get the data uh we should also set set user vote with a data select do single single to be able to update right away after creating it for example I don't have a poll test one two create AR reload it should be test create vote I hope it updated in state change it and I hope hope it changed it so if I go back here yes it's it's changed and we only have one vote in the database because it's only one vote per user perfect so that our user voting get OD get commit minus M um user voting but it's only going to allow off authenticated users to vote if I sign out from here and go back to check the to check the polls without having an account you might want to allow users without an account to vote for something maybe you want to have a property on the poll to say like allow unauthenticated users to vote uh but in general this is a very good uh option to be able to allow guest users to do something at the moment if I'm going to try to do something I'm going to vote and it's going to tell me uh there was an error you are not authenticated and you don't have permissions to do that so it even cannot read property ID so that would be in somewhere in user. ID for example here in Fetch user vote it's doesn't make sense to fetch user vote if there is no user right so I'm going to return same in the second case uh it doesn't make sense to vote because there is no user ID but anyway we could try we could try that and we're going to fail maybe you can do it like this and it will say fail to vote because you don't have permission for that this uh to allow Anonymous users to vote uh this is called yeah Anonymous authentication and this was one of the most requested uh features from super base and I'm very happy to announce that super base has added Anonymous sign in as part was of their last um Lounge week so if we go to this blog post under the lunch week we're going to see that now it's possible to enable Anonymous sign in and it's super easy to do that all we have to do go to our dashboard uh go to Project settings under authentication there is allow Anonymous sign in let's select that and you can also select allow manual linking in order to allow users to link their Anonymous uh credentials with their password and email after we decide to create an account let's click save and now users are allowed to create Anonymous sign in to do that simply call off sign in anonymously and that will automatically sign the user in let's check that for example I can do it in providers I can say that hey get the session but in the user fact get the session but if there is no session sign automatically the user as a guest you can do it in different ways you might have a login screen with a button continue as a guest and create it when the user presses that button in my case I want to automatically create an account for him you might have to think about an decide what would be better approach for you but uh and I'm going to show you in a second what is the differences so let's go ahead and use super base off sign in anonymously it's going to give us back the data with a session which you can um which will trigger this one so it will set the session and I don't need to do anything I will if even remove wait I will simply call super base of signing anonymously but only if there is no session only if a user is not actually signed in so if I reload now and if I go to my profile we see a user ID here even if we are signed out if I'm going to go to my table schema of users we're going to see a couple of users I was refreshing so that's why it created so many and if I scroll till the end of this page we're going to see here is anonymous and only one user is not Anonymous and the rest are Anonymous so yes now we have nine records I don't think it's going to create a new one if I refresh it's going to keep the same one because it stores it um it stores this information on the device it created multiple just because I was calling it uh without this if session now it has a session so it doesn't uh create a new account it will create a new account only if you press sign out it will go to the login and the next time you reload the application it actually created a new one with a different ID and we see 10 users here so the thing is that after you sign out from a Anonymous user you cannot sign back in so the user will lose data there but that's uh that's actually how Anonymous sign in works if a user later decides that hey I actually want to connect my account to that he might want to go and uh link his identities create an email and password and gain control over this Anonymous sign in that's possible and it is explained in the documentation you can check it out inv the super base uh here you are going to see from non-user to authenticated user when you update the user with email so he becomes a permanent user here convert user to permanent you can do that with update user email then confirm his email then add a password or using provide linking providers like Google sign in with Google uh what I wanted to show right now is if we reload now if I try to go to the login screen it redirects me to the uh profile screen well that's not exactly what I wanted but because I want I'm not yet logged in with a permanent user I am a guest user but anyway I I'm considered an authenticated user and this is important to understand with this concept with uh Anonymous authentication because an anonymous user is still a user so everywhere where you're checking like if it's user than uh allow him to do something should now be reviewed to make sure that you're checking if it's user and if it's not Anonymous for example I want to redir to the login screen if the user is not Anonymous so probably I will go into the off provider and I'm going to export one more thing here is authenticated as a Boolean which will mean whether the user is has a permanent account is authentic at it initially is going to be false and I'm going to export it from our value with the come on with is authenticated with the next value where session if session user is true but at the same time if session. user is not Anonymous is anonymous equal false so the user is authenticated when it has the user but it's not Anonymous so I can now use this is authenticated in for example my uh protected layout to take not whever it's user but whever it's authenticated so if it's not authenticated go to login screen now I can go here and and it's redirecting me back because I have to use the same logic the same e authenticated back on the authentication screen so on the authentication I redirect back only if he's not actually authenticated so now can go here it allows me to log in I'm signed in as a guest because you see I'm at the login screen but I can still vote because I am a guest and thank you for your vote and if we check in the votes table we have a new vote from a user with a different ID than the others that we had before with the EF the guest user so even if you I believe if you close the application and open it again even if you're a guest it's going to store that information for you you'll lose it only after you uninstall the application you're not going to be able to to use the same guest account you see it's the same super good but after logging in to a permanent account sign in whereever directed to the profile so profile is only for permanent accounts and I have a different Vault here because that's what I did before so that's everything well not everything another important very very important thing is the same thing uh as I explained Anonymous users are still users they have a user um role and you need to pay attention at your database security policies to make sure you allow certain features only to permanent users here uh it shows how we can do that we are going to use the JWT token and in that token there will be that is anonymous so we can use it as part of a ro level security so for example I don't want a guest user I want a guest user to vote so for that all good but but I don't want a guest user to be able to create a poll so I'm going to go into the view policy when I have insert I'm going to edit this policy at the moment I'm allowing all authenticated users to to do that uh Anonymous and a normal user we both authenticated role we need an extra check here that will say only the users that is anonymous is false should be allowed to perform this action if I save this policy go back here I'm signed in so I'm on the profile screen I can create a poll it was created but if I sign out now I am a guest if I try to create a poll I should not be able to do that fail to create a poll and you can yeah this is on the database layer you can do on the UI layer as well but you can still do other things for example vote so it's up to you how you decide uh how you manage these roles but important thing to understand is that when creating a new policy here When selecting the target role authenticated will Target both Anonymous users and also the one with a permanent account if you want to restrict something to only users with a permanent account you can check it through JWT token based on this is anonymous field so that was the uh tutorial guys I think uh I'm going to stop here and I'm going to publish the code and I want you to take this tutorial from here and uh improve it there is a lot of ways you can improve it you can add a lot of options to these polls you can add images uh you can count the votes and so on I had a lot of fun putting this together with you and thank you very much super base for making it possible uh and yeah um if you enjoyed it make sure to subscribe we are going to have a lot more tutorials like this in the future one of them is going to be this Friday so so this Friday we are continuing our local first uh tutorial which is also going to use super base anyway I really have to end this live stream thank you very much for watching and have a great day guys bye-bye
Info
Channel: notJust․dev
Views: 13,507
Rating: undefined out of 5
Keywords: vadim savin, not just development, notjust.dev, live coding, react tutorial, react native tutorial, react native for beginners, React Native, step-by-step tutorial, expo, supabase, supabase auth, backend integration, real-time data syncing, secure app development, ui design, supabase backend, supabase tutorial, voting app react native, poll app react native, integrate react native and supabase, react native poll, react native polling
Id: TdPnIu8Duwc
Channel Id: undefined
Length: 239min 33sec (14373 seconds)
Published: Wed Apr 24 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.