Build a React Native File Uploader Using Supabase Storage 🚀

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this video we will build a react native file upload with Super Bass storage and Expo [Music] Simon from galaxies.dev and today we're doing a react native tutorial in combination with Super Bass so super bass is the sponsor of this video I've worked a couple of times with Super Bass before and if you haven't used it I really don't know why go check it out you can get started for free it offers everything for you to get started with the backend as a servers authentication file upload other two things that we're going to use in this video but there's so much more about Super Bass that is everything you really need as a powerful backend for your application so go check it out and create your free account and we're gonna Implement our file upload using Expo and the latest sdk49 which just came out so we're gonna have the Expo router version two we're gonna have authentication for the different routes we're going to integrate file upload to an API to this Super Bass API and we finally also built a pretty cool interface for which you can find the code right link below the video so go to GitHub or go to the Super Bass block where you can check it out and now let's dive into to the coat alright so let's get started with our application and we're going to start in Super Bass so you can create a free account if you haven't done so and then create a new project I'm going to start one here I'm going to call this video um Cloud app doesn't really matter I'm going to generate a password you should take care of noting that I'm going to use Frankfurt and create my project I wanted to do this step right here in the beginning because this takes like one or two minutes so we can uh put this now to the background as it is setting up and focus on our application so I already started this running the command npx create Expo app latest I want to use sdk49 that suddenly I can use it the name is going to be Cloud app and we're going to use the tabs template also at sdk49 this is not perfect I think it contains a few files too much but we're going to get rid of them in a second of course we need the Super Bass JavaScript package we also need a little poly fill package array buffer for some base64 transformation and a little loading overlay because loading overlays are cool and easy to use and finally three Expo packages the first one will be used for authentication and handling the session the other two are required for selecting an image and then reading the information from our file system so go ahead with all of these and once you get that you can also create a new DOT EnV file yeah we can use a cool EnV file just like the cool backend kits although be aware this is not really like a back-end EnV we can use it and we don't have to commit it to GitHub and stuff but uh the stuff we have in the EnV that we're going to load because we use Expo public will be in the bundle of our application but anyway the Super Bass URL and the Anon key can be used safely and what a coincidence the project was just finished that was actually what was it a minute maybe I think it's gotten Firebase is getting faster so I'm gonna copy over my my Super Bass is getting fast the Firebase is only getting slower I'm carrying over my project URL and the Anon key so both go to my EnV file and then we can use them to initialize our client but before we do that let's quickly talk about two things I want to change in my project so number one is under authentication we already have by default um the email provider enabled the only thing I want to change is I don't want to confirm my email I don't really need that settings so hit save here and disable this otherwise you get email and that confirmation takes you to the wrong page it's a bit more complicated and I don't want to do this right now on top of that I will go to storage and create a new bucket I will call this files so this will be the place where we upload our file to from the react native app I don't want to make it public because only users should have access to their own files and to make sure that the files are in fact saved we're going to add a policy now you can create policies from here they're actually cool starting templates so if you don't know what a policy is or how it works these examples give you a really nice starting point however I figured this out and the policy we're going to use is something we can just do with the query editor so I'm going to do a new blank query here and paste this in so I want to create a policy on storage objects for everything so read update uh read create update delete using bucket ID files and my of ID should be equal to the folder name so that means a user with the ID 123 can only access files under files slash one two three that's the idea and then we can enable here run this and success no rows return I always get scared when I read no rows returned but if it's a success it's a success okay uh we got that so let's continue we got our app and I think yeah I mean we can start it right now uh with npx Expo uh so this will load our EnV file we got those starting Metro button I'm gonna press I so I want to run this on my iOS simulator you can also of course use Android or also even web but at some point we're going to be challenging as we use the Expo secure store which is only available on a device nonetheless we're going to see the default now with the Expo router uh version two and there are a lot of files and I don't really want this I want to give you an easy example to follow in all cases so we're going to do something radical we're going to release remove constants components and app just gonna release remove everything because I really want to show you how you can build this app up from the ground if you're scared that don't you see anything just create a new folder app insert an index.tsx Rec native functional export and then uh your screen is gonna be happy again with an index file and you can hopefully sleep better if you uh drop out of the tutorial right now but the most important part is now um getting everything in order and we're gonna start with the configuration so let's create a new file in it Superbass dot TS and within here we want to create the connection to Super Bass now what we need is not this um but the create client function from Super Bass on top of that we will also use the Expo secure store because this will help us to persist the actual session of a user so we can add this little adapter here this adapter manager which has a function to get an item set an item or remove an item and then we can pass this to the initialization of Super Bass on top of that we can now easily grab our keys from the process environments so the Expo public supervised URL Super Bass in and key and then we can export the actual object so export con Super Bass using Create client yes URL and key will be defined and then we can have some more options so many cases it already stops here but for react native we will now set the auth object in here and set detect session in url to actually false so this is something we have to do for react native otherwise we're going to get into trouble and then we're gonna set our own storage and use the Expo secure store adapter that we configured up here and what they those changes in place Super Bass will automatically use the Secure Storage secure store for the session so every user signs in this is handled and managed in the background and we're easily able to plug this into the whole react native and Expo echo system so no problem at all cool uh let's continue with our index so this is basically um our login page maybe we can even call this login uh sounds cool looks cool there we go okay so on the login we of course need a bit of State um we need email uh password and probably also a loading State and we need a functionality to sign in the user so on sign in we want to do something and we also of course need to create the view now as I said before you can find all the code down below so we're gonna Rush a bit through creating the UI part here because that's really somewhat boring and not super interesting so I'm going to add a few Styles here uh stylesheet yeah should be imported but we can do this in a second um and on top of that we're going to update the Imports up here do you have some more stuff from react react native actually we don't need that one really and of course Super Bass and the loading spinner now with those changes in place we can create the actual view we're gonna use this page to have both the sign up and the sign in on one page they will just make life a bit easier in your case you can just create another file and then you can navigate to that and then you can create your account from there for now that's all we need so we got the two text inputs we got attachable for on sign in and for on sign up and a bit of styling to make the text Fields really look like they're really cool the only thing that's kind of ugly are those borders uh we should be able to overcome this by adding a new layout here let's try this out layout.tsx and for the layout uh let's try if we can just re uh do like a root fruit layout um something and then we want to return I mean we just want to return a slot honestly um let's see export default root layout would this make the app happy yeah it's making you happy I know the right buttons to press good all right here we go um this is the login we just need to hook this up to the actual login functionality and the Super Bass SDK comes with all the functionality actually one more thing I see since Expo 49 we can do something like this isn't that cool yeah it is I think so those are Alias this setup in the TS config file which defines that at the top level we can just have an ad and we don't need these ugly relative path anymore all right uh on sign what do I want to use let's start here so on sign up we want to set loading to true and then we're gonna do the sign up with Super Bass which is just using auth DOT sign up and I'm passing in the email and password now if we do get an error I just want to use the alert dot alert yeah error signing up and then error message should be fine and finally set loading false actually what was that else alert sign up successful also that sounds nice yeah yeah uh here we just need sign up successful I don't think we need anything else uh let's see um I will also just add my testing so this makes testing a lot easier if you just put in your own stuff here during testing so these will be my settings let's try to create an account sign up successful and if I do it again error signing up user already registered perfect that's exactly what I wanted to see um now I can copy part of this uh basically only just the set loading and we can use now guess what sign in with password and sign in with password of course also requires email and password but if there is an error actually we could have left that error signing in so if we got an error here let's try the error case first signing in okay invalid credentials and otherwise we should actually get back an account or at least we should not get back an error so we're now signed in um the information we get is not super relevant uh it's not relevant here because we will now go a step further and add a context to our application so we can do this let's do a new folder with cool kids and structure our app in a great way so provide our goals here and then we're going to call this the auth provider.tsx what an epic name isn't it um in this file we will create a context for our application and we're going to listen to the state of the Super Bass session so we use the Super Bass SDK well listen if we got a user we're going to update the state if we don't have a user we updated and by doing this we can then wrap it around our application and use it as a little hook in the different parts like the tote and the use of the session in the rest of our application so it really makes life a lot easier let's do this I'm going to do this one by one so we start by adding a little type and then defining the context with partial of those types so that helps us to initialize it correctly I really remove this typescript will be not very happy with you then we can also export this as a little hook so that makes it easier once we want to import this stuff and finally we're gonna create the actual auth provider now this one's following a very common theme for adding authentication to your app we have the use effect which runs once in the beginning that's why we have the empty array here and once in the beginning we're going to set up this auth state listener and we'll also correctly unsubscribe if this is uh removed now on auth state change of Super Bass we get an event and a session event is not so important in our case but the session is so we're going to set this to our state and also the user in case we want to load some data from there and we also set initialize this will be important in a second because when you start the app the app is not initialized and you maybe or maybe not it's like trading as cat you might have a user or might not it's an async call to get the session of a user and I don't want to do any kind of routing before the session is actually there before we looked into the box and looked if fruiting as cat is actually alive or not so this is like I should call it like like schroding as kit or something so this is it additionally we have a little sign out and then we uh add everything as a value to our provider and now we can go to the topmost layout file in our app so this is how it works with the Expo router and we're gonna wrap this within our of Provider so our provider and could you please just do the relative Imports that would be so cool if you just did this automatically because I'm a cool kid dang so um I will do another initial layout now and in this initial layout I will do some more stuff I'm doing this because then we can actually access our hook as well so we'll just do this and probably you gotta have some other providers here so that it makes sense um yes this one needs to return something so now you're happy right um so what we're going to do here is we're gonna check we're gonna get a few Imports first of all so we're going to use the Expo router and we're going to use the router and the use segments hook because we're gonna get different segments of our path now this is the empty pad this is just slash but if I now create new folders and new files because we're using file based routing with the Expo router version 2. this is basically the path to a certain component or page I never put brackets around this I can just group different pages and this off part won't actually appear in the URL which is pretty cool so I can then have like a list of TSX in here yeah let's call this list and then I could navigate to slash list simply but the thing is I want to protect everything that is in this auth folder so I can also have like an outside folder which is public but everything inside this auth folder should be protected and we're going to add the protection as well but we also add a check here so with session and initialized we're going to add a use effect block and if we're not initialized I can just simply return here because then there's nothing for us to do uh on the other hand I also want to check if we are in this auth group so I can check the first segment and see okay the user currently trying to navigate to Something in the auth group and now based on that I can add a little redirection logic so if we do have a session which we grab from the context and we're navigating to something that's not in the out group like login register or any outside page we can actually directly take the user to the inside page right because that's how you do it otherwise the user reopens the app after a time he has a valid session or she um and it's just on a login screen so we can do a better job on the other hand if our session at any point changes we're gonna route directly back to this we could actually add if we don't have a session um and we're in auth group that would also kind of make sense so with that in place we just need to return a slot so that will just render everything else all the other layouts and files of all application and now we see I think we are actually on the list page because there is something up there I just can't see it correctly and if I want to see this correctly I will just add a new layout file in here layout.tsx and in this layout file I'm going to define the layout for the inside area so what I want to have is a simple stack layout and within the stack layout we can but we don't have to define the different pages I only have this one page named list I want to add the header title and I will also add a button to the header right um and then let's see here we go my files we got the lockout button up here which is simply accessing the sign out and we know we're Children of the context so we can use it in here and that's actually all we have to say about this there's one other thing that we could do so we could also have a redirect here so in case we don't have a session we could add a redirect that one also further protect this page but nonetheless we should be able now to get to that page and with that we have already finished the first part of this tutorial which was authentication we kind of didn't really notice but I can now sign out I'm brought back to this page because of these lines so session changed in our context we're reacting to this and replacing the router we're going here and if I sign in session changes I'm still outside and I'm brought to the inside area which is pretty nice and pretty cool actually uh sometimes you just need to take like a little moment and think about oh that's pretty cool what I've been able to implement without actually writing back-end code so thank you super bass once again for this uh you should also by the way be able to check out your users under Authentication so there you're gonna find the user account great now the next step is the actual file upload which is going to be interesting as well so let's go to our list page and let's set up the base let's set up the stage for our application I'm going to add a few Imports so those will probably come in naturally for you once you do this but what I want to do is I want to access the user and I want to create a state with an array of file objects now why do I want to do this simply because we can now create a function let's call this load images which would load our images in the beginning and to load the images in the beginning we know that we can use use effect and make this dependent on the user so just to be really sure that we are only loading the images in case we do have a user I'm going to put in a little to do here because we actually can't really load the images from Super Bass yet as we haven't uploaded any anything so in order to upload let's add a bit of styling so this will help us to create a Fab button the fat button is a floating action button and this Floating Action button should now appear at the bottom of our view on top of that we can already prepare the unselect image function and then we have this nice and clean view so nice dark background a button here that really nice a nice styling co-pilot I like that which will allow us to call a function now nothing of this is really special yet so that's why I've been basically skipping over it now things get more interesting as we integrate the Expo image picker so to pick some images we can now Define a few options and then call the image picker launch image library async or you could also launch the camera async however I'm using the simulator so I can't really launch the camera but both things would work as a result uh we should be able right to click this and capture an image um oh no I shouldn't put this into load images load images that's why it triggered automatically yeah that makes sense yeah so I could now select an image here I can edit it and zoom into this and select it and as a result I would get a Yuri back so let's probably lock this out um let's log result dot assets dot what is it assets results assets I think at index zero um this is the image and that should be dot Yuri right let's try uh we should probably check if res if not canceled so if not result canceled we can continue and cancel this is not how you spell it copilot I don't know what you're getting wrong there anyway let's try so I'm gonna select an image and voila uh this is a file so a file Yuri to some local file how do we upload this file from Yuri to Superbass well there are different options um first of all uh in most cases this works somewhat similar to how you would upload to your own API so if you're not using Super Bass this will also work mostly the same for a different API but if you want to do this with Super Bass there is the basic way and then I want to tell you about something else which is pretty interesting as well um let's get started the basic way would be to access the image then load the base64 string using the read s string using the file system uh package from Expo in the image Theory then creating uh the file path which will be user ID so this is the file pass later on in the Super Bass bucket so user ID Slash new date and the image type and then the content type and then just calling Superbass dot storage Dot from now selecting uh the storage bucket in our case there was files and then calling upload um using the file path the decode function with a base64 string and then the content type and we're going to follow this up by load images so we can upload update our state now this is the basic way how we can do this in a straightforward way with just a few lines but there's one more thing I want to talk about and that is a resumable uploads now this has been around with a super bass for quite some time now and I came very close to finishing an example using up here which is something super bass recommended here as well I think um yes here it is with API so my code looked somewhere like this you can actually see this in the GitHub repository in an early commit however this wasn't working 100 will react native yet so API doesn't really have react native support in a great way um yes I've been able to use it with a hook I've been able to add files to it and I've been able to um trigger all these functions and start and upload and I actually uploaded something to Super Bass storage which I was able to put in as the upload URL so all of that was really cool but the files were always zero bytes so something clearly went wrong with appium of API not being able to actually read the content of my yuris or my files however Super Bass does support this and implement this so you can have resumable uploads for storage on the web you won't have any problem implementing this with appy on react native I haven't been able to get this done I hope to show you an example of this in the near future and I'm sure the Super Bass team will take uh steps to realize this and make this possible with API over the next time just wanted to tell you that there are resumable uploads that is possible with super based storage and it pretty sure it will be possible will react native in the future now back to our use case um in my use case here we have the files bucket which should be empty so let's try and select the file now I'm gonna go into really deep here and then hopefully upload it so let's reload and there it is user folder created file created image upload it yes there we go it is there right there nice we could have also used like image transformation on the Fly Super Bass also has the image transformation on storage now or is it only for download I think it's for maybe it's only for download or upload but you can check this out as well uh that would be a nice addition as well speaking of additions um we are not yet loading or showing images so let's change this actually loading images is really like ridiculously easy the only thing we have to do is call the list function on the right bucket and again using the user's own folder and then we have our data here now um I could just do a little lock here so then you would see load images data Creator but I want to display this and to display this I need to download it and to download it I want to restruct my app a tiny bit because otherwise it's going to be just ugly and spaghetti code so I'm going to add a new file here I'm going to do this new file components I'm going to call this image item dot TSX so components image item and this image item will simply receive the actual item a user ID and an on remove image function so I don't want to remove the image in the actual component because then I need to update the state and everything gets ugly so I want to pass this up and then the parent component can take care of that uh besides that the image item will simply download from files slash user ID slash item name and then use the file reader to get a base64 string which I set as my image and then it's simply an item which has a flex layout an image text and a button to remove this so I should be able to save all of this and with a bit of luck with a bit of luck yeah we're not yet using it yeah that makes sense so uh going back to my list um I should now Implement a little scroll view something up here so let's do this and let's add the image item no still not getting the import right this is how the cool kids do it this is how they do it and this is it but now we got it uh awesome but I think there's one thing missing so we're able to pass in the ID of an item which is basically the idea of the file the actual file the user ID which we got from the context but we also need to implement this on remove image function and this one's once again pretty easy so let's quickly add this up here this will simply call the remove function on our bucket we have to construct the pad like this with an array of components uh yeah I just put it into one string it doesn't really matter too much once again user ID name of the file and then I'm going to update my local files so with all of that in place let's put it together one more time and let's start fresh from the outside area uh with the big application here in I I really hate to resize this emulator it never really works like I want okay let's do this I'm able to create an account I'm able to sign in with a great loading spinner I should be able to select a random image or capture it pick it upload it see it in the folder of the user on Super Bass and also in my app and I should also be able to remove the file with a click here which updates Super Bass storage as well and remove the image from my storage bucket so here we got it uh the full finished working example and actually I think it wasn't too hard yes we brought in some code to speed up the process but overall it's really super easy to use Super Bass with react native as we've seen super based storage you just need list download upload or delete it's a super clean API and also for Super Bass authentication we have the on Earth stay change the sign out or on our login page we had sign in and sign up so a really clean interface that you can use and it works perfectly with react native all right and that's it for today's tutorial I hope you enjoyed this I think this is a really really easy and straightforward way to upload your files to upload any kind of user generated content we've only seen it with image and the image speaker but could be videos could be other files it doesn't really matter super based storage will be happy to serve all your files once again thank you super bass for sponsoring this video go check it out link to the code and the written tutorial right below this video and I will hopefully catch you in the next one so until then Happy coding Simon [Music]
Info
Channel: Simon Grimm
Views: 5,073
Rating: undefined out of 5
Keywords: react native, ionic, supabase, reactjs, supabase tutorial, react native tutorial, react supabase, supabase react, supabase auth, supabase authentication, supabase for beginners, supabase image storage, react native navigation, react native vs flutter, flutter vs react native, react native for beginners, react native app, react native tutorial for beginners, react native project, javascript, supabase database, react supabase tutorial
Id: am6w5zEDk_g
Channel Id: undefined
Length: 32min 45sec (1965 seconds)
Published: Tue Aug 01 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.