Supabase for Flutter Developers - Authentication, Database and Storage | Rahul Agarwal | Skillshare
Search

Playback Speed


1.0x


  • 0.5x
  • 0.75x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

Supabase for Flutter Developers - Authentication, Database and Storage

teacher avatar Rahul Agarwal, Flutter Developer & Trainer

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Lessons in This Class

    • 1.

      Course Introduction

      1:09

    • 2.

      Why use Supabase

      5:23

    • 3.

      Create a new Project

      13:55

    • 4.

      Setup Auth Screen

      12:25

    • 5.

      Work on StartPage UI

      16:46

    • 6.

      Implement Signup and Signin

      10:25

    • 7.

      Sign out functionality

      5:16

    • 8.

      Deep link Integration

      5:15

    • 9.

      Setup Google Oauth

      7:09

    • 10.

      Implement Google Sign In

      12:00

    • 11.

      Working on the crud UI

      15:46

    • 12.

      Implementing Create functionality

      14:13

    • 13.

      Implement Read functionality

      9:03

    • 14.

      Filters and Modifiers

      14:25

    • 15.

      Implement Realtime Database

      7:12

    • 16.

      Update and Delete functionality

      10:59

    • 17.

      Enabling Row Level Security

      8:55

    • 18.

      Writing CRUD policies

      3:26

    • 19.

      Storage Configuration

      6:47

    • 20.

      Implement Upload Functionality

      16:57

    • 21.

      Fetch Uploaded Images

      17:17

    • 22.

      Delete Image Functionality

      6:54

  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels

Community Generated

The level is determined by a majority opinion of students who have reviewed this class. The teacher's recommendation is shown until at least 5 student responses are collected.

48

Students

1

Project

About This Class

"Supabase for Flutter Developers," is the perfect starting point for beginners who want to learn how to use the Supabase platform in their Flutter projects. Supabase is an open-source, real-time backend that makes it easy to add powerful functionality to your app. With this course, you will learn how to set up a Supabase project, authenticate users using email and password, as well as Google Sign-In, perform CRUD operations on the database, implement row-level security, and upload files to storage.

The course is designed to be easy to follow, with clear explanations and hands-on exercises that will help you apply what you've learned. Starting with the basics of Supabase setup, you will learn how to create a new project, install the necessary packages, and connect to the Supabase API. From there, you will move on to user authentication, where you will learn how to create a basic login system for your app.

Once you have mastered the basics, you'll dive deeper into Supabase's functionality. You will learn how to perform CRUD operations on the database, including adding, updating, and deleting data. You will also learn how to implement row-level security, which will allow you to control who can access and modify specific data in your database.

In addition to this, you will also learn how to upload files to storage, which is an essential feature for many apps. You will learn how to handle file uploads, store them in the cloud, retrieve and delete them later.

By the end of this course, you will have a solid understanding of how to use Supabase in your own Startup or Flutter projects. Enroll now and start building powerful apps with Supabase and Flutter.

Meet Your Teacher

Teacher Profile Image

Rahul Agarwal

Flutter Developer & Trainer

Teacher

Hello, I'm Rahul. I am skilled in building cross platform application using Flutter. I am freelance developer as well as conduct workshops to share my knowledge with the community.

See full profile

Level: Beginner

Class Ratings

Expectations Met?
    Exceeded!
  • 0%
  • Yes
  • 0%
  • Somewhat
  • 0%
  • Not really
  • 0%

Why Join Skillshare?

Take award-winning Skillshare Original Classes

Each class has short lessons, hands-on projects

Your membership supports Skillshare teachers

Learn From Anywhere

Take classes on the go with the Skillshare app. Stream or download to watch on the plane, the subway, or wherever you learn best.

Transcripts

1. Course Introduction: If we were to flutter developer, then you might be familiar with Firebase. Firebase is not the only option in the market. There is another competitor which is a very good alternative, and it's known by the name Superbus. Superbus is gaining popularity day by day and he's getting a good response from the community. The best feature is its open source nature and their pricing model. Supply base is free to start and it's paid plan chart is a flat monthly fee for unlimited use it rather than pay as you go, which can be very costly in the long term. This course is designed for beginners. We will start by setting up a new supervisor project. Then we will learn how to allow it indication using email and password as well as implement Google sign-in. After that, we will get into database crud operations. We will also listen to realtime database changes via streams. Then understand the concept of row-level security and how to write policies to secure our app. And finally learned to upload and delete files in this storage. By the end of the course, you will be able to build your own dream startup using all these concepts and who knows, it can be the next big thing in the tech industry. So without wasting any more diamond, Let's get started. 2. Why use Supabase: Hi, welcome to the very first video of the course where we will learn how to use supervised database with clutter technology. So what is Superbus? Superbus is an open-source, real-time and powerful back-end platform that makes it easy to build and scale web and mobile applications. To biowaste is built on top of Postgres sequel, a powerful SQL Database which makes it easy to work with complex data structures and relationships. It also has built-in support for authentication, authorization, server side logic and storage. Wildfire, which has been around for quite some time and has a wide range of features. So Barbies is relatively a new player in the market, but it is quickly gaining popularity among developers due to its open source nature. It's built-in powerful features and its flexibility. With Superbus, you have complete control over your data and infrastructure and you can customize the service to fit your needs. In this course, we will focus on learning about authentication, database, row-level security, and storage in a simplified step-by-step way. But before moving there, Let's discuss some points on why we should choose supervise over Firebase. The first point is SQL vs. NoSQL databases. Postgres sequel database are particularly powerful when it comes to complex queries, joins and filtering. Because data is organized into tables, Defined relationships. In supervise, you can use join command to combine data from multiple tables where you want to retrieve related data in a single query. You can also use filtering and sorting comments like where an orderBy to retrieve specific subsets of data. In contrast, NoSQL databases like fire basis, wearing data can be more difficult and less efficient. Firebase NoSQL model doesn't have the same inbuilt support for complex queries, joins, and filtering. So you may have to retrieve data from multiple documents and then perform those queries on the client side. A second important difference is the pricing model. Both of them are free for the beginners. That is, you can get started for free. But Superbus pricing model is more flexible and cost effective than Firebase. Supervise. Paid plan charges, a flat monthly fee for unlimited users, while Firebase charges based on users and has higher costs for higher users. In the long term, if your application grows, annual usage increases. Then the third point is importing pre-existing data. We'd say pervasive. We can easily import a CSV or copy and paste a spreadsheet to kick start the project. This is great if we're migrating data from another platform to superbugs. Firebase doesn't offer inbuilt services that enable us to directly upload bulk data. You may have some third-party packages, I don't know, but it's not inbuilt. The next point is self-hosting. Many developers may want to self hosted app. Wait for security reasons or scalability. When it comes to self-hosting, Dan said is simple. Firebase doesn't allow us to sell, forced our app. Well, super business, we've self-hosting is important to you. Then Superbus is the better option. Then. The final point is no vendor lock-in. When you are using a cloud-based service, it's important to consider the potential for vendor lock-in. Vendor lock-in occurs when you become dependent on a particular vendor Forest Service, making it difficult or costly to switch to a different provider. So Bobby's gives us the freedom to switch to another provider at anytime without any additional cost. But this is not the case with Firebase. We're stuck with Google platform forever. So either we are allowed to self host from the very beginning, or suppose you get started with Superbus, but later on I wanted to change the platform that is also allowed in super base. So because of these reasons, I also believe Superbus is more friendly or is more suitable for people who don't want to risk taking Firebase database and get a huge bill for some code or for some mistake in their app. Because since there is no flat charges in Firebase is your expenses can increase exponentially. So that's it. Without wasting any more time on the theory portion. Let's get our hands dirty and we will start working on our flutter app in the next video. Thank you. 3. Create a new Project: Now it's time we get started and create a new flutter project. And I'm assuming that you have already installed flutter SDK in your system. Go to your preferred folder and write that command to create a new project. Create Superbus. I will, I will name the folder this. You can name it whatever you want. Let's enter. It will take just few seconds. Okay? Now, our project is successfully created. Simply I will write, I will first go to Flutter. That is this folded. Then write the command code space to open that folder in our VS Code Editor. You can see here we have all these files and folders. Now it's time. We create a new Superbus account and then use those settings in our flatter project to get it connected. Simply go to supervise.com like this and sign in with your account. I've already signed in. So now here you can see I don't have any project. So first, we have to create a new project. It will say your organization. So when you are signing in, you can create an organization as well. I will write down project name as flutter, super base. Use any password. I will just write generate a password. That's it. Then choose studies and which is nearest to you. I will just choose this one. And I will start with the pricing plan is free. Okay, Now, Create New Project. After creating the project, it will take two to 3 s you can see to build a database and we will get our API informations. So here you can see I have the API keys and URL as well. And you can get the same API details in this section as well. That is Settings page later on if you want, and go to this API in the sidebar. This one. Now, we will use those API key in the flutter app. And for that, I will use a dependency. Simply go to pub Dev here, right first, Superbus flutter. This is the dependency I will use to connect with dw is copy it. Go to your folder, then Pub spec dot YAML. And I will paste it here. Press Enter. The next package I want is called dot ENV. This package is used so that our passwords are sensitive. Information doesn't get compromised because it's not advisable to write directly in the UI. Just copy it and paste it. That's it. Now, both these two packages are installed. To use that dot ENV package in the root folder, we have to create a file with just the extension that is dot ENV. Firstname. Here we will write our credentials. I will name is super base, URL is equal to. And second is superb ways. K is equal to. Let's go to your dashboard again. You have this URL here, copy it, and paste it in the URL. Then again, go and see here you have public and on key. Just copy it and paste it in that key. That's it. Simply close the dots ENV you don't want it. Again. To make sure our application can access that dot ENV file. You have to mention it in the assets. That is go to Pub spec dot YAML. And below here in the line 65 you can see it is being commented. Simply first, remove uncommented. Here. Again, uncommon the first one. And right dot ENV. And always remember this pub spec dot YAML file is very sensitive. If you have any tabs or spaces mistakes here and there, then it will throw an error. So this is also done. Now it's time we initialize our app. So go to limb and main dot dot. And we have to initialize the Superbus client in our main function with the API credentials that you have copied earlier. That is, you have mentioned in that dot ENV file. Firstly, yes, Import super base package here. And so import dot e. And we did this not ENV slash letter dot ENV, like this. In the main function. Makes sure that you make it a sink. Then you have to write these comments that is rigids. Florida binding. Ensure initialization to make sure everything is initialized. First thing we have to do is load ENV. These await dot ENV dot load. This is the command given by that package. Then we have to initialize soup always. Simply first I will get super base URL, that is dot ENV, then ENV. And here I will add that key that is so base URL. And if it is null, just use this empty string. And URL is capital. These things will give error. Then paste it and I will add the variable names above is key. And this will be key. After that, simply await super base, not initialize it except cURL. We have that. And on key rehab that as well. Oh, okay. We have these things. It's time. We structure our project into folders. Instead of writing everything in that main dot dot file, simply go to lab, create a folder and name it pages. Inside it create two more pages. It is to move dot files Home page dot, dot and start page dot, dot. Like this. In the homepage. Simply import that material. Then stayed less rigid. And home page. I created this rigid within seconds by using some extensions here. So you can also add these extensions. Yeah, I really turn gap for then body, then const center. Child. Simply write home page. We will change these things obviously later on. So I'm just thinking why is this lines here? Okay, Let's leave it again. Go to start page import, my TTL, then date less rigid. Name it start. Then return, scaffold, then body, then center. I will again simply write the page name for now. It is dark page. This is N word, is it? Okay. But later on obviously we have to remove this constant. And now let's see what happens in the later videos. Now, everything is done here. Then next video, we will work on the authentication portion and the pages. That said, seeing the next video. 4. Setup Auth Screen: Hi. Now it's time we learn about user authentication in Superbus. Go to main dot dot file and remove everything below this, my app. Let's remove it. I will also remove these comments just to make it look clean. Now create a new stateful widget and name it. That is with stayed for rigid and name it art. Okay. Now, in this art page, we will show or redirect to the redirect the user, according to whether user is already authenticated or not. That is, we will just check if a user has already previously sign-in or it's a new user. So that's what I will do is here. Firstly, I will create a super Base Instance. It is blind instance. Suppose always supervise is equal to superhighways dot instance client. This is how we call functions provided by Superbus. After that. So purveys, gifts, our returns as a user. I will just have this user variable. Remember, this is coming from Superbus. I will just assign that to this user later on. And now here, I will just check if user is equal to null. Then I will create this page that is dark page. I have this page. Remember in the last video or else homepage. It's simple. It is. If user is already there, then directly sign-in, sign him to the homepage or else they'll him to login. Here. Make this page the home. And now our material lab. This is done. Now. What we will do is super ways, gifts, as few functions, that is, to get got into user. This is the command. So Bobby's dot, dot got into user. So nice. Command returns a user object. Okay, Simple as that. Now let's create the future function. Obviously. It will take few seconds. That's why this name get art. A sink. I hope you know all this basic concept is what is called this future. And because these are required for this course. Now here, I will simply state that is this user variable to that command, it is User dot, dot, current user. And here you can see, this gives us this user. If you hover over it, it gives us this user, it can be null as well as it can have value. And after that, what we want is, we want to listen. That is on our state change. Which simply means if the user state changes, that is, the user logs out or the logs in, our page will reload. That is, it might be again sent to homepage or the start page. Here. And here. Should we listen. This is the event. And now here we will mention set state. User is a call to event dot session dot user, and this can be null as well. So that is if it's neither, then simply assigning the null value. If you hovered over it. See, this is gaming as this user. So simply means to get current user. You can either use our dark current user function. There is this function as well. This session. From the session, you can get the user details. Okay? Now, I will call this function in the init state. That is, when this screen is being rendered, the first thing you, he has, this function has to do is call this. And after that, according to the user value, the screen will be returned. So we have this thing's ready. It's time. We run the application. And also I will just change it to the name to Florida Superbus. And I have the homepage as this art right now. Okay, let's make this constant later on. If we required, I will change it. And I will remove that debug binary as well. Now, you run this application. You can use virtual device, are also your physical device. You can connect via USB cable and enable debug, debugging in your mobile device. But I will just simply use emulator. Go up and Android Studio here more actions than Virtual Device Manager. I already created this device, but you can create a new device from here. And see I'm using pixel for API 30 and read 11. We'll just start it here. If your system is not powerful, I guess android Studio will make it slower or the Arctic will be laggy. Now you have your device here. And you can see in this VS Code, my device is now active. I will just run and start debugging. Time. It takes some time. So you have to wait and have patients. I would just like to say, suppose you want to know more about authentication, functions and terminologies, then you can go to the official site of supervise. Here you will understand more about the current users sessions and all. But mainly there are few things, only few keywords and I think it's a very plain English. So it shouldn't be that difficult to remember. It is taking some time, but I guess we have to wait. There is no other option. And see. I have this warning. It's not like app won't run, but I have this warning here that is to change the Compiler SDK version. So I will show you how that's how it is done. But if you are not getting these red lines, then it's fine. But in my system, I have the upgraded. But as you can see, it successfully build. I know it took a lot of time. I hope your system doesn't take this time. Let's see what which is rendered start or home. See, we have this third page here. So the app is successfully then in that is that Superbus is also connected and there is no added in it. And also I will just tell you how to solve this. Close. I'm just stopping the application. Then. Go to Android folder, then app, then build-up Gradle file. Here. You will see underlying 29. This compile SDK version. Not compile SDK version. I will just remove the flutter and right, 33. That's it. And save it. And now, simply go and redone again that they start debugging. And I hope you won't see any red lines or any warning here. I don't want to again, wait for this application to run. So see you in the next video. 5. Work on StartPage UI: Hi, welcome back. So you can see in the debug console that there is no warnings after we change, the compiler has decayed SDK version. It's time we work on the start page UI. This is the page where user can login as well as register. The first thing we have to do is make it a state full version. Because obviously we will be working with lots of states. And let's begin writing our states. The first thing is that super ways client instance. So Bobby's dot instance dot client. Next thing is we have Boolean value of E is saying in loading it will be false for the first time. And another is, is not, is I will just write sign-up load loading, like this, sign in loading, and here it will be sign up loading. This is false as well. Then sign in and sign up will require tax whales that I'm having. This text editing controller is the concept in flutter. And obviously e-mail is their password will be there as well. Bus controller is equal to x everything controller. Then we will use the form widget that we require. On key. These are just syntax. You have to remember that this low bulkier forms state the null. And I'll always remember to dispose the states that are not all, mainly purpose instance. And the decks editing and cooler soda, there is no memory leak. K, No, go below. And he had in body I will have this center. But in that child, that child will have the form vision and bomb will have column k, c. And one year is a mandatory value of K G, N here, since let's go and check it out. Yeah, Foleys there, okay. Constants should not be there. That's it. That was the issue here. Is it shouldn't be constant. No. We will use this properties of column that is the main exists alignment, mean exists alignment data center. Cross x is land, gross excess alignment center and not centered. I will yes, you stretch. And I will wrap this form. Which single child? Scroll view. There is no error when we're typing. That is when we're typing email, a password is no added. Saying that the UI, I just forgot the adder, but if you remove the single channel scrolling, you will get that. Let me show you later on. After this forum. In this column, I will give some padding of doing like this. The first thing, I will always get a network image. Simply go to Google Images and serge Superbus logo icon. I will just open image. Here. Are the glue. Let's copy image and just let's see if it's dot PNG or not. Know. This might give some because you shouldn't have a image where it has this extension. Let's copy this image address and base. This is my image. Just open that same image. And now like copy image address. Now if I paste it, see this has this extension that PNG. And I really gave. High height of 150. Save it. You have app running. I don't know what Stat Edit. Ok, There is some matter. It's three sturdy image that network is there. I don't think so. There should be some error, but I just restarted. Again. I will just change the image. We will get data and again, we'll use this image. B major dress. The, it's so funny that you cannot get a image. Man. And let's see, let's use some other stuff. I will just give some other widgets and later on genes that image, email field, password, friend. The next field. And I will just use some size box, give them spacing. And elevated button. Having a sign in. Let's see. Is there some added here? I will just stop it and run it again. We have this output here. The logo, two text fields, any sign-in button. I will also have a sign up button here, and I will just use divider. Be const. Then. Just have an outline outline button and child rearing sign up. That's it. So we have the scaffold and center bedding is there. Okay. Now let's decorate text form for the email field is coincide. I will use the validator so that we make sure that it is not being submitted. Empty. Value is equal to null. Value dot is empty. We will simply return, is required. Or else, if everything is good, just return null. That is, there is no validation error. Then we have the controller as email controller. Declaration. And put decoration. Label is equal to E mail and keyboard type X input type dot email address. Now go to bus for password field. We have now validator. If value is equal to null, and if value is empty, then return is required. Rl. So turn that controller, we have swirled controller decoration. Decoration, limit is equal to text, sword and obscured. X is equal to true. That is, the user shouldn't see what he's typing. Now save it. Check out our app and see it is looking decent. Obviously, this is not a UI course. Our focus is to learn the Superbus. In them. Next video, we will learn how to implement sign in or sign up functionalities. And Q. 6. Implement Signup and Signin: Hi, so we have our UI ready. Now it's time we implement this sign of functionality. So this Superbus instance has art, as you saw here that is in the main.out. The partner sign-up functionality. Syntax is like the syntax. Super ways nought, art, not sign up. And here we have to send email and password. That's it. This is the list index required. And it will return us session as well as user. Now, to implement this, our sign-up button is here. First of all, I will do is just check that this is sign up loading is there then const Center giant circular progress indicator. This is so that progress indicator or else Let's go to the on press and make this child constants. Now the first thing we have to check that is in the form is valid. This is valid is equal to bomb qi dot current state. Not dwell in it. The first thing we have to check is if it's valid or not. And if it is, if it's not correct, then just assign the value null. Now, we have an if statement. If is valid, not equal to true, then we will simply return from here. Or else we will send the State DOT. Sign-up loading is true. Yeah, we will showed a loading indicator. Then we will wrap everything in it, a try catch block. Now, let's try a weird super ways. Dot, dot signup like this. And here for the e-mail we have to write email controller, not text. And for the password, password controller node text. And after this, we will just for messenger, snack bar. Success. For automation. Email sent, background color, colors, dark green. And this can be const. And I guess this await. We have domain days on press Sync. After this we will send us data. Sign up loading is equal to false. That's it. Now, what if there is an added those careful messenger not of contexts that show snack bar cons. Snack bar x will we sign up failed? N background color. Color is red. A and we have to again set destined to false, that is sign up. Loading is equal to false. So here we are first trying to sign up my time, given us, given to us by Superbus. And then we are showing snack bar. If it's confirmed or if it is, if there's any added, then also we're showing the snack bar. Remember, Superbus by default, enables e-mail verification, which means that when using Superbus authentication with these settings turned on, your users are required to verify their email address in order for the accounts to become active. You can disable it as well going to the Settings option in the authentication section. Now, we have this sign-up method, return simply, let's write that sign-in as well. And after that, we will state. Similarly. For the sign-in functionality. This is the basics index that is super ways, not art, not saying in weak password like this. But this is this index. Here we have to give email and we have to give password. This is a syntax. Our sign in. Let's do it. Let's we have this elevated button here. Yeah. Make it sink. That is the Sign In button. After net. Lot of things will be similar like first of all, we will check if sign-in loading is true. Then const center child. Cool. Progress indicator. And after that, we'll do like buying a ligase. Again, copy as well. Why to waste time. From here to here. Let's copy everything. Stayed inside here. And now let's see check everything. It will say. And in loading. Similarly, this will be signing, sign-in. Then this will be say, in weight. Other things. So we say and we don't require this as it will directly go inside homepage. But here we just have to sign in. And that's it. So this is done and I hope it will work. We have successfully written the sign-up as well as functionality. In the next video, we will test the working of this functions and also the design now. Thank you. 7. Sign out functionality: Hi, it's time we test the functionality. Let's write email and password 12345 and click on Sign Up. See success e-mail, confirmation cent. So now we have to go to that Gmail address and click on conformation. Let's Gmail n. When you go to authentication section and reload. See, we have this email here and it is writing for verification. And here, simply, you have to click the Z-disc, confirm your email. And now it won't do anything. But if we go and reload the authentication section, see that verification is completed. Now, if we go we have the e-mail and password already there. Since we have not said that state are removed, those we can directly test assigning functionality. Let's click it and see. Homepage is opened. So you might be thinking, we are not navigating after sign-up, sign-in. That is, we have this sign in here. We are not navigating. But if we go to main dot, dot file, here, we are listening to the Art state change. And that is why it automatically send us to the homepage. Now, in the homepage, let's have a simple button to implement that sign out as well. Go to homepage. Here. Let's plus important NANDA material superhighways. And I'm now directly in the app, but I will have a button. Actions. Then I can button. I can be, I can not logout this one. Make it const. And to implement on press first BAA, a supervised instance. The batteries client base is equal to Bobby's dot instance dot client. Okay? That's syntax. Here. It cannot be const. Now to syntax for psi naught is again very straightforward. Relate superhighways, not, not sign out. That's it. This is the only called quiet. Now, after saving it, if I go to the app and click here, that is that logout button, it should redirect us to the start-up page. It is start page, let's say C. Now we are being redirected to the login page. So our sign-up, sign-in, sign-out functionality are working perfectly. In the next video, we will learn about a concept known as deep-linking. Thank you. 8. Deep link Integration: Hi, welcome back. In this video, we will work on that deep link integration in our app. So we have the email password authentication working. Let's set up deep links so that users who have logged in via magic link or external or not, that is, Google or Facebook can come back to the app that you will have to go to your supervisors account, that is Dashboard. Then click on authentication. I can then click on URL configuration. Here you will find this steadies, redirect, URLs, URLs that odd providers are permitted to redirect. After authentication. Simply click on Add URL and right io dot. Super ways that my app then colon double slash login. I find fall back, that's it. And then click on Add Domain. See, we have this redirect URL here. You can rename this my flutter app and this login callback. But I tried changing this thing that is io dot Superbus and it was giving me add a while redirecting. So if you want, you can try it yourself giving different different names. Now, the next step for deep linking is we have to add some code. In the Android and iOS folder. You can simply go to the Superbus documentation and read about setup the playing C. We have added this redirect URL here, they're using flatter Quickstart. I've changed the name after that for Android, added Android apps source and AndroidManifest.xml. So let's go there. Android app source mean AndroidManifest.xml. And below this IntentFilter, we have to copy this thing. Okay, just copy the middle one. Go there. And above here that is the closing activity. Just paste it. Here, change that scheme. That is your reloaded my app. And the host is the same, that is login callback. We have returned, okay. The thing we don't have to do anything. Now for iOS. We have to do these changes. That is key. Have to just copy this thing above the ending snare. Let's go to the iOS folder. Then. Run our info.plist file. Here. In this position. Just paste it. And again, change this string here. That is my lot app. That's it. Period. After these changes, simply stop your application. Make sure you save everything and then run it again so that those changes are reflected in the application. So that's it for that deep link. In the next video, we will work on how to implement Google sign-in in our app. Thank you. 9. Setup Google Oauth: Hi, to enable Google authentication in our project. First, we have to set up Google Art and get those credentials. So simply open your browser, go to cloud.google.com, then you are already signed in by default. If not, just sign in with their Google account after that click on Console. Now, I have this project already, but you may not see it. You might see here like select the project. Then click here. Then click on Create New Project at the top. Simply named the project, I will write its flood. The bulb is. Okay. Then click on Create. It is creating. Now as you can see, simply select the newly created project. Now, you can see here you are working in Florida. So poverty is the next step we have to do is create the keys for our project. In the search bar. Here, simply type or AUD. Click on consent screen. Then select that option external from user type. Simply lab external. Click on Create. Then simply fill out this form. I will just say that it is purveys support email. I don't have any logo. Domain. Simply here as well. I guess nothing else is compulsory. Click on Save and Continue. Now, the next thing you have to do is get find your callback URL. So we don't have to fill up the scopes and OwlTest users right now, simply go to Here Supervisor dashboard. Here. Click on project setting option, then select the option API. Now here you can see the project URL. Hit this one, just copy it. And then again go to the Google Console. Click on credentials. This option. Okay, yeah, then click the Create Credentials to choose OT client ID. Now, application type I will be simply choosing web application. Since we have Android, iOS, and web meeting. Now, name will be blurred. Super web client. Then this is important in the authorized redirect, URI. First base, this is the one you copied from the super base dashboard. Then at the end, remember to add these lines that is slash ahd dot v1 dot callback. This thing, you simply have to remember that. And then you have to write these lines so that it is redirected to our app. And then simply click Create. After that, we will get the credentials. Copy and paste the values here because you will need it later on. After that, simply go to authentication. So Bobby's because now we are and we will use those credentials here. Click on providers, then find Google. And you can see it is asking for a client ID and client secret. That's it. And see it redirect URL as slash v1 slash callback. Now copy this client ID. State here. Again, copy Client Secret state here, and click on Save. That's it. We have completed all the steps and successfully configured Google sign-in for our project. In the next video, we will work on the UI as well as implementation. Thank you. 10. Implement Google Sign In: Now it's time. Since everything is done, we implement Google sign-in in our flutter lab. First, let's create the button in the start page. After this sign up button. Simply the row. Then we have children. And that children. Some cliff first thing we will have is the expanded region. And within this expanded region, we will have a divider. We will have. As always, you can change the UI according to yours. For me, this is not a tutorial about a very good UI, anything like that. Gene sets that are child will read the text. And then again, I have this expanding saying, I just want this thing. But the user know that either they can sign in with their email or they can directly use will sign in. Here. You can just give it a const. And I will remove the earlier divider. This one. If you want, you can keep it. I just want this one divider here. And now. After this row, then playwright, outline, button, icon and press. Just keep it like that. Label. Should we then d mu with Google. Then in the icon, I will have image dot network. I'm simply using a network image here. I just wanted to keep it very simple. And also height of that image will be doing D. And simply Google any image. Then Google logo transparent. And I will just simply copy this image address and paste it here. Save it. See, it is looking decent. Now, to implement the Google sign-in functionality. First, let's create a new button. That is not button that is a Boolean. Google sign in. Loading is called the false, like this. Then go to this outline button and here simply write if Google sign-in is true, then as usual, show is circular progress indicator. And seeing that is already in the on-premise, make it a sink. And now we will write the code. The first thing we do we will do is set state. Google sign-in loading is equal to true. Then we have this try and catch block. This is a syntax, syntax for Google. Sign-in. Right away. Superhighways that art dance sign-in width, like this. Okay. In that provider, simply write provider. See you have lots of provider. I will use Google. Then they importing important thing is the way direct to here. We have to first do this check. That is k is web, this one. So at the very top there will be an important foundation dot, dot. That is, if it is web than just don't do it, that is don't write it. Rls. Use the use the redirect URL, which is io dot. Scoop always. My flutter, my flatter app. Login, callback, like this. This is, this was our writing I just remembered in Redirect URL order deeply and stuff. This is the only code acquired after that, simply in that drag, that is catch block, right? Scaffold. Messenger of context, not show snack, snack bar content. The next thing up, like this. If you want, you can change the background color is L colors, dark red accent. And set state. Google sign-in is equal to false. We have redundant code. It's time we tested. If I go and if I go to our authentication and users, here, I will just remove this user because I will use the Google sign-in with the same username. Now. Let's test it. Everything is saved. Yeah. Let's continue with Google. It is opening an account. Yeah. I will choose it. It should have read directed. Let us see why. Here. I guess we have the Google sign-in, but it was not redirected. Has to be some issue here. See, it should have been reelected here. K Phi restart here, nothing will happen. Simply go and remove this user. And in the leases provide a URL configuration. Let's see what happens if I remove this local host in the EU direct redirect URLs. Let us see. My guess. This is the correct one. I will just hit the deer again. Save it. Okay, let's try it again. Go to continue with Google. And see. I guess you were not able to understand what it was redirected to our app. But I lay there was this issue. I just remove that local host you localize from the redactor URLs. And right now everything is okay. It is working great. You can see Google is there? Well, yeah, that's it. So our indication is also completed. I hope you have enjoyed. In the next module, we will learn about how to use database in super base as well as flutter in queue. 11. Working on the crud UI: Hi, welcome back to a very new video. And now it's time to start learning about databases in Superbus. Superbus provides a web-based user interface that allows us to easily manage and interact with our relational database. This interface provides a variety of features for creating and modifying table managing data and performing SQL queries. So here you can see this SQL editor just go there. The thing is in supervise, you have to define your tables and columns in advance because you can start before you can start inserting data into them. This is because Superbus is built on top of Postgres sequence, which is a relational database management system. And it requires a pre-defined schema in order to store data. So here, simply go there, go to this SQL editor. Or if we go to database also see here, we have the same thing, new table. Simply click on new table and now give you a table, a name. I will name it to-dos. Now, I will uncheck this row-level security for now and enable real-time. Because obviously, we will learn about how to use real-time data as well. Now, below you can see that there are two predefined columns. That is id and create a created at. Id is real. Generate ID automatically and check this primary is. Now here. Simply click on Add Column. Then. Plus I will write title and give it text. That said. And second one will write user ID because obviously we have to store the user as well. And here I will use it. Next thing is, you can use it as a teaser as well. But supervised returns that user variable or the user ID as a string. That's why I'm using string. And later on, we have to do some changes, or you can say convert as well, that we will do it that time. So we have the column, we have the name and it will real time and then click on Save. Oh Kay. And if I go to table, well editor as well, see we have our table. It is to lose. Also. I am using this new emulator. That is, I have connected my real device because earlier Android Studio as lagging a lot. That is why. Before moving forward to learning crud operations, let's first work on some UI portions. Create new file inside pages directory. Then play right. Create page, dot, dot and dot, dot. Okay? So inside Create page the dad simply import material, then kill it. They stayed full rigid naming create page. Then the first thing we will do, as always, is have a boolean that is excluding is equal to false. And we will create it takes everything controller because obviously if we are creating something, there will be a next field involved. And I will name it Title. Controller is equal to x editing controller. Like this. Now, simply return a scaffold bar. I buy bonds. Next, create data. Then in the body by adding rigid bonds and insights that 15 and that child have a column. Let's have that children argument. And let's say X3. And also since only one texts release date, That's why I'm not using this form and I'll let this text form failed foreign key. Again, it's really simple. Like Dell controller declaration, Const, input, declaration, int x. The title and border. Let's give it a border is an outline in boot border. K. After that TextField. Give some spacing with the help of his sized box. I, then then elevated button, Create and make it const. Okay. We will have this create page and definitely we will see it in our device. But first, let's create our edit page as well. This similar to create page, but only difference is that we are accepting data and assigning the data. Text editing controller. Simply go here. Import material. Stateful, rigid edit page. Here. That constructor we will accept two things. Final string, data, final int, id. And then we will simply accept it like does edited this data set. That's it. Now, as always, the same thing. Boolean is loading is equal to false. Editing controller. Controller is going to do the x editing controller like this. And now in the init state, what we will do is we will as saying that I did data value to them. That token cooler, slag, rigid, small w, rigid, not any data like this. Now, after this, let's go to our Create page and just copy this scaffold. Scaffold. We have here. Now. It will be added data. They'll controller is there. This will be a date. This is a date. I'm just thinking. What can we done? Okay, Let's do it here like this. If is loading is equal to true. If loading is true, sorry, balanced, center, Jane, circular progress indicator. Or else I have a column. With that column, let's say children staying in the sidewalks. Weight, double-dot infinity, height. But I'm just creating the update button here. Nothing much. It's like just to give it the full width. Elevated button on press. And child will be gone the next day. Like this. Within this column. That is after the size box will give some spacing with the help of another size box. I then, and then a divider. And finally, another button just for that delete purpose. For that user can delete from this page only. Const. I can, I can start delete. This label can be const. Next, Delete. And thus style. Let's give but Dan style, background-color, my TDL, state, property, dot. These other code you have to remember this is not done by me. And save it. In simple words. The only difference between the two pages that we have a delete button as well here. Just save everything. If you want to check out that page simply. Okay, let's go to main.out. And instead of homepages, send it to create page and save. See, this is our Create page. And if we do Edit page, and it is asking for two arguments, string and integer. String and be hello. Integer can be two. If I save it. And checkout page. See, this halo is already returned here because we are assigning it in the init state. And this update is taking the whole screen. Then we have this small divider. This is the delete button. It is looking decent. Again, let's change it to earlier. That is the homepage. So that's it. In the next video we will work on the Home UI, as well as how to create, how to implement that create functionality, functionality. And Q. 12. Implementing Create functionality: Hi. Now we have create page and edit page ready. It's time to work on the homepage and create buttons to navigate to other pages, as well as work on the body of the whole. Very rare we will fetch and show that created data. So go to homepage. Here. Let's give it a title in there, but I will just write. By way is then endow very top. Let's import, create page, import, edit page. Let's start working on the body here. And we'll remove n. We will use a list view dot builder. I hope you know all these widgets because these are again the basics of Flutter. I **** gun. And right now I'm just showing some dummy data. And later on we will replace those data from the data coming from them. Superbus, item Builder, text, index, string, and data is equal to dummy data. And the index number. We will show these data string. Then return list style text. Data, then trailing. Let's have an icon button. And the icon will have const. I can, I can start an ad here, it will be I can start edit. And let's give it a color, colors, red. And in the on-premise, let's navigate. That is navigator dot push. On decks. In that loud inside my TBL page layout will there will be text and we will send it to the edit page. Edit data is simply not data variable and ideas that index. These are again just dummy. And the next thing we have to do is creative floating action button. Floating action button. Child. Const, I can, I can snot, add on breast. And from this we're done. We will navigate to the create bridge. Navigate their dot, push. My daily page, layout page in here. That's it. Let's save it and check out the app. See, it is looking very decent right now. No doubt these are dummy data, but it's very simple to just replace it. So since we have the UI ready now, it's time we work on learning that cred operations, starting with creating our inserting data in Superbus. So simply go to Create page. First. I will tell you some syntax. To insert a record, the syntax is very simple. We have to write that is superhighways instance, that this client instance. Then from, from takes us. What is a table name where data is going to be inserted? Here? Just simply, just e.g. we have users or you can say we have the to-dos. Then the command is straightforward, that is insert, insert. And this area. This is a second argument which takes data in the form of map, our key value pair like this. Suppose we have then some value, the mean value, then date, then value. Like this. This is the syntax for inserting. And suppose you want to insert multiple record at once. So simply insert by mentioning them. In an ad like this. Then similarly, there will be tight, there will be value delivery date like this. This is how we can insert multiple records at once. And now, suppose you have inserted this value and you want it to be fetched immediately. For that, what we can do it, we can use a variable that is theta is equal to await, like this. And at the very end, simply append dot select. Here. It will fetch the inserted data. That is, we will get the response in the earlier method that is directly with await and without using the select, it returns null as a response. That's it. That's it. So we have it. We have understood how to insert data. Now it's time to implement that create functionality. The worst thing, let's create a supervise instance that this soup base is equal to supervise that instance start client. Then let's create a future function. Insert data. Like this. The first thing we will do is set the loading through. Then we will wrap the code in a try catch block. Here. The first thing we require is to get the user ID. And this we can get from the art method that is Superbus, that art current user dot ID. So it is now saying that it can be null. But since we know that the user is already authenticated, we will have this operator because we know for sure that there will be a value. Now let's write that syntax. It is from todos dot insert. N. Value will be dy del, del controller dot txt user ID. It will we use that idea? Okay, here. After you do this, it was my mistake. And then I will simply navigate and pop. That is navigate, gate the pop. And now let's do that catch. Just for debugging purposes, I will bring data. Inserting data. Thank days. Sets state is loading is equal to false. And scalp for messenger not show snack bar content. Then things went wrong. Leg this cave. In that dispose my turn. Lets dispose that I tell controller dot dispose, supervise dot dispose. So there's sodium, there is no memory leak. Here. Simply do the using ternary just like const, Center, cooler, progress indicator. And the on-premise Calder. Insert data like this. That's it. Now let's test that functionality. If I click on yep. And now if I just write Barbies and click on Create, then it, then it, it was that navigated that pop was called. So let's go to the database and refresh it. See, we had the data learn supervised, we have the user ID. So inserting data is working perfectly. In the next video, we will learn about how to fetch this data and show it in our app. Thank you. 13. Implement Read functionality: Since we have successfully inserted data, now we will learn how to fetch those data. So power-based provides us select method to fetch data from a table. Simply go to homepage. I will just write the index to select data. And here it's very straightforward. It is super ways from table name supposed to lose and say left. So this is the method we will use. This will fetch all records from that day will cause you to lose. Also by default. So power-based will return a maxima of thousand rows. Obviously it's a lot of data. But if you demand more, this setting can be changed also. Also, this syntax will return all columns. That is suppose name for to address age. But if you want, but what if we require only specific column? Says that only the name of all the records. So here I will simply write here even in the select. So it will only return the title column. That's it. These, these two you have to remember. It's a very basic syntax. Now, let's write a function to fetch data. It will be a future, and it will return a list in the end. Let's name it the read data, and it will be a sink. It's very simple. Simply write. Final result is equal to await. Superhighways from to-dos. Not select that set and return that result. Nothing fancy. Now since it's a future in the body, we will use a future builder. First of all, I will simply cut this because we will paste it. The future will the future. Then it has two properties. Future will be read, data and builder. It gives us context, as well as a sink snapshot. That is, this is the data coming from the soma base. Now here we will firstly, if snapshot dot has adder, firstly, we will write if anything is wrong, return center child, snapshot dot, dot two streams. Simply directly write this. Here. I will return a const center child circular progress indicator. That is why it is in the loading state it is trying to fetch. We will have a loading indicator on that screen. And what if snapshot has data? Again, this syntax are coming from. The future will not regenerate. This is not far away syntax. If snapshot has data, suppose supervisor has returned something, okay? And there is no data inserted. In that case. I simply show a rigid where it is return and where it is written. No data, every label like this. And if the length is greater than zero, then return a list. View dot n here. Item count will be snapshot, dot data, dot length. That is how many they are coming. Just create those number of widgets. And item will learn. It gives contexts and index. Index it is. And now here I will return this list view will, okay? I will return it item. Within that item builder. First thing is I will have a variable called var data, snapshot data and that index. So you remember it is in the map. This is a map data type. Now I don't need this dummy data. Item count will be okay. I guess I have made this mistake here. I have to do list view will just remove this. Let us see what data is there. Now I guess everything is fine. The name of the column is title. And what we are sending is the, that is an index. It will be id only ID, not the user ID. Just remember, because id is the row ID which we want to add in and it is unique. User ID will be same for all his data. Kay? Let's see if there is, if there is any error or everything is working perfectly. Learn supervise, it is coming from the database. And there was a loading indicator as well. So finally, we are able to create as well as the data. In the next video, we will learn about few more things when it comes to fetching data. 14. Filters and Modifiers: Hi. In this video, we will learn how to filter our data. So our app fetches all the data. But in most of the real-world situation, we would only want the user to read his own data. Allows us to only return rows that match certain conditions. And also filters can be used with any other methods like select, update or delete as well. Those things we will perform later on. Now, let's read or understand some filters in it. This first one here we will understand is equal to this one, fetches all rows whose value on that stated column exactly matches the specified value. Simply. This then like this, that is super ways from. Suppose we have this table called users. Then here we will select, this will fetch all the users. But if we read.eq, it is equal. And that is a name column should be equal to this value. So it will fetch on lead that specific user. And this name is the column name of death row. And this is the value which should be equal. So this is equal to filter ND. Remember this equal to, well, we use a lot of time. Similarly, we have not equal to filter as well. It fetches rows whose value on that stated column doesn't match, matches this specified value. So here we can ask, suppose this is a syntax from users dot and E, q naught equal, say here, name, not equal to. Really aid. So apart from that particular row, it will fetch everything. Sometimes you may require, it depends upon your application. Then we have great there. Then filter will fetch all rows whose value on that stated column is greater than the specified value. So suppose you want all the users whose age is greater than 18. So the syntax is like this. From users. Select the above. I think I forgot to select statement here. Select. And this one. We select not GT greater than column name will we age? Value is 18, So those rows value wouldn't be getting in 18. And other fields that is greater than are equal. For all rows whose value on that stay date column is greater than or equal to the specified values. So just e.g. from users select.gt. Suppose there is a followers column and just bring or get their users whose followers are greater than 10,000, odd and greater than or equal to 10,000 deaths. It similarly, we have less than, that is LTE less than or equal to? I will just slide here. Less than as this d n less than equal. Similarly like LTE. You can just understand it with the same example. So a few more. That is column matches a pattern. So here fetch all rows whose value understated column matches the supplied by turn. And remember it is case sensitive. So this case sends Dave, we will write it like super ways for users to select. Like like here. We will write the name column and what is that pattern? Oppose. It should have lake, the edge e sub I had that name. The rock, it will fetch that name. I hope you understood with this example. And similarly, we have column matches a case, a case insensitive. If pattern. Here it will be nice to part ways. Users select. I, like here it is insensitive. If you wrote it in lower caps, then also it will bring that same thing. Like if you just said THE in the lower, it is not an uppercase, then also it will bring this row. Like this. There are more, but I will tell you last one. This column in is in the ADA, is in the array. So it fetches all rows whose value in that column is found either on the specified list of values. It's like super may start from users, select and then NOT IN. And underscore. Then status is found either under there. So whether that value is offline or online or offline, Same thing online or offline. If if any of these value is present, then bring it. Similarly, there are, there are few more sub, such as column contains, every element contained by value filter, match at least one conditions. You have. These things. You can read. You can read about others in the official documentation. Right now, our focus will be more on equal two. And then we have modifiers. There's work on the row level. They allow us to return rows that match certain conditions without changing the shape of the rows. Modifiers are everything that don't fit that definition, allowing us to change the format of that response. That is, ascending, descending limits and all these kind of things. Remember, modifiers must be specified after filter. That is, if there is any filter after that dot modifiers. And let's, let's understand modifier. Here. It simply changes the order of response. It's super ways, not from users. Select. Here, we will add dot Order ID column as sending. Sending shouldn't be false. So by default, ascending is true. We can make it false. And then it will come in the descending order. And then we have limit that query modifier. It limits how much data is coming from. Users. Select limit. So bringing on new one data, or suppose you want to end it as analysis like this. It's fine like this. You can understand it's like a few more. Retrieve the query as one row and all, but those are not necessarily, these two are necessary for now. So it's time to apply what we have learned in now, about three dozen modifiers. Earlier in our app, we're fetching all the dub, but now using a filter, we will fetch only the data uploaded by a particular user is authenticated. Also, we will change the order and show the latest died the top. So first let's write master. And one more. Let's try to understand where you might be thinking why it is not showing because right now we have to refresh it because it is not real time. See, now, after restarting, it is showing us the three data. Now here we are in the future. Here in the future function, simply after dots select right dot equal. Column name is user ID. And user ID should be equal to super highways byways. The current user Id, like this, and order should be ID. Ascending is equal to false. Now, if I save it, it has changed. Now. We have all the latest data at the top. I hope you have learned a lot today. In the next video, we will work on the real-time functionality in queue. 15. Implement Realtime Database: Hi. Now we're able to add data, but the user has to restart his screen in order to reflect the changes. It is not a good experience. So we will learn how to use streams instead of futures in order to show updates in real time. So what is syntax first, let's show you some syntax that is real time database. Either you can use directly that they supervise. Dot from there we'll name is user, suppose then stream, stream. And remember that stream takes a list of primary key columns as its argument. So it is necessary primary E, and simply write ID. Okay, here. Then listen. And inside that listen, it will give us a list of data and you can do whatever you want with that data. Do something, okay, here, inside, inside you, you can do something. But what if you want to listen using stream builder? So using stream builder, you can then directly assign it here, like this. Suppose stream, a stream is there. Let's trim. Argument is there. And here you can simply write superhighways that from users stream. That's it here as usual, primary key. In this case capital. Just, I don't want to mess. This is the syntax. We will use this syntax because we are using StringBuilder. If you want to listen directly the suppose in the init state as well as well, then you can implement the above these to15 line. The first thing you have to do is no doubt we can directly write here. But I will just make it state full rigid. And here I will write a variable stream and lead because I will assign their value in each state. And it has this list of dynamic value. And we'll just write read stream like this. And then in the init state, I will do read stream is equal to supervise dot forum. To lose stream. See primary key in there asking, I will write ID. Then dot equal column is user ID. And value will be supervised or not current user ID. And similarly we have modifier filter column. Will we ID ascending false? That's it. We have this string. And now we will just change this to three millimeter. This will be stream and this will be read stream. Like this. That's it. Just restart. Now, let's check if it is working or not. Now, if phi sine n, right mass, what is left? Okay, I had this issue with the physical keys. This is not an error, it's just a keyword either. Nothing else. We'll just do it like this and click on Create. Then see, eight was updated automatically since we are using streams earlier, we had to refresh or restart the application. Obviously, this is more user-friendly. And most of the applications will require stream slag messaging apps or anything like that, notifications and all. Well, I hope you have enjoyed learning about the real time database. In the next video, we will work on updating and deleting our data. Thank you. 16. Update and Delete functionality: Now it's time we'll learn how to update an existing data. The supervisor provides us, update my turn and should always be combined with filters. Let's go to edit page. Here. Let's learn about update functionality. So syntax is either you can right away start from day one name. Suppose users dot date. Now here, send that data. You want to update this in the form of a map. Key value, that is name. I want it to change to Elon Musk. And the next thing you have to write this match, because here we will add the condition of which data to update. So id should be equal to ten. So update the data. Whose ID is this? Odd? You have another syntax. To update. You can use any of these two users update. So this is the same name, updated to elan Musk. But instead of match we will use equal. That's it. And here it will be like ID, calmer than not in the form of map. Just remember this is a difference between the two syntax. So whichever you like, use that D because you might be confused later on if you see any application code and you will think, okay, We learned only this keyword, how this is being used. That is why. Now simply implement this in our app. Here. First thing, have a supervisor client Function. Future wide, it doesn't do. It is not returning anything. The data sync. Here I will write if title controller dot text equal to null, then if it is not equal to null, then only perform this set state. Is loading is equal to true. Catch. In that dry simply right away. It probably is not from ruse. Not update. The value is del update the title value. Del controller dot text and match. What we have to match. Id. Id is rigid dot ID like this. And after it's done, simply Navigator, not pop. We'll just pop it nothing. Since we are using streams, so it will definitely get updated on the real-time. Here. If something is wrong, is a is equal to false. And scaffold messenger of contexts, dots, show snack bar, will write something went wrong. And we will check if that is what is the header. Ok, save it. And also I will use the dispose function. They do controller dot dispose. This is a good practice that soy or less, it's not required for this dummy project. But always we would like to do the best thing. Now, within this update, simply on the on-premise, assign the engine, that is this, and save it. Let's test the application. If I go to the third one that is master flatter. And they muster flutter and that and click on Update. See, nothing happened. Let's see if there is any error. The bulb is dot todos dot update. I think it should have updated. Eid early title controller dot decks match. Let's see our data. Okay. We have master Florida and dart here. But why it was not updated on the real time? If I refresh it, it is there but it should not be the case. Update function is working. Let's try it again. Update. Say okay, now it's working. I didn't get on a very small glitch by mistake, modified master flirt programming and updated. It is working flawlessly. We have understood the update function as well. Now the only thing to learn is how to delete data from Superbus. Superbus provides us the late my third as well. It's very simple like the update method and should be combined with filters. And we can use either match or equal. So what I am saying is suppose we have this delayed functionality. Syntax is straightforward. Super ways from users not delayed. And then make sure you have this match or equal. Though I have this match here, id is equal to ten, like this. Let's implement a delete functionality. I will simply copy this, update and paste it. I will write delete. I don't require this if statement. Let's state is loading should be true. Here. Await, shouldn't be. Delete. It is a weight Superbus from todos dot delayed. And directly we have this match ID. And we will have, after that we will pop. Or if you have any fungi error, maybe they show it in the snack bar and just assign it in the elevated button. Daily data like this, then place save it. Let's test this as well. I will remove that first one, mastermind stack. It is now being removed. If we go to our database data, for data, if I refresh, there will be three. So we have successfully understood how to create, read, update, and delete data. I hope you have enjoyed learning till now. In the next video, we will learn something new. They lend a practicing. 17. Enabling Row Level Security: Hi, Welcome back. Today we will learn about a new concept which is a row-level security, also known as RLS. Rls is a security feature that allows us to control access to rows in a database table based on a user's identity or a role. In Superbus, we can use RLS to restrict which rows of data a user can see are modified based on predefined rules. Until now, anyone with the public API key had access to our database. Also remember that default behavior after enabling RLS two-way table is that ate dinner, it denies all access whether user is authenticated or not. Until we mentioned our policies. Each policy is attached to a table and their policy is executed. Every time a table is accessed, you can just think of them as adding a where clause to every query. The table can have different IRLS policies. Maybe you want some table to be producted, some maybe not. So it's up to you which table you want to give access. So that's enough for the Curie. Let's enable it. Go to Superbus dashboard, go to our cation. Then you can see here policies. Then here it's mentioned RLS is disabled. So just click on Enable RLS. Oh, okay. So now if we restart our app, then we will find that there is no data showing. Let's see, see no data available. We have to write policies. And policies basically allows us to specify who has access to what data and what actions can be performed on the data. We have to write policies for all the crud operations. That is create, read, update, delete. And it is very simple. Click on new policy on this to-dos table. After that, you will get two options. We will choose get started quickly option for now. For more advanced option, you can see it later on as well. Simply click here. Then. It gives us for policies. But first of all, I would like to tell you what policies I want to have for this application. That is, for our todos app. Plus this, users should only access or read his own data. That means user ID column in super base should be equal to the idea of the person who is sending the request. That is the first thing. Secondly, all users should be able to create data if they are authenticated. So when, when it comes to insert, inserting, everyone is allowed. Just that day, they must be authenticated. And now for update or delete, users should be able to update or delete his own data on lead that is, just like that. Read policy. User ID column should be equal to the idea of the person who is sending the request. That's it. Now, again, back to this template. It gives us four options. First is and it will read access to everyone, then enable insert access for authenticated users on. Today's enable a bit access for users based on their email and 40s. And he welded delete access for users based on their user ID. We will use this, that is access based on user I did this template we will use and modify it for our convenience, simply use this template. Now. It asks us for things. First is policy name. I will simply write enable, read access for users based on user ID. Then. Allowed operation, I will select this one. And remember if you can do, but you cannot do two things. That is here, only one at a time. Then target grows, just leave it to default to all, since obviously the user has to be authenticated. Now, using expression. Each should, we ought dot ID equal to user ID, okay? So this user ID is that column name, and r dot ID means the person who is sending the request. Now, if I try to click Save, then it is showing an adder fail to create function. Odd ID does not exist. It should not be like this. And also there was another error as well. But wait, I will do it again. See here if same thing if I write, read access. And if I just selected this. Now if I write, review, safe policy and now see to create operator does not exist. You, UUIDs go to Tech since, since we have mentioned user ID, this value as text in supervised, remember that is, its value is text. So either you can change that column type two integer, or make this change just to make sure it will work like this. Now if I click on Review and save policy, policy successfully saved. So enable read access for users based on user ID. Let's see if our app is working or not. Now, we can access our own data. We have successfully. They tend to read access policy for our database table. In the next video, we will simply write the policy for insert, update, and delete. And Q. 18. Writing CRUD policies: Hi. Now we have to mention that policy for inserting. And for that, we will again go and click on new policy. Then get started quickly. And here we will choose the template, which is then we'll insert access for authenticated users to only use this table. Here. We don't have to do anything else. Then click on Review and safe policy. That said, we have read, we have insert. Now or update. We will again use the access based on the user ID, that is this template and date for users. And here I will click on update. It gives us another field which is, which will be same. And again, as I said, since it's string, I have to convert it to UUID and copy it and paste it here. That's it. Simply it means any update on the users based on their user ID. Review, safe policy. Okay. So now for the last one, recon new policy, weekly or delayed. Now it is like enable access for users based on their ID. Use this template. Everything is okay. Simply this one. Remember, this UUID you don't have to write if you have mentioned the column, that is the row names or the column as integer not string in the database. That's it. Delayed K. Click on Review and safe policy. So we have all the policies when Chen, right? So now our app will work perfectly fine. Row-level security is a very basic thing, but very, very important. I hope you have understood that when we're building a real-world applications, these are all the features, are all the necessary. Security is we will need in our application. So that's it. For this concept. In the next video we will start working on. So power-based storage, enqueue. 19. Storage Configuration: Hi, welcome back. So we have learned about authentication databases, row-level security. Now finally, it's time we understand how to use storage in supervise. In today's world, content is king. Then you look at social media apps or e-commerce everywhere you will find these images and videos. So it's time. We also learn how to upload files to our storage. The first thing we have to do is create a new bucket. Here you can see bucket is a container in which files are stored. Each bucket is associated with a unique URL, which can be used to access the files within them. Each bucket can have its own set of permissions, allowing you to control who can read and write to it. Just like RLS. When you upload a file to a bucket, it is automatically given a unique URL which can be used to access the file anytime. So just click on Create bucket name. I will simply write user images. Make it public so that we can access it later on. And also we will mentioned securities as well, so there won't be that much issues. So now we have this user images. What we have to write policies as well, just like we learned in database sex and about policies or bucket also, we can set up permissions that control who can read and write to them. E.g. you get, you could set up a bucket that is only accessible by authenticated users or that is open to the public. I additionally, you can set up violation policies that automatically delete files after a certain period of time. Now, click on new policy. You will have this simply click on new policy. Then we will use the get started quickly. And it gives us five options. Allow access to JPEG images in a public folder. Give you the access to only their own top-level folder name. As UID. Give users access to a folder on lead to authenticated users. Give access to a nested folder called admin only to a specific user. Give access to f phi to a user. We will use give the give users access to only their own. That is top-level folder name, this UUID, it is UID. Use this template here. First of all, select everything. Here. I'm sorry. I'm doing a really silly mistake again and again. But the next thing, then, user in wages, taxes, done them in a real safe policy. So what it means is there will be a folder created inside this bucket. That is, every user will have its own folder. You will understand it when we start uploading images. Now, we have to install a package as well. Go to pub.gov and write file picker. I pick this one. Simply go and copy a dependency. Go into Pub spec dot YAML file. Below fluid dot ENV. Simply paste and save. It is taking a little bit time. We will keep though. It's done. If if required, you can restart our stop and run your application, but I don't think so it is required. And also for Android there is no configuration. But if you are using an iOS device, you can just see the documentation here how to configure it. But for our device, that thing is acquired. So that's it. In the next video, we will start working on the upload functionality. 20. Implement Upload Functionality: Hi, Let's get started on the upload screen. Create a new file inside pages and name it. Upload. Page dot, dot. Start working on the UA. Import material inputs, superhighways, Florida. In board. By now create this state full vision. It could we just name it upload, age. And now calf as guns, Superbus, storage. Then body. For now, just leave it with the container. Then floating action button. Floating action button. This button will be used to add photo icon. I can start and a toll on press, just leave it for now. And then that very top create a state for loading. Unloading is equal to false. Now, go to homepage dot.in the AB bar. Create a new button to upload images. Here. I will have a new button as I can button on place. And I can be I can upload file. And it should be gone as always. And in on-premise, just navigate, navigate their Bush. Material it out. And upload page. That's it. Let's save it. And check out our app. It's still saving. Okay, we have this icon. If I click on it, see, this is the storage page. Now it's time we work on the image upload functionality. Supervise gives us upload function which accepts two arguments, was that filename. And also we can nest and mentioned the folded structure where we want to store it in Superbus in that argument. Second argument is the file which we want to upload. Let's go let's go to Upload page. Yeah, First thing in board, not IO. Then create Superbus instance, client instance, like this. Then create a function. Future. Upload File Sync. Now posting we will do is use the file picker library. File is equal to await. By big platform. Not pick files allow multiple, multiple falls and they will be dot image. We will use the File tab is image for now, obviously the same way you can upload any file. Now, we will write an if statement to check if the user has choose any file or not. If the file is not null, then only the state of uploading to true. Then let's have a try catch block. In that drive bus. It's heavier. File file is equal to, we have to convert it into a file object, file dot files first dot path. And it wouldn't be null since we have the if check. Then you might be asking white first and all because it gives us the list of files and we know we haven't allowed multiple, so just choose the first file, That's it. Then String name is equal to big file, dot files. Dot first name. Then string upload. Uploaded URN is equal to await. Now this is the syntax super ways storage. Not from our bucket name is user images. Then here, who's the upload function? And it is asking about depth bat. So remember, we have to create a folder by the name of that user id. Simply re I hope you remember that we are in the policies we have written like that. The supervisor is not art, not current user ID. Then have a slash and then filename. Like this. And this is a file already taken. Now if you want, you can just print uploaded URL. And then I'm just doing set state is loading is equal to false, is not loading, it's uploading. Uploading Isabelle to false. And scaffold the messenger of contexts snack bar that I file uploaded successfully file uploaded. Sexes fully. Background color, color is dark green. And just make it the constant. And in that catch, just say print. For now it's debugging. And we'll print ad. Set state is uploading files. He's uploading musical to false. And similarly in scaffold, something went wrong. That's it. Now, K Yes. That's desktop application as well. Okay. I have not assigned it. Let's go to upload. Our function name is upload file. San it here. Now, if I click on the button, I'm just thinking what is the added here? Now my data is there, but also in the Floating Button. F to do if is uploading is true. And cons that goal. Progress indicator. Save everything, try again to see what is the adder exception through missing plug-in hockey, let's stop our application and restart it. So I have already started my application. Let's test it again. Click on the button. Now its supply base is asking, we can allow just once. Then use this image and save file uploaded successfully. Now let's go to our supervisor dashboard. Here. If I just reload it, you will see we have this user image. And we have this image here. And this is the name of the user ID. That is, this is a folder of the user ID. So I hope you have understood how we can upload images. Just pause the video and understand our try to understand the code. This is simply a basic thing. The first, since this upload EXE file, datatype debt, why we have converted it in file. Then we have the filename, and that's it. In the next video, we will patch the uploaded images and Q. 21. Fetch Uploaded Images: Hi. Now it's time we fetch the uploaded images into Firebase. We can use the list method of the storage dot bucket function to select All files within that folder from him. Bucket list method returns a list of files in the bucket, which you can then iterate over to access the individual files. So just for the sake emulating the syntax, syntax to fetch images. It's simple like this. Final list File object. Results. Suppose here a weight. So Bobby's dots storage. From then, from images, that is, this is the bucket name, dot list. Okay? You can just slide bucket name here. Bucket name. So remember, we can mention the folder name inside this list by passing an argument called Math. So as in our example also, we are creating folders by user ID. So we will use that. Let's dark and write def function. Create a new function. My name, get my findings. Final list. File object. Result is equal to await Superbus. Superbus naught. Naught H. Naught from user image is dark list. Okay? So this is the air, but obviously you have to mention that folder name. It will be super res dot dot current user id. That folder name. Cave. Now, also, just remember this result doesn't return the image URL. So here, what I mean by that is wait. List, though I will just write bar item in result, print item. Okay, let's try and do it. Let's see, move everything from the console. If I click, obviously I haven't called the function. I don't think so. We have init state here. Okay, let's put a dummy purpose. Let's do the init state. Get my files. Now, if I go to the page, then we have instance of file object item C. This is what it gives us. Bucket ID, buckets curated, metadata, name like this. But it doesn't give us the image URL, so you will get the name, you can get the name, sorry, id and name, as well as metadata as well. So if I restarted. Then you will see ETag size, cache control. Everything is the ad rather than the image URL. Now, for that, supervise gives us another function that is to get the public URL. I will show you how. First I will create an empty variable, which will be list of string. My images like this. Then it may change. In result. We have by now, you will get URL is equal to. Now here. From here we're supervisor is not from, not from user. Images. Dot get. Let us see what's going on. Okay, I forgot that storage. What the silly mistake. Dot user images get public URL. See. Now it is asking us for that part of that image bar that we have to. Firstly, the folder that is so pervasive, dot, dot current user ID. And also if you want, you can use some state management like provider and get this idea and all stored there. Right now I'm just making it a very simple way. And remember we get the image name. So it's like image dot name, like this. From this, we will get the URL which can be used to show innovation. Okay? And let's see if it's the future or not. No, it's not the future. So I can just remove that weight. And here I will add these information in that above at EMTALA. First thing I will also store the name so that it can be used later on to delete, delete purpose. And URL is going to do and get the URL like this. And finally, I will return my images. And also if you want, let's first print if it is working or not. My images variable. And let's see, I'm just going to that page again. And see image name is this, URL is this. So that means we are getting the information. This is that public URL. Now it's time we showed that images in that UI that is here in the body earlier it was just a container. This will be changed. Now let's write future builder. Your chair. We have that future and get my files. Context, a sink snapshot. Snapshot. Now, if snapshot dot has data, then do something else. Return is circular progress indicator. Indicator. If snapshot has data, first, let's check if. Snapshot. Data. Dot length is if it's equal to zero, that is, no image is uploaded. Then return bonds, center text, no image labeling. And if this is not that case, then return. Let's do that. Widget. And remember, you can use builder as well, but I am using another widget known as separated, so that between all the elements, I have a separation of, that is, I have it divided as a separator. This is one of the widget in clutter. I bill that is there, but I will first write. Separator will learn. It has texts and index as well. We'll just return a const divider like this. Thickness to color. Color is dark black. Like this. Then item we'll learn. Again, same thing on the next index. N. I will get the data map image data snapshot data index. I'm just storing that map value here from that list one by one. And return a row, which mean excess elements remain accessible. And Mendota center and children will have puddings. First is size box. Here. It will be common. The box, this is, this will be the image. I'm just giving it the height. It doesn't expanse to all or less sticks or have any issues later on. Image dot network. Now here, lead image data, URL, box, dot cover. And after this sized box, within that row, I will have an icon button. I can will be I can snug delete colors, red, 0, key. And I will remove this init state for now. I hope everything We'll work. Jed is, let's check out our application. I'm clicking on that button and see we have the image showing up in our app. I will just give a padding to this list view. That's it. By adding will be const, edge insets dot symmetric. What they can. Then like this. See, this is our image. I hope everything is okay. Let's upload another image. Let's see. I will use this virus. See, we have this divider as well and we have two images here, which is looking awesome. We have done the portion of fetching images as well. In the next video, we will work on this delete button. And then we have done everything required to learn in Superbus. Thank you. 22. Delete Image Functionality: Hi, welcome back. So now let's work on the delete functionality of the storage. In superhighways. We have DUS, remove my tech to delete a file from the bucket. So just write syntax to move by its very basic slip final list object. So it returns us that deleted file as well. Super ways, dots, Storage, bucket, name, dot remove this, remove x and add a parameter with the filenames inside this image, one dot PNG, like this. And also, if we want, we can mention the folder name here is a hair as well. In our case, it will be done and user ID. Let's create it. Here. I will remove the print, will be future void. I don't want to return anything which are wide, delete image. And it will take string name, that is the image name. Let's type the try catch. The catch block. Yeah, that's right. Super ways. Dots, storage dot from user images. Remove. Yeah. You have to write up part. Part will be super a's are not current user id plus and image name. You can use string interpolation as well. But right now, let's see if it's work or not. Then I will just send data, refresh the page so that our future will die. Shows us the latest images. And if is there any error, then contexts, snack bar, simply write something, went wrong. That's it. We have to use this function to call it here in the icon button. Like garlic, image name, image name, and it will be name. Yes, we gave it a name. Let's do it. Let's save it and spring out our app. We go there. And if we did this supervise, if I click on it, see it is now being deleted from the storage as well. So if I refresh it, Let's see, I think it will be the movie, yes, only one image is the edit is for. Our delete functionality is also working perfectly. In simple words, we have that complete application, just see, just tested. Finally, if I do this, then I will simply projects. Now, let's click on Create. Insert is working. Then we have real-world. And if I change it to black, it is also obviously it's wrong, but it's working. And then go and delete is as well. Have deleted it. This is the crud operations are also arena have learned about the row-level security as well. We have done authentication as well. And again, if I go and upload it. So as you can see, the upload is also working perfectly. And I will just sign out. So thank you for being the Lee and I hope to see you in my future courses as well. So till then, just keep working hard and keep practicing.