Build a Google Docs Clone with Flutter, Node js and Mongodb | Rahul Agarwal | Skillshare
Search

Playback Speed


1.0x


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

Build a Google Docs Clone with Flutter, Node js and Mongodb

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:06

    • 2.

      Create a new project

      4:07

    • 3.

      Design Login Screen

      15:57

    • 4.

      Setup Google auth for Android

      5:26

    • 5.

      Setup Google auth for IOS

      6:32

    • 6.

      Setup Google auth for Web

      5:26

    • 7.

      Create auth repository

      6:44

    • 8.

      Assign the Functionality

      8:32

    • 9.

      Create a Node js project

      6:59

    • 10.

      Creating an Express Server

      6:08

    • 11.

      Establish MongoDB Connection

      5:56

    • 12.

      Create a Signup route

      5:21

    • 13.

      Model User Data

      4:26

    • 14.

      Test Api with Postman

      8:19

    • 15.

      Creating User Dart Model

      8:08

    • 16.

      Call Signup Api from Client

      10:09

    • 17.

      Test the Sign In Functionality

      6:48

    • 18.

      Create Auth Middleware

      8:54

    • 19.

      Route to get user data

      4:33

    • 20.

      Store Token in Shared Preferences

      6:33

    • 21.

      Check Auth State

      11:43

    • 22.

      Implement Routemaster package

      7:59

    • 23.

      Sign Out Functionality

      5:11

    • 24.

      Route for Creating Document

      10:41

    • 25.

      Document Repository

      11:12

    • 26.

      Function to Create Document

      8:45

    • 27.

      Fetch all my Documents

      11:22

    • 28.

      Document Screen UI

      7:06

    • 29.

      Flutter Quill Text Editor

      5:16

    • 30.

      Method to Update Title

      7:11

    • 31.

      Get Document by id

      7:49

    • 32.

      Establish Socket Connection

      13:18

    • 33.

      Realtime Collaborative Editing

      15:15

    • 34.

      Implement Auto Save

      6:37

    • 35.

      Copy link to share

      4:28

  • --
  • 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.

12

Students

--

Project

About This Class

Are you ready to take your app development skills to new heights? Join us on an exciting journey as this course will guide you through building a Google Docs Clone, a cutting-edge app that enables real-time collaboration and document sharing.

In this comprehensive course, you'll dive deep into the world of Flutter, the revolutionary framework for building beautiful and responsive user interfaces. With Flutter as our frontend, you'll learn how to create stunning and dynamic app screens that captivate users and provide an exceptional user experience. But we don't stop there. We'll delve into the power of Node js and MongoDB, creating a robust backend that seamlessly handles user authentication, data storage and real-time updates. We will learn to harness the potential of Google Sign In functionality to provide secure and convenient access to your app, and leverage Socket IO to enable users to collaborate in real-time.

State persistence is crucial for any app, and we'll equip you with the knowledge to implement token-based authentication and store them efficiently using Shared Preferences. Managing app state is a breeze with Riverpod, a state management solution that provides scalability and maintainability. You'll gain full control over your app's state, allowing for easy expansion and future-proofing.

Upon completing this course, you'll have all the skills necessary to develop cross platform applications with build custom backend. That means no more relying on Firebase all the time.

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: Intermediate

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: In today's fast pace world, real time collaboration is key, introducing a groundbreaking course that will empower you to build a cross platform Google Docs clone from scratch. Using the power of flutter for the front end and leveraging no GS and Mongo before the back end, this course brings together a robust technologies tech. You will learn to use socket IO to harness the true potential of real time updates, enabling users to work together, see changes as they happen and collaborate effortlessly. Furthermore, by implementing Google sign in, you will provide your users with a secure and convenient way to access your app. Also, state persistence is crucial for a smooth user experience, that's why we will dive into the implementation of token based authentication, securely storing them in shared preferences. And the best part is, you will get the knowledge of implementing River Port, which is an efficient state management solution. Whether you are a developer trying to take your skills to the next level or an entrepreneur planning to build a next tech chant. This course is designed for everyone. So without wasting any more time enroll now, and let's get started. 2. Create a new project: Hi, welcome to the very first video of the course. We will build a Google Docs Clone using Flutter, no JS, Mongo Db, and socket AO. So let's get started. I'm assuming that you have already installed Flutter S DCNO system. So make sure you have done it. Simply to check, you can type flutter version like this. The setup is very straightforward. I am using the version 3.10 0.4 for this application. The first thing we will do is create a new flutter project. So go to your desired directory and open a terminal, and then write the command flutter, create Docs clone. You can use any project name. I am naming it ToxClo. Then you can see. I have this project. Now, open your favorite code editor. I will be using VS code, then open the folder. This is a dog's clone. Okay. So here all the files and folders are present. I hope you know the basics of flutter because this is a project based course, not for absolute beginners. Now, instead of running this default application, the discounter application. We will create a login screen. Also, we will structure our project into proper files and folders instead of writing everything in main file or directly into files here. So inside folder, create a new folder and its cras Inside screens folder, create a new file login screen dot dot. This will be a stateless wage. First of all, import material then create a staless wage like this. Name it login screen. And I am using these extensions, that is some pltter snippets by Nevash then Dart Data class generator, then flutter report snippets. So make sure you have these extensions in your VS code. It will be very helpful. So, this will return a scaffold. That's it for this video. In the next video, we will continue working on the UI of this login screen, which will be very simple, and then we will run our application in mobile as well as web device. Thank you. 3. Design Login Screen: Hi. Let's continue working on the login screen. Inside the scaffold, have a body tag, then give it a center. In the center, we will have a column vigid. Now, what I want is in the column, at first, I will show an logo, then give some spacing, and then a button, which we'll simply write sign in with Google. And it will be an icon button. Now the children. First, will be image network. I will use a network image. If you have your own logo, it's up to you. I will just simply go to Google. I will write Google logo. Let's see what. So S here, we have There's logos. A lot of logo. I guess I used to like one, but now I'm not able to find it. Obviously, you can't take any of them. It's not a big deal. Let's see which one is transparent as well. Okay. Let's say this one y. This one is transparent. Let's say I will just write copy image address. Then I will paste it here, but this is not a PNG. This is. Let's see what happens here. I will give it a height height of 150. Also in the main do dt file. Let's make the login screen, the home screen. I will remove all the default my home page code. Then the home git I will const login screen. I will give the title as Docs clothe. Then the bug banner. Let's remove it. In that theme, I will just change the color to base blue. I don't like the purple one. It's up to you. It's all personal preference obviously. Okay. Then I will start my Android emulater. And then start debugging. It will take a few seconds or minutes I believe because this is the first time. Also, I would like to say recently, I have started working on custom back ends like no Jas Mongo. Earlier, I was just using firebase all the time. But now I believe firebase is not suitable for companies or large projects. For your MVP, it's okay, but I don't recommend it. Let's see. Okay. We have the logo here. I will just make it center main axis alignment center. Then give some spacing sized walks, height hundred then. Then I will use a filled button icon. Label will be constant text sign in with Google. Now icon will be image network and its height will be. Now for the network image, I want a Google image. That I will simply write here, Google Logo circle. Now, this one looks okay. Let's copy mage address. Paste it here. And save it. What was the error here? Image network? Yes. Things are fine. Oh, what is the issue? Let us say Some kind of error. Why copy this image. So see, obviously, this is not looking very good. That's why I was using some circular. But it's up to you. It's not like very serious thing. I'll just check one more time. This will also not look good. Man this is. T Okay. M. Lastly. No. I believe I know this doesn't look good. Yeah. For the, let's have. This is decent. You can change whatever image you want. But right now I'm just focusing on the functionality. I know this took a lot of time. It should not, but still maj address pasted And yep. Now, this circle the best. Among all what we tried. Okay, so we have the height. This one, 150 is there. Then this 130 is there. Okay. That's it for this video. We have the basic I done. In the next video, we will work on the sin in functionality. And also, I just remember, I want to run this in b as well. So now Now, if I tried to run on this crew, you will see what happened. Because obviously our app will be cross platform compatible, so it should work on b and d IOS. Now here, you will see some kind of error because to make sure network images work on b, you have to add a line of code here. That is in the b, go to index HTML. In the bottom. Above the body tag, we have to write a piece of code. Scri type is equal to t Java script. Window flatter renderer is zeal to TM. This code you have to write in order to make it work. S type text, Java script, and this should be window. Not the sc flutter render is zeal to DML. Now again, If I try to run on. If I go and in the main do dart file and click on Star debugging. Let's see what happens. Now, it should work the network image. I don't think so there is any kind of error, but this image is not showing. Okay. I will look into this in the next video, but as you can see, there is no error at least. The app is running. If I restart, then also this logo is not there. But I will check and let you know. Thank you. 4. Setup Google auth for Android: Hi. In this video, we will work on the Google Art for Web. Go to the Cloud Console. Click on Create Credentials Art client ID. Choose web application as the application type, and write the name Docs Web. In the authorized Java script origin, you have to put your deployed URL. But in our case, we will write HTTP column local host three than. Obviously, we are not deploying it. That is why, but it's up to you. And then here. Click on Create. I hope that there is no adder. Here we don't need to download the JN file. You only need the client ID. Click on. Okay. Then next step we want is go to Web Index T five. I will past the client D for now and then go to Google Sin in Web. This package. Google Sin in Web package. In the instructions, you will get this line of code. This one. Simply copy it and in the section. Paste it here. In the content, as you can see, you have to paste your client ID. Like this. Now, as you remember, we wrote Local Host Street. We have to run our web on this specific port for now, which you can do using simply copy it. And in the terminal, past the code and change the pode to 3,000 and click on Enter. We have the chrome here as a device. It will run on our chrome device, but on a specific port. Otherwise, it would have used random ports. Okay? Again, we are facing this issue. The issue with the network image on. M The image should be different, I guess. But okay. Let's first see the functionality. Okay. I guess something is not right. I don't know. But I will stop the application change this image as well. And in the next video, I will test the Google. Okay. Obviously, Google, it won't work. If I click on it, then also it won't work because we haven't create any functions for it. So in the next video, we will work on creating methods so that we can assign that method to this perton. Thank you. 5. Setup Google auth for IOS: Hi. In this video, we will configure Google art for IOS. For this process, you must have a MacOS system. This cannot be done in a windows device. In VS code here, right click on the IOS folder and choose pen in X code. So as you can see, X code can be used only in a MacOS. Then here, click on Runner. Then you get the bundle identifier value here. Simply copy it. We need it in the upcoming step. Again, go to your Google Cloud Console. Click on create credentials, then At client ID. Then choose the application type as IOS. Give it a name as Docs IOS. Se Bundle ID just paste whatever you copied. And click on Create. Now download this past file and rename this file to Google G Capital Google Service Capital Info, like this. This is important, remember. Okay. Now, you have the X code open here. Drag that pleased file inside this IOS runner folder, wait. Let me see. Yeah. This one. This folder, you have to copy it and just make sure Now drag and paste it file, pat this file here. Make sure this is and click on finish. That's it. You can close this. No. For the next step, you have to go to put site. I will just go and See here. We have the. We have the Google in here as well. Go to and search for Google sign in package. Here, you will get all the instructions we did. See. For the IOS integration, you have the Google Survey in F P file. Move it to the IOS runner folder. The only step we required is this eighth one. So copy this line of code and go to IOS runner info list, not one, only the info p list, and past the code at the bottom. Below this line pasted. Like this. Okay. Here, as you can see, copy this value from the Google Info doot plist. Here we have this reverse client ID. Copy it and paste it here. Okay. And finally, go to the port file and uncomment the platform IOS line 11 line. That's it. These were the steps required for configuring Google t for IOS. In the next video, we will work on the web portion. Thank you. 6. Setup Google auth for Web: Hi. In this video, we will work on the Google Art for Web. Go to the Cloud Console. Click on Create Credentials Art client ID. Choose web application as the application type, and write the name Docs Web. In the authorized Java script origin, you have to put your deployed URL. But in our case, we will write HTTP column local host three than. Obviously, we are not deploying it. That is why, but it's up to you. And then here. Click on Create. I hope that there is no adder. Here we don't need to download the JN file. You only need the client ID. Click on. Okay. Then next step we want is go to Web Index T five. I will past the client D for now and then go to Google Sin in Web. This package. Google Sin in Web package. In the instructions, you will get this line of code. This one. Simply copy it and in the section. Paste it here. In the content, as you can see, you have to paste your client ID. Like this. Now, as you remember, we wrote Local Host Street. We have to run our web on this specific port for now, which you can do using simply copy it. And in the terminal, past the code and change the pode to 3,000 and click on Enter. We have the chrome here as a device. It will run on our chrome device, but on a specific port. Otherwise, it would have used random ports. Okay? Again, we are facing this issue. The issue with the network image on. M The image should be different, I guess. But okay. Let's first see the functionality. Okay. I guess something is not right. I don't know. But I will stop the application change this image as well. And in the next video, I will test the Google. Okay. Obviously, Google, it won't work. If I click on it, then also it won't work because we haven't create any functions for it. So in the next video, we will work on creating methods so that we can assign that method to this perton. Thank you. 7. Create auth repository: Hi. In the last video, we faced a similar issue of network. So what I did is, I simply downloaded two images. That is, if I show you, in the root folder, I created an assets folder and inside it, I pasted the two images. And then in the pop spec dot Yamal file. See here below in the line 63, I uncommented the assets line and write the asset folder, that is, our folder name was assets. So inside it whatever images or files we put, we can access those images. So make sure you do the indentation right because if you have any extra space or tab, you might get some errors. Then in the login screen, simply I write image dot asset assets logo dot png, and for the icon, I write image as assets Google dog. So this will solve our issue for later on as well because I don't know what was the issue with that network image, but obviously in production, you will use asset images. Now moving forward, I will type Q and stop the running of the application to install two packages. We will be using River Pod as the state management tool in our application and HTTP to send request to the server later on. This right flutter add Flutter R Pod, type space, and then STP. These are the two packages I want to install. If I go to pop spec dot ML file, see, we have the flutter pod and STP package installed. Until now, we have successfully configured the Google signing package. Now let's create functionality or methods in flutter to allow the user to sign in. We will create separate file for this purpose. Inside folder, create a new folder name it theory. And inside it t repository. Okay. Let's do it at the very top. I want the Google signing package, and then the TTP package. Then create a class t repository In this class, instead of initializing the packages, I will accept the packages object in the constructors. Here I will write final Google sign in. Google sign in and final client client. Then create at Here, I cannot simply write this dot because obviously this is a private variable. So I have to write required Google sign in Google sign in and required client. And then semicolon. Colon, the Google and assign it to the private variable. C. Client is equal to client like this. This approach is used because it is convenient to do unit testing later on. We won't be doing it, but obviously, if you want, you can implement that. Let's create a function which will allow user to sign in. It will be an function. Wrap it with the t catch block. For the timing, I will just print the error. And in that tr I will write final user is able to await. Google sign in dot sign in. And then we will check if user not equal to null. That is the person has selected an account and sic user print user dot e mail user dot display name for now. Later on, we will do the back end stuff. So that's it for this video. In the next video, we will assign the function and test it. Thank you. 8. Assign the Functionality: So we have the repository created. It's time we use the pot package to create a provider. So here, first of all, input latter put package, then create data final art repository provider to provider. And then we art repository. And here we will create the instance of the Google signing, as well as client. So we will pass the instance of the art repository class to the provider instead of creating multiple instances in the application. The RF object allows us to interact with other providers. That is when one provider depends on another provider, then this F will be very useful. Okay. Let's assign this sin in function in order to interact with the provider in the login screen. We will use the consumer igid method. So simply change this stateless widget to consumer widget. So this comes from the flutter river pot. And here we will get a widget F. And I hope you know river port as well because these concepts, obviously, these are not the beginner friendly concepts. You should know what is this consumer widget, what you will do with this f. But also, if you do it with this course, you will understand by doing it practically as well. Just understand that with this ref, we can call this art repository provider and this function. So here, simply void sign in with Google. We have to get the wig F because wig RF is only accessible here. So I will assign this function to this button. We will pass this to this function. And I will read dot read. What is the provider name repository provider sign in with Google like this. And here we use this read because when we are outside this bill function, we have to use read all the time. And when we're using this code inside the bill function, then we will write watch so that it can listen to any change in that class. Let's assign it to the field button here. Simply write sign in with Google, and we're passing the F. Also, if you're coming from provider, you have to wrap the main dot d file. In provider, it was changed notifier provider or multi provider like this. Here, you have to wrap it with the provider scope. I flutter port package. Then wrap the my app with the provider scope and add the constant at the beginning. That's it. Now, if you are running the application, make sure you stop the application and rerun it. Also, I have tried this app before as well. So I know if you run the app in Chrome and try to sign in with your Google account, then you will get an error. So, why not show you. Because you have to do something you have to enable something here that is people API. See here. Okay. If you try to run in Chrome and sign in with your Google account, then you will get an error in the terminal. The thing is in the web, plugin will do an additional request to the People's API to re the logged in user information. For this to work, you enable access to the API in your project. Click on enable Also, this link will be mentioned in the error in the terminal. If you don't click here and try to sign in, you will get this error. Let's say I will just recommend that you write these steps because I know there were a lot of steps to do. In your later projects, just in case you forget, you can look at those steps. We have the PAPA enabled. Now again, I need Pop Google sign in. I forgot that code. That is to run to run in a specific port this code. Pay state 3,000 percenter L et us say what happens. If I click on sign in, S. Continue to Dogslo. I will write S. We have the e mail, we have the displaying. So that means our Google sigil is working perfectly. It's a good thing. Now, obviously, we are not doing anything with the values now because in the next video, we will start working on our backend server. Thank you. 9. Create a Node js project: H. To store our data, we need a back end. Go to news RG and download the recommend version for your system. NPM will be automatically installed with Node JS. I have already installed it. You can verify it by using the command node slash version. S? I have 18.15 version in my system. And you can install this. It doesn't make any difference. Now the fun thing begins. We will create our server. Here. In the root folder. It is outside Lib. Remember, indirectly in the project folder, create folder name server, and I will close all these files. Obviously, you can use any location. I just prefer it inside the project directly. Pen up your terminal and change the directory to this server folder like this and initialize an empty NPM package. N Y. These are the code for no S S. It creates a packet dot file. The next thing is, we need an entry point for our server. Just like in flutter application, it is the main dot dot file. Inside server folder create file index dot S. You can name it anything but make sure this value that is main is same as whatever your file name is. You bot name are index dot S. This is the default name. And in this packet dot JS file, you will see all the external packages which we will install now. The first package we will install is Express. Express do JS is a framework that works on top of node JS to simplify its APIs and add helpful new features. It makes it easier to organize functionalities with middlewares and routing. So write the code and NPM install Express. Like this. Then see here, we have the express. The next package we want is node mont. If we start the node server now, then whenever we make any changes in the code, we have to stop the server and re study again and again to see the update. This is not a good development experience. Just like in flatter, we have the hot reload functionality. Similarly like this, there is a package which allows live refresh of the server. That is whenever we make any changes, it will automatically restart the server. So NPM install slash G, node moon. Like this. G means we are installing it globally, and I have already installed it. That is why this is giving me an error. In my system, Nd Mon is already there in the global state. After installing it, you have to go to this package or JCN file and write a script. That is, first of all, I will remove this test script and write start, which will be Node index dot JS. And similarly, we will have Dv, which will be Nude Mon index dot JS. So this start will be in the production use. And while we are in the development phase, we will write NPM run Dev to start our server from now on. Then the next package we want is Mongoose. We will be using Mongo DB as a database. And to connect our Node JS application with Mongo DB, we will be using an NPM package called Mongoose. It will help in creating data models and store in the database and also provide CRD methods which are very easy to use to write NPM install Mongoose. Okay, I I did the mistake. I have to write change the directory to server. Okay. Wait, wait. In the server right NPM Mongoose. What happened was, if I go here by mistake, we have this module packet file. I will remove all code. Yeah. Okay, I have this Mongoose as well. In the next video, we will create a basic or you can say we will create our express server. Thank you. 10. Creating an Express Server: Hi. In this video, we will create the server, but before it, I have a few other packages to install. First one is NPM install stock.au. We will be using this package to establish a real time connection, which simply means that the front ten will keep listening to any changes in the database and reflects it without restarting the app. In other words, we will be able to use streams instead of just futures. Obviously, in our application whenever one document is getting updated, the other people who are viewing that document will get the real time updates. Then next package I want is NPM installed JN Token. This package is required to create a token based on user ID. This will be stored in the user's device that will allow us to persist stat of the authenticated user in our application. Then next thing we want is NPM install cores, CORS. So this will help us to access functionalities on the browser. Most of the time, our client application only needs to access resources within the same origin. But there are scenarios where your application needs to request resources residing on another domain, and that's where course comes into play. So just remember, these are required. S. We have course JS web Token Express Mongo IO. These things. Okay. This is done. Now, go to Index or JS, and the first thing we will do is create a server. For that, we have to tell our project that we will be using Express. This is how you import a package here, constant express to re express then we re the cos package. Then initialize express here Cs app is to the e Middle wares. That is mile wares. Manipulate coming from the client to the server. App express dot JS, this will convert all incoming data to JCN format, and this will app use cose. This is required just to work on the web. Then we have to mention a port in which server will roll. So if If we have deployed it, then it will take the port of that server, or else in development, it will use 3001. Since web is already running on 3,000. That is why we use 3001 here. And this code means, suppose you have deployed this in on the Herro coup. So there it will automatically retrieve this value from your hosting platform. Finally, write app dot listen. You will be listening to the port that is 3001. You have to mention this IP address that is anyone can access this server because obviously, I want other people to use this server as well. And if server is running properly, then in the console right, using the back tick, I will server connected at pot and the pot variable. This this tag is above the tab value, that this is not com parenthesis. Just remember. Now, to run the server, upend the terminal, go to the server fold and write NPM run. And see server connected at pode 3,000. That means our server is running. And remember, these codes this code is related to No JS and Express. If you don't understand, I believe you go and watch some basic tutorial. What is going on behind this code. That's in the next video, we will set up the Mongo Db Atlas for our application. Thank you. 11. Establish MongoDB Connection: Hi. In this video, we will set up our Mongo DB Cloud database with our flutter application. That is not flutter. You can say our server. Go to the browser and type Mongo DB dot com. Then click on sin in. I will just simply sign in. You can sign in with your Google account. After that, if you are a new user, you can give any name to your organization and select Mongo DB at las option. Remember, I have already have an account. That's why I was not asked those things. But after that, after creating an organization, you will be sent to this where you can create a new project. And here I will name it Docs clo. Click Create project. This is creating the project. Our project is created. Now here, click on, build a database. Select the free tier. Then provider is A A. Select the region which is nearest to. I'm not changing the cluster name click on. Create. Here you have to give a username and a password. That's your password. I will just give it a very simple one for now. Remember, these credentials are very important and will be required in just a minute. In the IP address, simply write 0.0 0.0 0.00. So that everyone can access the server and here choose my local environment and click on Finish close. Go to database. This is configuring or set up, our database will be set up within a minute I believe. Because we will require a string. It's connected. It's a. Click on Connect. For the connection string, click on Mongo V code and C, we have this string here. That set, go to your code in the index the JS file. Now let's establish connection between the app and the Mongo DV. First of all, import Mongo's package, like this. Then here I pas DV is equal to paste the string and enter the password. You have the username and the password was two, three, four. Then write the code mongoose dot connect DV dot then, that is, this is a future. If it is connected successfully, console dot log Mongo connected successfully or else if some d is there. Then write console dot log error. Let's save it, and let's see what happens. See Mongo connected successfully. So which means we have successfully established the connection. In the next video, we will start working on our APA routes. Thank you. 12. Create a Signup route: H i. In the last video, we established the Mongo dip connection, but I forgot to mention the database name here. So at the end of the string, I will write the database name is Google Docs. So if you don't mention the database name, by default, it will use test as the database name, and then inside it, there will be collections. But I prefer to give a database name. That's it. So if I save it and write CD server PM Rd, then see Mongo DB connected successfully. Okay. And if I go to the website or the database and click on Browse collections. Then, obviously, right now, there is nothing to show. So let's save the data we get from Google after authenticating. For that, we have to create rest API to perform RL operations in the Mongo DB. Also, instead of writing all the routes or the APA routes inside this index the JS file, we will create separate files p separate functionalities. Inside server folder, create a new folder routes. And inside it right at Dot has. So this file will only contain the routes related to authentication. So let's import our packages. I require express and I will be using a custom router. I will simply name it art router. You can also use app dot G and all, but the convenient way is using express router. Now, let's create the API for sign up. It will be a post request t router post. API URL will be API sine up. It will be an Sing function. And this will give us a request and a response parameter. These are the concepts from No JS and Express library. Now, wrap our logic in a catch block. And here from the front end, we will pass the data in the body of the request parameter. It will be reconst is equal to request do body. So here in this body, we will send the data later on, and I will send the data by the name that it will be name, e mail, and profile pick. So we will pass these data in the body from the Fronts. Just remember these things will come later on. And at the end export the router so that We can use it in the main index do GS file because we have to make sure to register that router here because this is the main file. So at the top. No at the top. You can directly write app dot U, and then AT router. It will import directly. S. This is done by using this. That is any API which comes server name or the locals thousand API sign up, this will be executed. So that's it. That's it for this video. In the next video, we will model that data which we're getting from the user. Thank you. 13. Model User Data: Hi, welcome back. So we will store user data in a collection named in the database. So to model data for user collection, create a new folder inside server, and name it models. And inside it, create a file user dot JS. We will be using Mongoose for data modeling. So at the top import Mongos Then first of all, we have to create a schema for our user. Schema means what pills will be there in the user collection and there are types that destroying Boolean and other properties. So simply write const schema is equal to new Mo schema. This is how you do it. Then the first field will be name and it will be type string, and this will be a required field. Then the next thing will be e mail. It will be a string string, and this is also required. Then we will get the profile pick. Similarly, this is a string that it will be the URL. And this is also required. Since we are authenticating with Google signing. Obviously, the chances are we will get something in return. Then we have the schema. It's time to convert the schema into model. The cost user is equal to Most model. I will write the collection name and the user schema. And finally, export. Module export is the user so that we can use this user's model. Here, remember, Schema means what will be there in the user collection in our case and the types Then after schema is there, we have to convert schema into model, and that's it. Remember to export the model. In DT also, we do data modeling. Obviously, the thing is different. Here, it's more about connecting or performing the cloud operation to the database. And in that, it just converting objects into that dart, sorry, JCN data into the dart object. That is the difference. That's it. In the next video, we will test the sign up API that is this one and also write the logic. Thank you. 14. Test Api with Postman: Hi. Let's use the user model to read as well as create new data in the Mongo DB database with the help of this, sign up API. So here we get the data. First thing we have to do is check if e mail already exists. Because if user already exists, we don't have to insert the data again. Le Let user is equal to await user model. S. This has been imported. O user model dot find one. These are all the syntax of Mongo OM. It will simply find where e mail is equal to this e mail value. Now we will check if user does not exist. That is, if this user is null, then create a new user in the database. This is our model. We will simply populate that his name is the name or the e mail fill, we get the e mail. And for the profile pi, we get the profile pick. Now to save it in the database, the code is user is equal to a weight user save. Now in this variable, after saving, we will get the user data, that is the updated data. So this, we will simply return. After this if statement, that is S the JS that is response in the form of JS. I will write user user. That is the key is the user, and this user is the value or the JCN response we got from the Mongo DB, something like, wait. It will be something like this. ID is going to do something N like this, we get the response. Also, if user does not exist, then only we are creating a user or else, we are simply returning this user data C. That is why we can return this user variable because either it will get the value from here or it will get the value from here. And in the catch, I will write response Data 500 dot J. In the error, I will send the error message. And you might be thinking, what is 500. So if the status code is 200, that means it is successful. And here, if everything goes well, then status 200 is sent by default. That is in response, status code 200%. But if you want to change the status code while returning the JCN, you have to write like this. That is 500. That is something in the server side if you know that 404 means theta or doesn't exist. So there are different types of status code. Now, to test the API, this API, we will use a tool called Postman. Since to perform any crud operations on a server, we need a client or the front end. But to simulate requests from a client, we can use postman. So either go too postman and install a software because I have already install in, say the directly trying to log in, but go to postman.com and install the software. And this is Postman. And here I will test it. This will be the software. Simply click on this plus. Here, you can change the request type. I will have the request as post. Make sure your server is running. We have to send the request in STTP, column local host API sign up. And in the body, Choose Ra and make it Jasen because you have to send a data in JCN format. And what data you have to send is first one name. I will give Rahul email@gmail.com, and then profile pick something dummy. Dum. Okay. So this is post request. Server is running. We are sending a post request data is okay. Let's click on send. And see, in the response, we get user, and here this contains a JCI file, JCN map with name, e mail, profile pick, and this ID is automatically generated by Mongo Di. These are unique IDs. And if you go here and refresh, Then say we have this Google Docs database, and inside it, we have one document in user's collection. So that means the sign up APA is working perfectly. That's it for this video. Thank you. 15. Creating User Dart Model: Hi. We have tested the APA successfully. Now let's call the APA from the flutter side. But first create a model for user data in Flutter as well. Inside Lib. So I will just close the save. Inside Lib, create a new folder and name it models. And Inside model, create a file user model dot. Let's start writing user model. The final string name will have a name property, the final sting email final string profile pi Final UID final string Token. Here, UID will be that ID property. And token we will generate later on. Create a constructor user model, and write required this dot name required this dot e mail required this dot profile pick required this dot UID requ token. Now, you have to create Jason's salzation as well, which you can directly do with generate ceralzation. How I got this, I got this with this extension called Dart data class generator. S. I've installed that extension in my VS code. This will generate serzation and all. Here, you just have to change it will be ID. And here. Let me check. And we don't have the copy generate copy. Now, let's check everything is okay or not. This to map is correct. Name e mail token. We won't be using this to map, but yeah, then with P Map. We return the user model here. And here I will just safety. I will do this null check. That is for whatever reason, if there is any error, Here, this UID will be ID, which is coming from Mongo DV. This is important. Here I will write ID because since Mongo DB returns this returns it. Then we have to Jason, that is. And from Jason st source from Jason Jason Code. And copy it. I also. This is the user model. Now, to access the APA from the client. We must send the request to the URL. But if we only mention STTP local host 3,001 from that is from Flutter, then it will work on Chrome, but not on Android or IOS. Since Android will see the system and itself has two different entities. Also, I'm not sure about IOS, we will check it, but for Android, I'm definitely sure it won't work. So instead of local host, we will write our own system. That is this species private IP address. Remember, not the public one which you get if you Google and write, what's my IP address? In windows, it's very simple. You simply have to open up the terminal and write IP, CO N FIG, that is in the terminal right, IP, CON FIG. In windows, you have to write this, okay? But If you are in on MAC, you have to go to system settings, then Wi Fi, then whatever wi fi you are connected, network settings, and here you will get the IP address. Simply copy it and create a new file inside lib and name it Constance dot dart, and we will mention it in a host variable. That is HTTP, then paste your IP address, then in the end column and 3,001. That's it. Save it, and we don't have to use that file anymore because we will call the host wherever we want. That's it for this video. In the next video, we will create the method to call the sign EPA from our client. Thank you. 16. Call Signup Api from Client: Hi. Now, inside the signing with Google method that is in the repository. Let's call the sign up API and send the data to the server. Here I er not equal to null, then write final user account is equal to user model. Here, we will create a user model. Name will be user display name. And for some reason, let's do the null check as well because I don't want any error name, but e mail it will never be null. Profile picture, also is URL, and this also can be null. For the U ID, just leave it empty for now and the token, leave it empty for now. Empty string. Okay. Then let's call the post request from the client. That is R is equal to a client post request It accepts we have to parse it with URI. And here we have to write first of all, host. That is that constant variable, slash API sin. And then in the body tag of the post request. We will write user account two JS. I hope you remember this is that two JSN, which will call two Map, and it will save it. Here, it not be ID should be ID. Leave it as it is. L et's see what happens. It is to JS, and then we will also write just wait below this body. We will also write headers. Headers. This is an important thing when we are dealing with ST request, you have to write content type application JCN and JR ST is called a UTF eight. Okay. Now, let's use a suit statement to check the status code. Remember, we will be focusing on the 200 status code. If everything is okay, we'll simply write final new user is equal to user account copy and In the UID, we will simply write JCN decode rest body, access the user, and then the ID, like this. We are converting to JCN so that we can access this property. That is why JS decode. And here right break. Remember, I'm not working on error handling for other status des that is 404 500. Right now, let's focus on the main functionalities. Also, let's store the user data in our state management. That is, we can store the user data model in our River pod so that we can access it anywhere in the application. But if we simply use this provider, then it won't be useful as it is a read only type of provider. We have to use a different provider known as state provider, which can be used to update data as well. So this is very useful. Yes, wait. Wait So for that simply in the art repository write pin user provider is equal to state provider in the in the value, just leave it for now, and the state type will be model label. It is either it will be null or have a user model data. After this, create a new file inside models. I name it result modeled or Dart. This will be the return type of our sign in with Google function. Since it can return error as well. Remember, this sign in with Google, it can return error as well. Here class result model. Final string label error final dynamic data. Let's create a constructor. Re this error, re do data. Here in the repository, simply change the written type to future result model. That in the 200 First of all, we have to result model result 02. Err null Data null for the time being. Then if status is 200, then we will populate the result result error Theta will be new user. And if there is any error, then we will write result to result model. Error will be e two string, and theta will be nel. In the very end, we will return the result. That's it. So this is our function. You can see if result, that is the return type is result model, which will be very convenient to check if there is any error of there is any data. That's it for this video. See you in the next session. Thank you. 17. Test the Sign In Functionality: Hi. When a user successfully signs in, we will need a home screen. Inside Screens folder, create a new file home screen dot and first import material then also import letter R Port package, because we will be using a stateless consumer widget. S. That is, sorry, we will use a consumer widget so that we get the reference to our widget raf. It works similar to a stateless widget. The only difference is that we can access our providers. That's it. So here, the scaful, then in the body, have a center tag and the child, I will display the e mail of the user from the provider. Just to make sure everything is working perfectly. The user provider. Dot e mail. So I hope you remember this user provider has a value data of either user model or null. So if the user comes to the screen, that means it cannot be null. Now, in the login screen, when we execute the sign in with Google functionality, we will check for error as well. And also, if everything is okay, we will navigate the user. So here for showing snag pars, we will use messenger is equal to s messenger of context. And for context, we have to ask for context while executing this function. And for navigator, you will write navigator is equal to Navigator that of context. Okay. Now, we know that this function returns a result model C, so we'll simply write final result result model is equal to a weight, and for a weight, we have to make this function. Tie in with Google. So now we'll check if result model error is null. That is everything is okay or else. So if error is there, we will show sreful messenger snag bar. And in the snag bar, we will simply show the result model error like this. And if error is, everything is okay. First of all, we will update the value of user provided that is user provider dot notifier, then update. And we will write result model data. And then we will push replacement material page route, Builder, Cs Home screen, and here it will be context. That's it. Now, call this function here. That is we have to send the context as well. Let's say I hope we won't get any error. Save everything. If I this web and try to run it in the, let's say what happens. If I click con sign, and write program blog. Then see, we are navigated to the home screen with our e mail. That means everything is working perfectly. And here I don't remember. We are saving data as. Yeah As you can see, we have name, e mail, and profile pick. So we have stored data which is coming from the Google in our own database. So that's it for this video. See you in the next session. Thank you. 18. Create Auth Middleware: Hi. So as you can see that our Google sign in is working perfectly. But now the next thing we want is if we restart the app, I don't want the user to sign in again. They should be directly taken to the home screen. To implement that, we will generate a JCN web token in the server when a new user signs up and send it to the client in the response so that it can be saved in the device local storage. This token won't be stored in Mongoi we. Go to the S here, when the sign up API is called. Before sending the response, we will generate token, but at the top, we have to require it first. Cs J two is to require JCN web Token. Then here, we will write const token is equal to jt sine. And we will give the ID as user dot ID. This one. We will generate random token from the user ID value, and we have to pass a secret key as well. So I will use password key. You can the secret key, but this is required later on. And now in the response, we will send token as well. It is token and that token value. That's it. Also, I want to create a new route to get user data. But I have to make sure that the user is authenticated and then only he should be allowed to access certain routes. Obviously, if the user is not authenticated, he shouldn't be able to create a document and all. For that purpose, let's create a middleware, which will check whether Token is present or not in the request. Now, in the server folder, create a new folder. Middlewares and inside middleware, create ut JS file. Here at the top, again, require the JCN then we will create the mile like this cons t is equal to a sync. It will have request response and the next. This is a syntax to create a mad. Now, write a t catch block. In the catch block, we will directly write response 500 dot Jason error message. Also, we have to export the ut middle ware. Now let's write the logic. First, I will get the token value from the header that is request header, and I will send the key obviously in the header, I have to send the key and value pair. The key of the token value will be ut token. You can name this key anything. I'm just preferring this syntax. Then first of all, I will write, if token is not there, then return St that is 401401 means no authorization. Jason and message will be no art token access denied. Okay. I token is not available, then we will verified two t verify. Now we will verify the token that is with a secret key so that it knows that the token is v. And here we will write if verified it is not verified. Then again, we will return re status 401 Jon message token verification failed. Authorize denied. Then if everything is okay, then in the request parameter, we will add or you can say we're appending the ID value that is verified ID, and in the request, we also a pending that token. So you can understand that, if we write request user, then we will get the ID and it should be ID. And you have to make sure to call next so that whatever function or the callback is there, it will be executed. Just remember what is a middleware from the client to the server. That is client wants to access something in the server in the middle. This function will be called. And everything it's okay, then it will go to the server. This was the middleware. I hope there is no error, but it's fine. We will see later on. In the next video, we will create the route to get a user data. Thank you. 19. Route to get user data: Hi. Let's create a new art route, which is used to get the user data, and can we access only if the user is authenticated. This can be done using the art model were. So go to routes at the JS and below the sign up Prout create art router that get Now here, we will call the art middleware. Remember, and then we have the async. Request response like always. This is the code. Earlier in this, we haven't any middlewares, but in this get request, we are using the middleware. And also, remember, okay. First, let's get the user data. I is equal to await user find y ID, and we will send request that user, and then we will send a response. That is user equal to user. Token is equal to request token. Now you might be thinking where this request and user is coming. We appended the ID and token in the art middle. Remember, request or token, and if you go to utile, we have this request token. So we are appending these values in the request parameter. And now remember this will be executed only if that art middleware has no error. So we are sure to get the value here. This is how we will get the user data. Now, go to art repository. Here, while we are adding this UID, now we can access that token as well. I will assign that token value as Json the code rest body and token. Now token, we are sending token as well. Se this token, which We can add in our new user. And with this help, we can access the token. Let's test everything. I hope everything is saved. If I open postman And now, if I send this post request with this data, let's see what happens. I hope In the database, let's see I will remove this data. This one, same one which I am sending now. Now if I send, see, now we have this token generated. That means the JCN web token functionality is also working now. In the next video, we will store this token in the user's local storage. Thank you. 20. Store Token in Shared Preferences: Hi. Now we are getting that token successfully, but we have to store it in the user's device. We will be using an external package known as shared preferences. You can also use hive. But in this torial, we will be using shared preferences. So simply open up the terminal. I will stop the server and here Not the server. I will stop the chrome application and write letter Pub add shared pre per ns presenter. Okay to double check it. See. Shared preferences is there. Now, to save token data and shared preferences, let's create a new file inside depository. And name it local storage repository. Imported preferences data class. I will name it local storage repository. It will contain two functions that token and it will accept a token value. Now we have to get an instance of the shared preference preference do get instance and simply write preferences do set string. E will be X token and value will be that token variable. This is how we store or you can say set that token in the local storage, and then again, create a function to get that token. So it will be a future function, which will be a nullable string. Get token nullable because when we tried to get the string from the shared preference, the return type is string, which can be nullable. So again, create the instance, and now write string token is equal to preferences that get string, and simply this key. That's it, and then return the token. It is simple. Because obviously you can understand first here we are storing it with this key, and then we are re that key. Nothing else. Now let's call this set token function when a user signs in for the first time and save the token India device. Go to earth repository. And here first, accept it in the constructed. It is final local storage local storage repository. Then here I required and then write. After in the sign in with Google function, when we get the success and the result, then I will write local storage seen newer as simple as that. Because obviously here, we get the success response with that token. You know the token is there in the body. And then we assign that token inside the new user variable. Now at the very top, we have to pass local storage instance as well. That's it. This part is done. We will work on using this token in the upcoming videos. Thank you. 21. Check Auth State: Hi. We have already created a route in the server to get user data. Let's create a function, or you can say a method as well in the client side. So in this art repository, Below the singing function. Let's create a new function, which will return the result model as data type, that is return type, and the name will be get user data. Okay. First of all get the user model is result model. Result s two. At the very beginning, both error and data will be null, then we will have our logic inside the catch block. If it's an error, then we will write result model error is error, the two string data will be null. And return this result. And inside the tri block, First of all, we will check if Token is available or not it is string token is equal to await local storage that get token. If token not equal to null, then send the request to await client that get Here, it will be URI do pars and inside it, it will be host and slash directly. And now in the headers. First of all, we will send that is content type This is mandatory. But then now we will send x at token. So this is the key we mentioned in the server. So we're sending it in the headers. Remember, when we are using a gat request, we cannot send data inside a body. Now, below write a switch statement for the status code and check if case 200 is there, then we will write final. New user user model from JS. Now it will get a bit trickier because Wait get that token. Wait. I will, first of all, I will write, Jason. The code rest the body. Er. And then inside it, I have to write copy it and then token token value. And here I have to again. I have to Json Code 's So here in response, we get user and token keys. But our dat model accepts name, e mail, profile, pick, et cetera. So that is why we first decode so that we can access the user key and then encode because from JS accept string. So this is the logic. It is little bit complicated, but still you have to understand it. Then in the result model, we will sinull, and here new user. Then We write local storage, dot set Token, new user dot Token, and then break. That's it. This is the logic or you can say the punch to get the user data. Now let's check as soon as the app loads that whether user has already signed in or not. Go to main the dirt here. First of all, convert my app to consumer state full widget. So if I write consumer widget, wig RF RF. And let's say, if there is any option. Nope. Convert it to state full. Then I will just change it. That is consumer state full aged. This will be consumer state, and similarly, this will be consumer stat. That's it. Now here, First of all, I will create the result model, which is null for now, and create a function to get user data. We will call the function from here. Result model, to a re repository provider user data. And then I will check if result model not equal to null, and result model, the data not equal to null. Then we will update the data inside user provider. Here we have to use notifier, then, state will be result model data. So we are storing the user data now. And call this function in the init state. It is in it state. All this get user data. And here we will write Final user is to re do watch user provider. And the home we will check if user is equal to u, that is user provider value or else constant home screen. Okay. Let's test the functionality now. I will go to the database, and I will just refresh and delete the data. And now that the website in the crew and see if I sign in, and then again try to refresh my browser, then what happens? Let's see. Now if I click on signing, then sign in. Then I am sent to the home screen, but if I refresh, then see, I'm again navigated to the home screen by default. So that means our JCN ab token and the shared preferences all are working perfectly. Now, you can say little by little, our app is progressing. So that's it for this video, S in the next session. 22. Implement Routemaster package: Hi. We have to think how we will manage the routing in our flotter application. If you want, you can use navigator, but there is a problem, which is dynamic links. Basically, whenever you go on the website, you have to pass a certain URL, which will fetch the current document. That means we have to pass the D of that particular document in the URL. This is very difficult with the default navigator. So we will be using an external package, which is route Muster. So here I will stop my application and write flutter pub add route Master. Let's go to pop Yamal file and C. We have the route master here. Before mentioning our routes, you have to make small changes in the material app. First thing is you have to write material app router. Then in the top import route Master And this home property will not be there. Instead, we have to write router delegate. And route information Parser. This one will be directly Route Master Parser. This is just the code. In the delegate, you have to write Route Master delegate and the route builder. We will have the context and final, and here inside this delegate, we will use our provider. Because obviously, the logic of tending to screens will be written here. Here I will simply check if user not equal to null and token is not empty. That is user is authenticated. And if you see here, it returns a route map. That means we have to return a route map for logged in users, and here, we have to return a route map logged out users. Simple as I did this imports won't be needed now. And for creating route map instead of writing our routes here directly, let's create a separate file for it. Directly inside the create router. And here first import material, then import route Muster and directly right final log out route is equal to route map. Inside its routes, we can mention as many routes we want. In the slash, he will be sent to material page child login screen like this. And similarly, we will have a route for logged in. Here, he will be sent to the home screen when only the slash is called because already we know that he is authenticated. And remember, as I said, inside this, we can write multiple routes. Obviously, later on, we will have other routes for logged in users. Go to main dot dot file and return logged in route here and return locked out route here. As simple as that. Now we have, since we are using the route master package, we have to replace the navigator code. Go to login screen here, see, we have the navigator code. Instead of navigator, we have to write route Master of context, and instead of push replacement, this code, we have to write navigator dot replace slash. That's it. This is how we use the route master package for navigation. It's good. I will say. And I guess everything else we don't have to change anything else. That's it. Let's say what happens if I rest my app and say all the functionality that is, we are all directly navigated to the home screen, which means the route master is also working seamlessly. Thank you. In the next video. We will work on the sign out functionality. 23. Sign Out Functionality: Hi. Now the next part is creating an A bar in the home screen where users will have the option to either log out or create a new document. Go to home screen above the body tag. A bar. A bar. We will get elevation is zero, actions. And in the actions, we will have icon button. First button will be icon. Icons add and second button I can start log log and then log out color will be co start red. Save it. Restart our browser and see, we have the two buttons. Then create the sine out functionality. The logic will be very simple. Go to art repository. Below get function. We'll write sine out. We just have to remove the token from the local storage and call the sign out from the Google sign in package. The first, we will write a Google sign in sign out. So this will help us to use different accounts if we again try to sign in. If you don't use this line, if they use signs out and again click on sign in with Google, then he will be automatically using the previous account. And we will simply set local storage. To empty strain. Let's call this function, go to home screen here. Create a function wide sign out. It will accept a ig F. We write F dot read at provider dot sign out, then read provider notifier state as null. It is clear the user provider state. Because if we update the state, that main function will be called again. W, I will show you. First, let's assign this to the sign out function. Sign out function. We are directly signing out, and we are sending the F. Okay. So what I was saying, If we update the user state here, then this will be called again. And if the user token is not available, then we are using the locked out routes. Okay? Let's test the sign out functionality, make sure you hot restart your application. Now here, If I click on sign out S. We are navigated to the login screen. And now if I try to refresh it, then again, login screen is showing. That means our authentication functionality is working perfectly from Google sign in to sign out to storing the tokens, everything. In the next video, we will start working on that document screen, that is creating a new document, storing it in the database, et cetera, et cetera. Thank you. See you in the next video. 24. Route for Creating Document: Hi. Now the next thing to work on is creating a new document. For that, let's create a screen for it. Inside Screens folder, create a new file document screen dot dot It will be a consumer state full rigid. And also, it will accept an ID so that we know which document it is. Let's do it. Let's import material. Then iter river pod, then a stateful consumer widget document screen. It will accept an ID return careful in the body. For now, we will just show the D i ID. Okay. Remember here, obviously, we will when we are creating a new document, we'll pass the ID, and also just imagine if we are editing any document, then also we will pass the ID. Now let's work on the Ben logic, and we have to write the functionality for creating a new document. But first, let's structure the model for the document data. Inside models folder, that is here, create a file documents. Now, create a schema first, we have to importo. And the document schema document schema two Mongoose Schema. First thing will be ID. U ID means that is the user ID, you can say. It will be required filled and type will be string then created at This will be required. But here type will be number. Because in flutter, we need the date time in number, which is milliseconds since epoch. Then title title will be required to type string, and then them that is remove any white space in the beginning or at the end. Then I want content This will be a type of array, and default will be an empty array. These are the fils. Let's create a model, const document equal two Mongoel. Document document schema, then export the model. That's it. So I hope you have understood. We will create a collection called by the name document, and these will be the fills inside that collection. Also, like similarly for the route, we have A dot JS. We will have a separate route for document related stuff. Inside the routes folder, create a new route document GS. And here in all the packages require Express then const doc is required models. Slash document then document router, we will use this name for the Express router. And then we need the art middleware as well because only the people who are authenticated will be able to use these routes. Middleware t. Okay. Let's create document router, post request. We will have the request for creating a new document. So it will be Doc C We will use the Middle and then it will be a syn callback request response wrap everything in a try catch block. Yeah, it will be response status 500 dot Jason in that message and remember to export the this document router. Now in the tri block, first, we will retrieve the that is data from the request peters or the equ request body because since this is a post request, I will just send created at value. To request the body. I know I will send this data. Then let's create a new document this new document in send for the UID. I will request because with the help of the Middleware, I'm sure that we will get it initial title will be document and then created at. This will be created at. Then let's save the document. A document save and in response, send the document. Remember, status code will be 200 by default. And now we have this route registered the route in index do JS file. At the very top con document router And here app document router. That's it. So that's it for this video. Let's continue in the next session. Thank you. 25. Document Repository: Hi. The document route is configured in the server. Let's create a method in the client to call that route. So here, go to the repository polder and inside it, create a new Dt file. Document reposit Let's start creating last three. We will accept the instance of client. This client is coming from the HTTP package. Remember. No accept it in the constructor. We have to write required. Client, then to client. Okay. Now, we will create a method for creating document, which will result which will return result model as data type. And here, write the name, create document. It will be an as function, and it will accept token. Let's in the very beginning, initialize or create an object of the rear result model with null values. Then wrap everything in a catch block here. This I can write result. And this will be a results to result model. Error will be e two string, and data will be null here. At the very end, return the result. Now, let's focus on the block. And also, before moving forward, we know that we will need model for our document data as well in the client side. So inside models folder, create a new file document model dot site document. Model. It will have final string of title final string of U D final list of content. Final dt created at and then we will have ID. This will be the ID, which is auto generated by MongoDB. Then create a constructor this title ID. This content created and then here simply generate Jason serialization. Let's see what is the error here in the factory. We are returning I say, what is the issue here? I believe everything is fine in this code. We have Oh. Let's do it by hand. Title will be Map title Nt UID will be map. And here it will be UID. This is the user ID. Content will be list from Map content then created it will be time millisecond since EPOC map created a ID will be here. It will be underscore ID because this comes from Mongo two Json is okay and from Jason document decor source. Okay. I guess everything is fine here. I'm just checking. Again, I don't want these errors. This is then let's continue where we left in the create document method. Here, we will send a post request to our API. In this, response will await client post URI in it will be post doc create Then in the headers, we will send if you go to Let's copy this content type. And then x at token with the token. Then in the body will send Jason and code, and here we will send created at it will be dot milliseconds. Okay. Below it, let's have a switch statement rest status code case 200 to rest error u Data will be document model from JC rest dot body break and default will be result equal to result model body daternal. If there is any different kind of error. That is why we will send that error in the result model. That's it for this video. In the next video, we will call this function in the home screen. Thank you. 26. Function to Create Document: Hi. In the last video, I forgot to create a provider for our document repository. Let's create it at the top simple final document provider will do provider and the value will be document repository, and here it will be client. That's it. That's it. Now go to Home screen file here. Let's create a function, which we call the create document method from the repository we just created. And then we will assign it to the Aber button. Let's write d. Create document. We need build contexts, and the wig ref First get that token. Dot read. Use a provider token. Okay. Then final navigator is equal to master of context. Then we need a snack p snack power variable. Scaffold messenger dot of context. We will use it just at the end. Now, result model is equal to await F dot read document repository provider do create document, and we are sending the token. Then we will simply check if result model dot data not equal to null, that is everything went well, then navigator dot push and the part will be slash document will send the ID that is result model dot teta dot ID. And all else we will show snack par snack bar dot show snack par Content will have the error that is result model error. That's it. Now, we wrote this route, but we also have to register this route. Go to Router do dot file. Here in the logged in route, We have to create a new route, which we document, and then here, it will accept ID as parameter. Route material page. Child will be document screen, and here in ID, simple route part parameters, ID for safety. We are giving empty string. Let's test it first, save everything. Then run the app. Server is already running. But here. Let's run it for 3,000. I hope there is no error. Let's go to our Mongo DB. Let's see new collection is created or not. To log in. Then here create a thing happened. I go here and refresh. Okay? Documents is there. But not, no data is inside it. What went? What just happened? Do slash create document repository. I'm doing c request. Ten anything. Wrong is there. Okay. If I guess I forgot to assign this function. Wow. This was a very silly mistake. In the icon button here. Assign create document and send cont and re. Okay. See, we are navigated to this document screen. And here, if I refresh, then I get the document. That is user ID, titled document, everything. So that means until now, the functionalities are working perfectly. In the next video, we will create some other routes to get these documents as well. Thank you. 27. Fetch all my Documents: Hi, we can successfully create a document. Let's focus on getting all the documents of a user. For that, we have to create a route in the server. In the server, go to routes and document JS. Here below create document router G route. It will be Doc M. We have to pass the art Middleware, then It will be request response. Everything will be in the track, catch, block, rest status 500 Json A dot message. Now here, the logic is very simple. We will get all the documents by this command a document dot find. That's it. It will be UID UID is request. So we will get all the documents this user has created, and we will send it in the response. That's it. This was the routes. I hope we have understood. There are different types of methods in Mongos. It's fine, fine by ID, fine by ID and update. So these are all the things related to Mongo Divi. After this, let's create a method inside document repository to fetch and return all the documents of the user by calling this route. Go to document repository here below this create document. Future result model, get documents. We have to accept that token. Then it will be a bit similar. This code will be similar. This code will be similar. Here you will get client. It will be get request to host Docs M. Headers, we have to pass the content type and the tocal then in the switch statement, we have status code In case of 200, we have to do few things. That is, first of all, we create list of document model. Documents will empty A. Then we will lop through all the data in I is equal to zero, I less than J D code re body. Length I plus plus and we will add documents add and here it will be document model from JS JS code JS decode re body. That is f we decode and get the value. Then again, encode because from Json accepts the JCN value. This is the logic, then result to result model error null. Data will be documents break and default will be result result model, rest body in the error andata null. That's it. This is the logic of fetching the documents and converting them to the document model. Now, go to home screen file. Here we will display all the documents using future builder in the body. In the home screen in the boy. Let's write future builder. I future will be ref dot document repository get documents, and to get the icon, we have to write ref dot User provider do token. So everything we are getting from the provider. It will be bill context context a syn snapshot snapshot. Now, let's check if snapshot connection state, is two connection state. Then we will show center circular progress indicator like this. But if everything is okay, then return center inside it, have a container with thick and red margin as it sits on top ten then in that, We will show everything in a list view do builder age. You item count will be snapshot dot Data exclamation, again, data dot n item will be item builder context index. Now here, we know the data is in the document model format. So we can write document is equal to snapshot dot Data dot index. And simply return and ink well it because it will be we can tap on it. And here child will be a sized box height will be inside its center sh text document, the title gives some styling constant textile size 17. Simply, I will use a card to show the title of the document. You can give other stylings as well. In the on tap, I will write route Master of context do push and the part will be slash document document ID. That is document ID. We have created this route. Or for this. Let's is that. And if I go to the home screen, then see. Now, we are able to fetch our document. And if I click on it, we are sent to the document screen. So this functionality is also working seamlessly. In the next video, we will start working on designing the document screen. Thank you. 28. Document Screen UI: Hi, Let's focus on designing the document screen, and we will start by creating an app. Go to document screen do dot the scaffold create an app. Will have background color colors that white elevation zero actions padding cost gins that all tent piled button icon. Cs icon icons do Lock si 16 and label will be text. Okay. Also create a title controller because I know we will show and edit the controller in the ab. Title Controller to text editing controller. Now just give it the text and titled document. And we have to dispose this as well. Title controller dispose. Okay. Now, in the title property of the ab par here, in the title property, we will show the logo and a text bill, which will contain the title of the document. We start with Padding Vg. Const edge in set start symmetric vertical nine. In that child, we will have a row with childrens. First one will be the logo, which we have in the home screen. The login screen, we have the logo. Height will be 40. Then give space with sized works with ten, since it's zero, we have to give Then again, create a sized box, but here we are just using it to give a certain width to our text fill. Child text fill gives some decoration input decoration. Content padding in set only ten then border input border none, then cust border outline input border inside right border side border side color color blue. And then in the controller title controller. Okay. Also, just for the look. I want to give a small divider at the end of the a separate with the body, just to make it look good. So I will also use inside the abb, use the bottom property. Here, I will use preferred size gid, then preferred size will be constant size dot from height one then child container decoration, box decoration. Just give a border. Border dot all color colors dot gray shade 300 w 0.1. That's it. I just want to give it Small border. Now, refresh or hot restart our application and see. We have the logo. This is the text bar text field. We have the share button, and this is the bottom. So that is why it is a little bit better, I believe. We can go back as well. So this UI is working. In the next video, we will work on the body of the document screen. Thank you. 29. Flutter Quill Text Editor: Hi. Now in the body of our document screen, we want the user to be able to edit and write whatever he wants, just like Microsoft Word software. For that, we will use an external package known as flutter quill. So if you go here, and just write again. And here flutter Qil This one. This package we will use, simply installing and copy it. I will stop my website and write Flutter Pub ad. Okay. If I go to check in Pubs TML, I have the dependence installed. Now go to document screen. In the body tech first, import the flatter Q package as Q. Because this package has some methods or variables which can interfere with our material package. That is why. Here in the body We have the center and inside center, give a column. Column, we will have children. The first thing I want is first give some spacing, then the tool bar, that is s quill, the Qi tool bar. The basic controller will be, if we have to create a quill controller. You just write final quilt I thought controller is equal Q controller do basic, like this. Then assign the controller then give some spacing again. This controller means all the t, b, it, all these kind of editing tools. Then we will have an expanded wise. The expanded, we will have a size box of weight 750. Inside it, we will have a card git, which will have an elevation of three. Inside it have some padding git with const in sets all 30. Inside the padding child, we will have Qi Qi editor, the basic controller will be controller. Read only will be false. Save everything, then run the browser. Let's see how it looks. If I go inside, see, this is the toolbar, and this is the area that is the editor. So right now this screen is looking very good. Anyone can say that. Here we can create an edit documents. That's it for this video. In the next video, we will work on, updating the document title. Thank you. 30. Method to Update Title: Hi. Our editor is looking nice. Now I want that the user can edit and update the document title. For that, first, we have to create a route in the server. So go to Routes document JS, Blow create a new document, which will post request. It will be Dosh title. We will have the art Middleware, sync request response. Then just copy and paste the tra catch blog. And in the t, we will have const. We will send ID and the title. ID and the title inside request dot body. Then we will get the document that this document is able to await document find by ID and. We will send the ID and the title. Like this. And then simply send a response that document filed. Next, let's create a new method inside document repository to call the title route. Go to document Repository below the gt documents. Title required string token required string ID and then required string title and simply a post URI p and then host slash Doc slash title. Then inside the headers. And obviously make it a sync inside the header just copy and paste this line. We have to send content type and the x ut token. But here in the body, we have to send JS and code, and then ID as ID, then title title. This is important. This is the method. Now, go to document screen. Here we have to create a new function to call the update title method from the repository. Yeah. And go to document screen, not the home screen. I would update title Widgit RF RF string title then simply write f dot read document repository, the update title Token will be ref dot read user provider Token ID will be gi ID, and title will be title which we passed in this function. On this, we will assign to the text well, which is in the a bar. Here, I will simply write on Submitted. We get the value and simply called the update title function and the value. Save all. Let's test it, perform the hot restart. Now, see this is untitled document. But if I update that is updated document or you can updated title and press enter. And then go back and refresh. Then see, that title has been updated successfully. This functionality is working perfectly. That's it for this video. Thank you. 31. Get Document by id: Hi. Our title is getting updated. But if we go to the documents screen, then you won't see the updated title. So let's work on that. We will create a new route in the server to get the document data by their ID. Go to document JS here. Document router get It will be Doc ID that is it's a parameter. Then a sync. This copy paste it will be a weight document dot find by ID. And we will send request ID. And it will be a single document. That's it. So I'm just rechecking it. I hope I don't make any error while copying and pasting. Okay. Now go to document repository, create a new method to call the Get route. I just want to check again, that's a Get route. Document repository. Below the update title. We will create it, but I believe this is very similar to the create document. I will just copy the create document code, paste it here. Let's make the changes. First, I will get document by ID. It will accept token and the string ID. Then in that t, it will be response client get RI p doc ID. Headers is okay. There will be nobody. I guess this is fine whose doc ID. In the suit statement, if it is 200, then we have the error and it will be data model from JS break. If there is any error, we'll simply throw that is this document does not exist. And this will through and it will be catched here. That's it. This is the function. As you can see, this was very similar. Why waste time writing everything again and again. Now go to document screen. Here, create a function to get document by ID. I will create vid Petch document by Fetch document data. I will. Let's create a res model variable. Also, now we can remove this Dam text from the title controller. Now go to fetch document data and heart result model is to await RF read document repository that get documented by ID this ID will be widget ID, but here token will be ref dot read user provider do token. And then I will write if result model dot data not equal to null. We have at least got some data then text is equal to result model dot dta I know it will be a document model dot title. And then set the state. And make sure you call this function in the init state. So that whenever the screen is loaded, that the data is being fetched from the database. Save all Let's go and if I restart. Now if I click here, see, we get the updated title. Now we can see the title both in the document screen as well as the home screen. That's it for this video, see you in the next session. Thank you. 32. Establish Socket Connection: Hi. In this video, we will establish the socket connection between the client and the server. In the client side, we will be using a package known as socket IO client. So pen up the terminal and outside the server folder that is in the root folder, right. Letter pub and socket Io client. Presenter. Right now, the server is also not running. Let's install the socket io client and check it. S. I have the socket ICli 2.0 0.2. First, let's work on socket functionality in the client side. That is in the flutter project. Inside Lib, create a new folder clients. Inside clients, create socket client do. L et's do it first of all. Import the constants the dirt file, and then import the socket oclient as capital IO. We will create a class which will return the instance of socket Iolient package, but it will be a single ton so that only one instance is created. This is how you do it. Class socket client, then IO socket the static instance of this class. This is a private instance, then create socket client underscore internal a socket is equal to 00. I will be the host, and then we have to send this data. As I said, this is just the syntax, you have to send transports is equal to here web socket then auto connect is equal to false. And then socket exclamation connect. Okay. And then create an instance of this class that is get instance. It will check. If instance is null that is, it is not being initialized, then we will call this internal function and then return the instance. Exclamation. That's it. This is how you create a single t class. If you want, you can read or Google more about it. And remember, this is just the syntex. In short, this will send us an instance of socket client. This class only does that. Now, next, we have to configure our server as well to establish a socket connection. In the server. In the packet of JN file, we have already installed a socket IO. Now, go to Index JS file here. We have to make changes. You have to first at that top const HTTP, zeal two require HTTP. This is by default in U JS, and then import the socket package is required socket I O. Now, after initializing the express app, you have to write R, server is equal to STP create server. And send our express app and then write R IO is equal to socket and send the server. This is how you do it. And also, at the very last, we won't use app dot listen. We have to write server do listen just so that we have the socket connection as well. Then here, I will simply write on connection that is if we have a socket connection, then a call back. It gives us details about the socket which is being connected and write console log. T, I will write socket socket connected. And I believe this should be socket dot D. Let's see what happens. Okay. Next. Next, we will need functions to interact with socket in the client side. For that, let's create a separate file for all the methods related to socket. Inside the repository folder here, create a file socket repository. Here at the f import client socket client and import the package as well. It is both. Then socket reposit First, I will create socket client instance, that is socket client equal two. Socket client instance socket. This is the singleton which we just created. And then also we will create a getter method. What if I want to use it socket two socket li. Then Here, I will also create a method which will emit a join event. That is in sockets, what generally happens is. It's all about sending or emitting an event and listening to event. That is one person will emit an event and the second person will listen to it. So simply we will join room. String. We will need the document ID, then docket client met. I will send an event join that is listen to this join, and we are sending the document. Document ID. Now, in the server, we have to listen to this join event. Go to index dot JS, and here inside the connection, we will write socket. Which event, join event. Here, we will get a dock ID that is from the client. And here I will write socket join this dock ID and write console do Logo Join. Okay. Remember, here we listen to the join event. We can also emit event from the server, which will be listened to by the client. Now, finally, to test whether the socket connection is working or not, go to the documents screen here and create an instance of the socket repository class. Sock repository sock repository, z two. Okay. I in its state. Write socket repository join room and send the document ID, which is wig ID. Now, first of all, change the server and write NPM run and also I run our web app in the p 3,000. Okay. We have already logged in. Now, let's say. If I click here, then see socket connected and room joined. That means our socket connection between the client and the server is being established. That's it for this video. See you in the next session. Thank you. 33. Realtime Collaborative Editing: Hi. The socket is connected. Now we have to create the logic where users can collaborate in real time. Or that we will emit a typing event from client with data and listen to that in the server. Go to socket repository. Here we will create a new function. It is vid typing with map string dynamic data, and here we will simply write socket client em event will be typing and we will pass the data. And here, this data will be a map, which will contain the ID as well as the data which is being typed. Then next, from client, we're emitting, so we have to listen to this event in the server, go to index the S file, and here we will write socket on typing. We will get the data and here we will use socket broadcast. Broadcast. Okay. Now here, broadcast means that data will be sent to everyone in the room except the sender itself. That is obviously if I'm typing, I don't want the data to myself. I just this broadcast means is to which room, it will be in, and then we will emit a new event changes with the data. So that just try to understand. Here we get the data from from the person who is typing. Then we will emit a event changes to everyone so that this data can be updated to others who are in that, in the same room, that is who are in that same document. That's why this room ID is nothing but the document ID. We know that all the document ID are unique. That is why we can use them as room IDs. Okay. I I only do IO that two, then everyone except the sender will get the changes. That is why we are using broadcast. Now we are emitting the changes. We have to listen in the client. Again, go to socket repository. Void change listener. Now, it will accept a function. I will map, string, dynamic and here we will write socket client dot on changes, execute this function. With the data, which is being sent here. Here, whatever we sent before. We get the same data so that everyone's document gets up data. This data is the same data. Now go to document screen. Here you have to make some changes. First of all, Instead of initializing the quill controller here, I will write Q controller and it can be no label for now. I'm not initializing it. Then I will not create, I will initialize it inside the patch document data. Let's see, That state is there result mode is there Here, I will initialize it. Is a good too. Q Q controller. We have to send document. And remember, whatever I'm typing here, this is the syntax of the QL controller package. The flutter Q package. This is nothing related to flutter. Data content is empty. And just check if it is empty, then the document se Q document from Delta Delta means whatever data we have inside it. It will be quill dot Delta from JSN, inside it, we have to write result model dot data dot contain. We are just converting it to the data, which is understood by the controller. And selection, it will be cos t selection collapsed zero. So this is just the syntax. Okay. Now also here, I will show a loading indicator till the constructor is not initialized. Till the controller is not initialized. So I will write if controller is equal to null const sol body centered child circular progress indicator. And here, here add exclamation because we know that the controller is now initialized. Now, in the in state, call the change listener method from socket repository, so that we will keep listening. Socket repository change listener. It will be and inside it right controller that compose Delta. It is again Q Delta from JN Delta selection will be controller selection or else constant O. T election do collapse of set zero. And here, this source will be do change source do Remote. That's it. Make sure you read the documentation of the flutter package, if you have any doubts. Now, inside the fetch document data function, listen to the controller changes so that we can update the changes in everyone's screen as we type. Here below this set state. We have to write controller dot document that changes do listen. Now, we get three data in this event argument. First, one is before, that is entire content of the document, then we get the change, which is only the changes that are made from the previous document or that is if we type another letter, that only that letter will be here, and source that is either it's local, that is we have typed or remote, that is coming from outside. So just right. I event source is the qu to Q the change source, local. Then the map. String dynamic map is equal to Delta event do change, that is whatever we have changed and the room ID. I is widget. Then we will simply call the socket repository and we will send a map. That's it. This is how we do it. L et's test it. If I ask that Now here, obviously you test it, we need to have two chrome websites open. You cannot simply write new tab and all. So first, you do new window, but here, make sure you use guest. Then only it will work or else the same token will be there. Now here type and just type this local host. Press enter. Now, log in with a different Google account, which you have mentioned in the test section of Google Console. Remember that. Log in with it. Okay. Se. Right now, there is nothing obviously. But let's test the functionality. If I click on it, and then copy the document and paste it here. We are in the same file and here if I type hello. Then see. This one also gets the update in real time. That means our socket connection is working and also we can see the changes in real time. And if I hear right, hello, Rahul, then see, this one also gets the changes. Until now, this functionality is also working, that's it for this video. Thank you. 34. Implement Auto Save: Hi. Everything is working. But if we refresh the application, see, then all the type data is lost. If we go back, then all the data is lost. For that, we have to implement the auto safe feature. Let's do it inside the socket repository file. Create a function wide auto safe It will accept map string dynamic data, and it will simply emit an event save with that data so that it can be saved in the server. Now, go to the index JS file to listen to this event. At the top. First, we need the document model. Then here outside the io connection, I will create a function constant save data between Data then get the document. That is a weight document dot find by ID. We will get the room ID in this data. Then we will simply change the document content to Delta. And then write document is equal to await document dot save that set and then inside the IO, we will write socket on if we the save went simply call a save data function with the data, whatever we get. Finally, in the document screen, if you go here in the document screen here in its state. We will call the auto save method every 2 seconds so that it will keep saving whatever we have typed. Here, I will write I will use that dot periodic Then write. Gans duration seconds two. Every 2 seconds, I will call sucked depositor auto save be a string dynamic and we will send Delta. It will be controller, the document dot two Delta and room ID will be get ID. This is the logic. Let's test again, make sure you hot restart and open the app in both tabs. I will just restart again just to be in the safer side. If I go here, copy and paste it here and simply write hello Rahul. I will make it bold. Then with the bullet list, I will write learn letter. Learn No JS and Mongo DB. Se. It is the real time functionality is working perfectly with everything bowl and numbered list. And if I go back and click on this again, S, the data is not lost. If I refresh, then also the data is not lost in both the document. Which means the autos functionality is also working fine. That's it for this video. Thank you. 35. Copy link to share: Hi. This will be the final video. As you can see our application. That is the main functionality of our application is working perfectly. I just want that whenever user clicks on this logo, he can go back to the main screen. And obviously, it's very simple to implement. You go to the document screen, and here in the asset logo PNG. Wrap this widget with a gesture detector. In on tap, call route Master of contacts dot replace with the home route. That's it. If I heart started, And if I click here, see, I can go back. It's just a very basic feature. You don't have to, but I just like it. And finally, I want the user to be able to copy the document link, when he click on share, then he can paste wherever he want and share with everyone. For that to implement, go to the field button. It is this one here in on press, write clipboard set data. Then write clap board data. Text will be our link is a TTP local host document and add the document ID. And then in the end use then and simply show a scaffold messenger that off context that show snack bar. And in the snag bar, tell the person that link copied it will be a constant That's it. This was very much simple. Obviously, if you want, you can use third party packages to share on whatsapp, mail and all. Right now, I'm just planning. I'm just implementing the safe to clipboard. Now, if I click on it, see, link copied, and if I paste it here like this, then I am taken to that document. That's it. This was our application. All the basic functionalities are working perfectly. Obviously, you can do other things as well. It's up to you. But at least you get the basic understanding of how to create such applications using Flutter, no JS, one go to B, and socket IO. I hope you have enjoyed as much as I did. That's it for this complete course. See you in my other courses. Thank you. Have a nice day.