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.