All language subtitles for Flutter-Course-for-Beginners-37-hour-Android-App-Development-Tutorial_en

af Afrikaans
ak Akan
sq Albanian
am Amharic
ar Arabic Download
hy Armenian
az Azerbaijani
eu Basque
be Belarusian
bem Bemba
bn Bengali
bh Bihari
bs Bosnian
br Breton
bg Bulgarian
km Cambodian
ca Catalan
ceb Cebuano
chr Cherokee
ny Chichewa
zh-CN Chinese (Simplified)
zh-TW Chinese (Traditional)
co Corsican
hr Croatian
cs Czech
da Danish
nl Dutch
en English
eo Esperanto
et Estonian
ee Ewe
fo Faroese
tl Filipino
fi Finnish
fr French
fy Frisian
gaa Ga
gl Galician
ka Georgian
de German
el Greek
gn Guarani
gu Gujarati
ht Haitian Creole
ha Hausa
haw Hawaiian
iw Hebrew
hi Hindi
hmn Hmong
hu Hungarian
is Icelandic
ig Igbo
id Indonesian
ia Interlingua
ga Irish
it Italian
ja Japanese
jw Javanese
kn Kannada
kk Kazakh
rw Kinyarwanda
rn Kirundi
kg Kongo
ko Korean
kri Krio (Sierra Leone)
ku Kurdish
ckb Kurdish (Soranî)
ky Kyrgyz
lo Laothian
la Latin
lv Latvian
ln Lingala
lt Lithuanian
loz Lozi
lg Luganda
ach Luo
lb Luxembourgish
mk Macedonian
mg Malagasy
ms Malay
ml Malayalam
mt Maltese
mi Maori
mr Marathi
mfe Mauritian Creole
mo Moldavian
mn Mongolian
my Myanmar (Burmese)
sr-ME Montenegrin
ne Nepali
pcm Nigerian Pidgin
nso Northern Sotho
no Norwegian
nn Norwegian (Nynorsk)
oc Occitan
or Oriya
om Oromo
ps Pashto
fa Persian
pl Polish
pt-BR Portuguese (Brazil)
pt Portuguese (Portugal)
pa Punjabi
qu Quechua
ro Romanian
rm Romansh
nyn Runyakitara
ru Russian
sm Samoan
gd Scots Gaelic
sr Serbian
sh Serbo-Croatian
st Sesotho
tn Setswana
crs Seychellois Creole
sn Shona
sd Sindhi
si Sinhalese
sk Slovak
sl Slovenian
so Somali
es Spanish
es-419 Spanish (Latin American)
su Sundanese
sw Swahili
sv Swedish
tg Tajik
ta Tamil
tt Tatar
te Telugu
th Thai
ti Tigrinya
to Tonga
lua Tshiluba
tum Tumbuka
tr Turkish
tk Turkmen
tw Twi
ug Uighur
uk Ukrainian
ur Urdu
uz Uzbek
vi Vietnamese
cy Welsh
wo Wolof
xh Xhosa
yi Yiddish
yo Yoruba
zu Zulu

Original subtitles

this massive flutter course will take

you from being an absolute beginner to

being able to release apps on the google

play store and the app store bandit is a

very experienced software developer and

an excellent teacher hello everyone and

welcome to this free flota course my

developer expert for flutter and dart

and let's jump and jump right in who's

this course for i designed this course

mainly for absolute beginners so whoever

hasn't even done a written a single line

of code before i actually when designing

this course i designed it for two

specific personas one was a graphic

designer who was working mainly with

actually it doesn't really matter what

graphical tool you're using photoshop

and the other persona was a project

manager who's mainly working with jira

so um i've made the assumption that you

pretty much don't know anything about

software development from before and

even if you're a software developer you

could perhaps jump over the things that

you might know but if you haven't done a

flutter development from before i

strongly suggest that you actually

follow the chapters chronologically

which is the way i've designed this

so um as i mentioned i want when i

design this course i want i wanted

everybody to just follow the chapters

one at a time and one after each other

chronologically so um i highly recommend

that you don't jump over chapters just

because there's so much information

provided in each chapter and i will be

referring back to information that i

provided in previous chapters in each

chapter so i think it's very good if you

can just follow the course the way i

design it to be consumed which is

and what you learn in this course is not

only the basics but you'll also go from

a complete beginner to being able to

applications in apple's app store and

google's play store and we're going to

blend of different tools and software

we're going to be using visual studio

code we're using firebase for the

backend which i'll teach you all about

we're using even figma as a graphic

designer to create our icons and

loading screens so and there's lots to

be learned and i'll take you through

those steps and i don't make any

assumptions about what you may know from

before so i'll explain everything along

the way so you'll go from absolute

beginner to be able to be able to

actually release your two applications

which is the same code base in apple's

app store and google's play store

uh if you if you're attending this

course please do follow me on social

media and i'll really really appreciate

it i'm evan.mp on twitter and also you

can find me by my full name on linkedin

that'd be much appreciated this course

but for those who want to and are able

support me um then you can do that by

buy me a coffee.com van that so without

further ado let's just jump right into

to the first chapter of our flutter

there are so many different topics that

i could choose for the first chapter

however after going through the material

that i've been preparing for you for

this course i realized that one of the

absolute basic points that we have to go

through is the developer accounts

for apple and google now if you're not

familiar with the term of developer

basically what a developer account

allows you to do is to release your

applications on um apple's app store and

as i mentioned in the introduction

you may choose to follow along this

application to the app store and the

even if you do decide to not release the

on the aforementioned stores you will

for the optimal experience of

development for ios and android you will

most definitely need a developer account

i mean it is quite deep to try to

explain the actual reason behind it

from my perspective one of the most

important reasons you may want to have a

developer account is to create the

so every application on ios and every

an identifier which is usually something

called a reverse domain identifier and

some were somehow it was decided that

every application needs to have an

identifier and every identifier is kind

of like associated with a domain name

and a domain name is kind of like a

website for instance if you have

yourname.com uh as your website

you would say that okay i'm gonna create

an application for ios and android in

flutter and i'm gonna call it fubar

it was somehow decided that your

applications identifier would then in

then it would literally be your domain

if somebody knows the reasoning behind

it i would be glad to hear that and i'm

sure that there's resources out there

explaining why that is the case but it

kind of feels like it's become

and we just have to roll with it

the reason i explained the app

when you set up your back end later when

we set up the back end later together

in that the client that we write in

flutter is going to talk with our

backend and store the notes retrieve the

setup also will require you to have your

even though you don't necessarily need

to have a developer account to get an

app identifier because an app identifier

is just something that you decide

okay here's my app identifier i think my

blah blah and even though you don't

actually need a website that's the thing

but an app identifier is usually

associated with a website so don't worry

you don't have to have a website in

order to follow along with these steps

but it is still good practice to create

your developer account in order to

another reason that you will need

a developer account for apple and google

then you will need to register a

use some resources that apple provides

you in forms of certificates and keys

in order to deploy your application to a

telephone or an ipad for instance

and android the world is a little bit

different in that you don't have to do

in order to then submit your application

later so that it can be available for

everybody who has an android telephone

or a tablet you will still need a

it goes without saying that it is a very

deploy your application later to app

it's still a very fundamental step so

i suggest that you actually go through

these steps that i'm gonna provide you

and that's why i actually decided to

sorry i have to just edit my notes a

if you haven't watched the introduction

to this course and you're just jumping

here i suggest that you go to the

introduction and watch it i know it was

about 34 minutes it was quite a long

introduction but there are so many

important points that i feel everybody

needs to know before you get started

with the course so please watch those if

you see me moving my head around then

and i explain a lot of things

that are like the fundamentals of this

all those decisions which i believe are

so important that i still suggest

everybody watched an introduction before

they actually start with the course so

why we need a developer account i

believe i've already covered this

the utility is an account that you

that gives you extra resources as a

developer in order to be able to deploy

your application and deploy your

there are two main types of developer

accounts one is an individual account

and the other one is a company account

for me the biggest difference between

these two different accounts is the

if you register an individual account

then you as an individual are liable for

that application and as users download

your application and interact with it if

they have any problems any for instance

if someone for some reason believes that

you're storing their data in the wrong

way or that you're storing their

personal information without exposing

that and telling the users about that

then they can personally hold you liable

for for instance breach of information

infringements or whatever it is so

just know that you can register yourself

app store apple's app store and google's

but you need to also be aware that

should you wish to do that then you're

personally liable for any problems that

occurring in the future so that's the

or an individual account and as a

based on what type of company you've

you may or may not be personally liable

any damages that may be caused to your

users and if they bring it up to you now

i know this is all sounding a lot

in reality what we are trying to do is

not that big a deal but we are still

trying to store i mean the goal of this

course is to um at this course is to

an application and create an application

that can store users notes notes can be

and you're storing those notes then um

on a backhand that you have full access

so you're kind of like storing user

so it is very important that you

actually treat that data correctly make

except those who are authorized

company account you want to create if

that's what you want to create now

because for instance in sweden where i

a personal company account in that or

sorry a personal company so you can

register a personal company it means

that you are personally liable for that

and you can also create a company that

it's like an umbrella basically sits on

top and then there are people who are

directors of the company and blah blah

so you're not personally liable

and that is the same structure that you

can find in many other countries

and many other countries you can set up

proprietorship or something called

english is not my first language but

it's something like that or you can

create like a limited company that you

have limited liability and you're not

these are the different types of

developer accounts that you can set up

we can i mean that point i think we all

understand now that you can create an

individual or a company account

i think i mean i personally registered

as an ios developer and an android app

and since i registered a company account

i can't go through setting up the exact

but at least i can show you some of the

now you can't see the screen right now

now i'm gonna bring my studio here

and i'm going to make this screen a

little bit bigger so that you can see my

let me also make this a little bit

smaller on top so that you can see

the content a little bit better

so you can see here that there are two

options available to you either you

enroll as an individual or you enroll as

and it is strongly recommended actually

so you need to make sure that you have

two-factor authentication turned on and

so that's that's not a problem all this

means basically as an individual it

means that just you you will need an

account you will need to set up an

however if you want to set up as an

organization like if you have a limited

company and you want to create an apple

developer account that is linked to that

organization is a little bit different

you will need to set up something called

addons or duns or i don't know how you

it's a new thing for me at least but it

is an identifier for your company that

you either have been assigned to already

i think there is a company called dmb

so if we go to let me see if i can bring

learn more if you go to learn more here

is called by done and bradstreet

there then we have uh the ability to

for me i was one of the lucky people to

have already been assigned a duns number

because you either have um let's see if

you see it says dmv may have already

assigned your organization a free uh

before enrolling look up your

organization to see if you have a duns

number so you can just click on the link

you can then select your region for me

it would be sweden then i would write my

some address information contact

whether there is a duns number assigned

to your company so i suggest that you

actually do this by going to this

so that's for a duns number if you

already have one but if you don't have

one then you will have to create

and request a duans number from dnb

i would show you the website for dmb and

my browser is set up so that my locale

is already provided to the browser which

is swedish and then if i go to the dmv

website you're gonna see everything in

and that doesn't make any sense just to

read the information in swedish but

i believe you can go to dmb's website um

duns or dunes or here so this is a

let's see if it can change the language

actually i can see here that they're

very they're actually in sweden

and i wonder if we can here change

if there's any way to actually request a

and i can't see anything related to that

to be honest with you so if you go back

i can see i can request the duns and

so what happens if we just go back to

this url that we were on before

and then i just change the locale

get a duns number okay that's good

and then and you can hear say i'm an

it says look up your organization

when you try to get a uns number

it tells you to go to apple's website

if we say that then okay legal business

so you will you will need to go through

this process which doesn't seem to be

to get a duns number you see requested

the uns number so you probably just want

and i i can't explain this complete

process to be honest with you because

first of all it will be a waste of time

uh because these are so many moving

parts and a third-party company that i

have no control over so if i even try to

explain their process it may change

it's not a good investment of our time

but everybody else has figured it out

and i'm pretty sure that if you just go

and say request the uns number you can

get your uns number but begin by going

you may already have been assigned a

do that first please but but if you have

to request the uns number i believe

there is a little bit of a cost to it

and that is about 70 dollars if i'm 70

to 80 dollars at the time of recording

count with almost about a hundred

uh hopefully actually a lot less about

does that make sense i said so many

numbers seventy dollars at least

try to get your duns number at least

that that's what apple says you will

now of course if you want to register

as a company i can't stress this enough

i remember vividly when i registered

a developer account at apple

and they rejected my request saying that

your website doesn't have any content

and they were right because i just

created an empty website like a domain i

regis i know i didn't actually create an

empty website i registered a domain

and there was no website so when you

typed my website's name it was it would

just not show you anything so

um and they came back and said no your

application is rejected because you

don't have a website what kind of

so then i had to actually get like a

hosting service and i have some content

a website sorry as a company as an

organization you will need a hosting

service you will need a domain provider

you will need to ensure that you have a

website because they're not the same

and you have a domain provider it still

doesn't mean that you have content

on your web page but what i realize is

register your domain and have hosting

service make sure that you have a

content in there say hello we are this

we work with this and this if you have

any questions contact this email and

here's our phone number here's their

address etc so you need to ensure that

an organization it is actually an

organization it's not just like hi my

name is fubar i'm sitting at home

contact me if you have any questions not

and of course after you made your

decision you start the enrollment

learn more continue enrollment on the

and then you come here and you will

basically need to provide your

and continue with the process now we're

not going to go through this but

the important thing i have to mention

go through the enrollment process as a

an apple developer unfortunately there

uh last time which is about a few months

ago when i registered or i had to renew

my registration you have to renew your

apple's developer account you have to

process is not free unfortunately it

last time i registered or renewed my

registration it costs 99 and i believe

it's been 99 for a very long time so if

you're in sweden it costs about a

crowns if you're in england it probably

costs about 80 pounds or something

um and in the us it's about yeah just

count with almost a hundred dollars so

i used to be able to provide this like

you have to have some sort of credit

card or debit card to be able to pay for

um after you've done that after you

register your account as an organization

you will have direct access then

or an immediate access to your developer

account and you can start developing

if you're following along with this um

course and you want to deploy your

application to the app store and play

get your developer account either as an

get that process out of the way because

a developer account especially if you're

an organization as i mentioned here is

not a super fast process i mean when you

get the account then it's simple it's

fast and you're in there immediately but

the process itself is a long process so

um i remember for me it took about two

weeks because i got one rejection took

about one week for them to renew like to

review the process the documents again

is not a fast process uh unfortunately

it's yeah it's just long long

get that out of the way if you can

one more thing that i need to mention is

if you're registering and you want to

sell applications which is not the

purpose of this course but if you want

to sell applications then you will have

so they need to ensure that the stuff

that you're selling in different

then being sent to your bank account

will be accounted for when you're paying

so and i believe that if you're trying

apps on the app store then you will have

to fill in some forms with the u.s tax

i don't even remember irs i think

internal revenue services or something

like the irs i believe that you have to

fill some forms like send the forms to

them then they will come back with some

sort of identifier to you and then you

will need to use that identifier

on apple's website in order to basically

say that yeah yeah i know i'm selling

stuff in the u.s i'm selling stuff in

japan i'm selling stuff in sweden norway

gonna pay taxes for them here in my

country and that's what the form says

here is my name here's my company

i'm an organization or i'm an individual

personal identification number my

um is my address my phone number etc and

to irs and then they come back and say

okay now we know who you are and here is

identifier number like a business

identifier number bin or something they

call it i think i don't remember exactly

but i believe depending on whether

you're a business or an individual then

the number is a little bit different

so if you're a business i think it's bin

and if you're an individual is in i

um i don't know what that dialogue was

some bluetooth devices wants to connect

to my computer i don't know what it is

that's that part it can be long and it's

that was a lot of information um

now uh what we can do now is to talk a

little bit about android as well

the good thing about the android process

like setting up your account for

as a google developer is that it's a lot

more straightforward as you would expect

from google and given that they're um

sending updates to an android app to the

google developer console is a lot more

straightforward than it is for ios i

don't want to scare you but it is a fact

and you will know that later when we

actually get to the end of this course

for ios and android that it is a little

bit more straightforward for google

but you still need to sign up for a

i'm gonna take in my notes uh that i've

what we also need to know is that there

i'm going to copy that and paste it over

here so you see which one i'm talking

then you can see that you can set up a

developer account and once you've logged

in so i'm assuming that you're logged in

then you go to play.google.com slash

console slash user or you zero sign up

what you can do is just google

google play console developer account or

google developer account then you will

end up in a url that looks kind of like

so don't count with this url that i

mentioned here because it may change

you can as it is for ios development you

can either set it up personally as an

individual or you can set up as an

happen to have set it up for myself as

an organization because i do have a

company here in sweden so it is a lot

easier for me to tie all my business

relations with apple and google into one

entity which is my developer account for

it wouldn't make so much sense for me to

explain this either to go through all

the details but if you want to set it up

for yourself as an individual just press

on get started or if you want to set it

as an organization just press get

started there as you can see you can

provide information about your

organization and you can see here as

well as soon as you say i'm an

organization then they say okay what's

uh you can see if i don't have a website

we recommend adding a website that

represents your organization well

kind of makes sense i mean if you're a

company where's your website every

company should have a website unless

you're like a pizza restaurant or

something even a pizza restaurant

probably needs a website but we have a

pizza restaurant here in our town that

and you don't you probably don't want to

say that your company's website is on

and if you say you're an individual then

and they ask for some other stuff

but still interesting because

it says enter the url of your website or

uh so here you kind of have to need

you kind of need to enter that as well

so maybe you can get away with a

facebook url i laughed about it but

maybe you can get away with it i don't

but i don't recommend that to be honest

with you because as you will see later

in the course when we actually submit

our apps to app store and play store

data points that you have to provide to

both stores one is a privacy policy url

the support email and the other one is a

contact email and if you're if you're

setting up a business account

then i really suggest that you actually

set up a website because if you set up a

website and you have a domain you have

an email provider then your email will

professional to set up an email that is

bound to that it's connected to your

email to your domain than it is to say

i wouldn't trust a business that has a

i kind of want to know that yeah here's

a serious business that they have their

own website and blah blah blah

setting up a website setting up some

emails doesn't necessarily mean you're

but it makes it more dedicated if you

the process for setting up an account

developer i think that's that's about it

uh that's all i wanted to mention in

this uh first chapter of our course uh

i highly recommend that you get your

developer accounts for apple and for

what you'll also need to know is that

i mean i've talked a lot about now apple

account and a google developer account

if you're if you're developing uh your

on a windows machine for instance if

you're if you're trying to learn how to

develop flutter applications and you

don't care about releasing your

you don't have to do any of this

just follow along with the course as

if you want to actually release your

most definitely need to also have a mac

because you can't build your application

otherwise there are some tricks you can

photo application then later on like a

friend's macintosh if they have one or

you can send to a service that's in the

cloud and they build the app for you and

then they will send it back to you and

or maybe they even have to submit it

it's a bit hairy to be honest with you

it's it's a complicated topic it is a

little bit difficult to explain

for instance if you're on a windows

machine you can't even have xcode xcode

and the the entire like a chain of

tool sets that gets installed on a

an application for ios platform

now why am i talking about this and

the reasoning behind that is that if

you're developing a flutter application

can be deployed on a windows machine um

macintosh or collectively called as

web android ios five platforms at the

release your application and build it

for ios for instance and test on an

iphone or an ipad you can't do that on a

windows machine unfortunately that's not

there's nothing wrong with a windows

machine it's just apple's fault for

locking down their build systems and all

their tools to macintosh so they haven't

yeah they haven't made the decision to

bring their tool system and tooling to

windows unfortunately or linux

swift which is the language to write

can be run i believe on linux um on

but its main platform is still

i know that this is a lot of information

also to learn but if there is anything i

close this chapter the first chapter of

you can learn flutter and follow along

with the steps i'm going to provide in

this course without having to register

you will need a macintosh if you want to

release if you want to comfortably build

want to release your application on

google play store which is point three

if you want to do that you will need to

register a developer account on google

i believe that's all that's all you need

some of you may already have all these

accounts and don't have to worry about

know all this like if you're coming from

a design and design background if you

all you do is work with figma et cetera

and this is somebody for important

information that you'll need to know

about because i don't want you to get

like frustrated during the process

so i just want you to have some

information so that you can get started

at least without without too much hassle

all right that's it i think for

chapter i can take in my notes that i've

explained everything i want to explain

it's not unexpected to be honest it's a

and i kind of want to take my time with

and for me as well to understand all

so great i think um that's it for this

so i'll see you in the next chapter

hi everyone and welcome to the second

chapter of our course now if you haven't

watched the introduction to this course

i really suggest that you do that before

continuing with the course because there

are so many points that i've explained

introduction that i believe are so

continuing with the course so

in this chapter what we're going to do

is we're going to take care of some

setup steps that are required for

this course and all the other chapters

that follow along after this one chapter

um we're going to talk about flutter

and how to install flutter whether

and we're also going to talk about

xcode android studio and we're going to

extensions to our code editor so

if you're coming from a background where

you haven't worked with any kind of

i'm going to take this chapter quite

easy so if you're an advanced programmer

already you may want to skip this and

you already have like flutter install

everything you can skip this chapter

so let's start by talking about

well traditionally developers and

programmers or software engineers

creating and writing code with their

different languages and then they're

targeting different platforms it's very

important to understand what a language

the the end station where a software

so let's say windows is a platform mac

is a platform linux is a platform and

ios that runs on all iphones is a

platform android is a platform etc

you as a software developer would use in

order to target those platforms to write

software for those platforms so you use

a programming language in order to write

a piece of code and be able to run that

code on that target platform okay

so a programming language example is

um what else is popular right now java

you as a software developer who's trying

to learn flutter would use then dart as

your program programming language as i

that has been the tradition that a

person sits in front of a computer and

says okay i want to write a program for

windows then they go and write some code

maybe they will just use some other

technology i don't know what's out there

right now for windows maybe they would

then they would be done and they will

release the software for windows and be

then someone comes in the project and

says ah we need the same software for uh

macintosh or we need the same software

for instance platform then you would

uh exact same code pretty much for the

so this process would be very repetitive

in that you would have to write the same

software over and over again so

things such as flutter came in in order

to remedy that so saying that a software

engineer sits at home or sits in the

office works with a group of other

people and a designer maybe or a few

designers ux there is a product owner

et cetera and then they would write the

which will then be run on different

platforms so as a software developer you

wouldn't have to maintain different

similar pieces of code that only can be

run on one specific platform so

flutter in its ground basically is a ui

and writing beautiful applications that

run on multiple platforms at the same

developed by google has been in

production for a very long time it's uh

tried and tested it's open source

if you don't come from like software

engineering background open source

basically the code that makes up plotter

contributing to it or maybe just

learning from it so if you're for

instance coming from a background of as

a designer it's kind of like you have

your figma file open to the entire world

or your adobe xd source open to the

entire world for for them to watch what

you're doing as you're designing and

also for them to be able to fix stuff in

your design if they see it not working

so flutter is open source ui framework

what a framework means i mean if you're

not coming from a software engineering

background a framework is kind of like a

as a software developer so you can use

these tools take a bit of this one take

a bit of that one in order to produce an

flutter it in itself is a software

as a framework because of it's a

collection of tools so if you hear a

framework just know oh there's a

collection of things i can use to

that's what flutter is um but

is a programming language language

dart has been in the making for more

than eight years is a language that at

the moment being maintained by google

and also is open source so anybody can

contribute to it anybody can learn from

it and and find exploits or maybe

problems with it and it will get patched

by the public or by google themselves

the language the programming language

that powers flutter you could say

now you know what flutter is and now you

and i think in the next step now what we

or you could just call it a website

that allows you to run or write your

and run it directly in your browser

without you even having to install

anything so just open your browser and

as you will see soon we go to dark pad

and you will see how it looks like so

show you a little demonstration here so

and i can actually increase the size so

you can see a little bit better

i may have to rearrange some components

here on the screen so you can see the

so i went to dartpad.dartlang.org

and you can see here that there is a

program written on the left hand side

what is dark dark pad allows you blah

blah text to be there so you can have

context of what i'm talking about

and you can see that the program is

sitting there and you are allowed then

to either change the program the way it

or click anywhere here to see

or press the run button so i'm just

going to press the run button and you

the text hello got printed to the screen

number of times it was actually printed

it's also printed on the screen so hello

so what you see on this side is the

if you remember from open source so this

programming language called dart

and this is the output of that program

dark pad allows you to write text

here and just execute it and see the

that's what dart is i mean sorry dark

pad is and we're going to talk

about dart and dark pad more in the in

right now what we should do is to start

uh i mean you could say okay but flutter

ui framework how about dart well the way

flutter is packaged by default is that

it includes the dart programming

language and its runtime so if the tools

required to run any dart code

it packages all of that in just one big

chunk for you so you don't have to go

and install different components like

install dart separately in flutter so

let's just then improvise and i'm going

then you go to this beautiful website

i'm going to increase the size here so

and you will see this beautiful website

and what we're gonna do is just to press

we press on get started but this

website looks like this right now maybe

in a few months or maybe in a few years

it will change so you'll just have to

the installation part right now it's

called get started and i can see it's

located as docs.flower dev get started

then pick your platform here i'm on a

macintosh but if you're on windows just

click on windows and then you get

instructions on how to install fodder

and then or if you're on linux you can

also do the same just get instructions

now i'm going to mac and i'm going to

look at this information here i'm going

to increase the size so it's a little

bit easier to read and it says okay

download the following installation

bundle to get the latest stable release

sdk means software development

development kit i believe so it's just

like series of tools for you to use it's

then we're gonna do that let's just get

and it may take some time because it is

uh bit of software as you can see it's

so depending on your internet connection

yeah anything between a few seconds to a

after you've done that then you will

what that kind of means is just i can

see that my mac is already decompressing

this zip file for me so i don't have to

do that myself and it's already

decompressed in this place so i'm just

and i'm gonna show you its content so it

now that you have this what you need to

do is to ensure that all these files are

protected so that you don't accidentally

delete it and it's also a good like um

you know exactly where it is so

by that i mean don't put it on a desk on

your desktop and don't put it in like

documents or anything it's not a

what i like to do is usually to have a

i will open terminal here as you can see

terminal if you're not familiar with it

control pretty much the entire system

if you're on a mac or if you're on linux

or any unix based system and if you're

on windows you can also do a lot with

so in windows that terminal is called

linux and mac it's called terminal

i'm using a a terminal here called i

uh but if you're on vanilla mac os then

you would go and open terminal

like this which is just looking like

so i'm going to open i-term right now

which is my terminal you can open the

terminal that you're comfortable with

i'm going to increase the size of this

my installations for these pieces of

software in my home directory which is

denoted by this little funny character

if i look at the contents of this i can

see i have a folder called tooling if i

and look at the contents of it i can see

for me flutter installation you know

this folder that got in that got

downloaded for me in my downloads folder

i would go and copy its contents

in this folder so if i say cdflutter

and then you can see that i'm in my user

dev folder tooling flutter so this is

where i choose to put flutter now you

can choose to put this downloaded folder

anywhere else as the documentation tells

in the desired location for example

go ahead and do that pick a location and

for me this location works for you it

may be if you're on windows it would

you could say dev backslash tooling

backslash flutter this could be a good

location for your tooling hot photo

i'm imagining now that you've done that

you've gotten a folder and for me it's

this one where you've extracted your

third step you will need to expose

flutter's binary files to your system

and what that basically means is that

flutter as an sdk or a toolkit or a

bits and pieces of software in it and

some of these bits are more important in

that sense that they're actually

whether in macintosh windows or linux

you can have different documents some

documents can be text sound documents

can be images some documents can be i

what else they can be and or a word

document for instance okay because i

or they could be programs a program is

something that you can just double click

on and a piece of software gets executed

and then it will open for instance an

example of the program is a microsoft

another example of program is a google

another example of program is safari

so these are programs and flutter comes

also with its own built-in programs that

do very specific and important things on

recording studio nothing you had to do

these important programs that are inside

the flutter installation which you just

downloaded need to be exposed to your

so that you can work with flutter

if you're for instance from a design

it will allow you to anywhere in your

terminal just write figma and figma app

and that's the same thing with flutter

in this folder you see we're in the

flutter folder where you downloaded your

installation and install it in this

folder there's a folder called bin which

in here there are so many things that

are important to the entire system to

run you see flutter and dart these two i

said so many but yeah there's pretty

so these two binary uh executables need

and the way to do that on a macintosh is

to change your paths as is documented

so the way i like to do that is i go and

so if i do a vim and look at my zsh rc

i can see my paths and you can see it

so you see i've actually put that export

this may be a bit intimidating to be

what all it's doing is that you see this

placed here i don't know if i can

actually zoom into it and if you can see

i don't know how that looked in the

a sort of like a set of instructions to

my terminal on this macintosh to tell it

binary executables are placed such as

dart python etc etc so when i install a

uh in this way you see we just

downloaded a package and just put it

somewhere on our computer uh macintosh

won't know about the stuff that's in it

of course it won't so you have to tell

because otherwise if you don't do this

step if you don't do the step three then

every time you want to run flutter then

you have to specify exactly where that

is so for me it would be in my home

folder dev tooling flutter being slash

but if you do this then you can anywhere

in your terminal just write flutter and

windows computer will know where to find

do that put put these instructions as

and after doing that you may need to

reload your path using a command

depending on which shell you have you

put that instruction in somewhere else

you will have to modify your um

i remember this from many many years ago

let's see if you have to do that

if you wish to run flutter commands in

regular windows console take these steps

blah blah from the start search end and

select edit environment variables for

what you'll just have to do really is

just to follow these steps i mean i'm

going through basically giving you some

of these instructions so you can get

like a head start but these instructions

can also change in the future so don't

rely just on what i'm telling you please

just go to the installation website here

uh here as you see docs flutter dev get

and try to follow along with the

you should be able to be anywhere on

now fluffer doctor is a very important

it looks at your flutter installation

and it kind of makes sure that it's in

good health as denoted by the word

because fluttering itself is a framework

and it depends on many other bits and

which your computer may need to have in

order for flutter to actually work

flutter doctor will then go through a

series of steps to ensure that first

flutter is updated and that you for

tool chain that you have xcode installed

i mean this result at the moment looks

quite fine on my computer but if you're

running flutter doctor for the first

time on your computer you may get a few

problems uh some of the problems that

you'll experience probably is going to

sdk couldn't be found xcode couldn't be

because if you're running flutter on a

windows machine or linux machine then

you can't have xcode xcode is like the

and only runs unfortunately on mac os

mac os ios and ipad os pieces of

software so although you can run flutter

windows machine without a problem you

test your flutter code running on an

iphone unfortunately unless you have

and the easiest way to get access to

that is of course to have a macintosh

and that's unfortunately because

it's uh it's just not available for

you've run flutter doctor and it's

it's basically gonna tell you that okay

now i'm gonna assume that you're on a

macintosh it's gonna tell you that okay

uh xcode for instance uh you need to

install xcode and the way to do that is

you need to open app store on your

computer and just type xcode here

and go and install xcode on your

so depending on i don't know which

version is the latest at the moment but

if you're trying to develop flutter

applications that and also make sure

that they run on your ios phone or the

then you need to install xcode if you're

on a mac sorry if you're on a linux

computer or windows you don't have to do

this step actually you can't do

you've installed develop developer tools

for xcode so let's see how we can do

from terminal there's a command that you

in order to do that and that command

i will zoom into it so you can see

it says sudo xcode select install

so you need to issue that command in

your terminal so if i do that and it

says what's the password i'll enter my

and it says they're already installed so

if you haven't done that please go ahead

and execute this command in order to

install command line tools for your

now the next piece after xcode that you

let's see if i can actually bring up

so we've talked about flutter doctor

that was flutter doctor and we also

talked about installing xcode so i'm now

bringing that up a little bit late

and but now the next step is to install

what android studio is is like the

equivalent of xcode but for writing

android specific applications now

for in order to write flutter

applications you don't need android

studio per se but you kind of need the

for programmers they provide you with

something called an sdk just like

ios and android also provide you with

and since flutter utilizes these native

capabilities of each platform in order

to for instance create an application

that's compatible with ios or android

it will utilize the native uh components

or sorry or the native pieces of

sorry mainly called ios sdk and android

so you need to download android studio

so you get access to the sdk manager so

you can install an android sdk

now xcode in itself when you download

the latest version of xcode it comes

with the latest version of the ios sdk

but android studio doesn't do that

wait a minute yeah it probably does in

the latest versions but we can check

so if you go to your browser and just

developerandroid.com let's just go there

and then you can just click on download

android studio and then there are

download options and you can see there's

available for windows mac and linux

then please go ahead and download uh

your android studio and i can see the

for macintosh is a package so you can

install it easily you don't have to

unzip anything and for windows is also

like an executable so tar gz

now let's say that you've done that and

now after doing that then you should be

when you bring up your android studio it

will just pretty much be empty here

on the screen and you'll get some tips

and tricks how to use android studio but

the important thing for you here is to

the android sdk so if you go then to

i believe there is an sdk manager right

so just ensure that you have

an sdk installed for me i have android

installed here so ensure that you have

one of these sdks ready for you to use

and as soon as you've done that then

the part about android sdk is going to

so that's that so we've talked about

android tool chain which is the android

we've talked about xcode chrome is just

a web browser if you want you can have

that if you're developing app flutter

applications for the web it kind of is

and then this you're probably if you're

just getting started with flutter you're

not going to have this vs code part

a a code editor an open source code

and it is the code editor that i'm going

to use for the entire course for this

entire course as we go on and to be

honest with you i've tried android

studio and i've tried vs code for

flutter development and i can highly

recommend that you use vs code

just for its sheer performance it's for

its ability just to really focus on a

simple editor without bothering you with

lots of bells and whistles so

it's a preference though some people use

android studio for flutter development

and some people use vs code so

one is better than the other it's

so that's for android studio and the

android sdk so now let's go ahead and

install visual studio code which is the

tool that i'm going to use for this

let's bring up a new window and i'm

going to say install visual studio code

and i'm going to bring the window up

and you can download the one that you

prefer for your computer i've chosen mac

and for me specifically i have a

macintosh with an apple silicon so

i then choose this one mac with an apple

silicon and then it's gonna download

that for you automatically so it's just

about 200 megabytes i think or actually

100 megabyte only after you've done that

on a macintosh you would go and

in your applications folder so i'm

actually gonna delete that which i

downloaded just now because i already

so that's for visual studio code um

talk a little bit about um some

extensions that we're gonna use in

visual studio code so let me bring up my

you know we don't need that let's go and

bring up visual studio code um and then

i already actually have so many visual

uh but i can just say new window so you

see how visual studio code looks like

let's see don't show again okay so this

is pretty much how visual studio code

looks like so it's a very simple

um now what we need to do for this

example is to enable a few extensions

now the first section extension that

we're going to enable is called arrow

lens and you need to go here on the left

hand side find extensions and just type

and just say airlance just like that

click on airlands and just press enable

or install i believe it's called so

error lens allows you to see errors in

line without you having to click on a

it expands the entire error as you're

coding you will probably have some

errors in your code that error will be

then displayed right there in front of

your face in its entirety so you don't

have to press a little small button to

be able to see the complete air

so it's a fantastic extension

now the other thing that you'll need is

something called a bracket pair

colorizer and that bracket pair

colorizer is something that is already

installed in visual studio code

it used to be a an extension that you

could download but it was so popular

that microsoft has added that internally

to visual studio code so you don't have

to do that manually sorry by installing

now that we've talked about that the

next step is to actually install flutter

button i've already installed that so

there's a disable button for me here

extension and then you'll also need the

dart extension so just type dart and

we also need to install another

great extension called block bloc

i'm not going to go into the details of

what block is because we will learn

about block a lot later in the course

extension to have as we go on you're

i can't really explain exactly what it

is right now but just install it and i

will tell you more about block later in

that was basically installing a block

when you start up your visual studio

code it probably doesn't look like the

and that is because i have a custom

theme installed on my visual studio code

and scenes in visual studio code can be

installed just like you install an

extension so if you like my theme you're

more than welcome to go in into

extensions and then search for tokyo

it has different theme colors as well

this is the one i use tokyo knight

actually i use this one tokyo night

so if you want that theme please go

and now that we've talked about that we

the last point that i wanted to discuss

in uh before we wrap up this chapter

now that we talked about a little bit of

setup for setting up your flutter

installation and setting up your text

editor which in this case is visual

in the next chapter which is chapter 3

dart programming so before we actually

jump into writing flutter applications

we're going to talk about how to write

or at least understand like the basics

so without further ado let's close up

this chapter and i'll see you in the

hello everyone and welcome to the third

in this chapter i thought maybe we could

focus a little bit on um actually not a

little bit but quite a lot on dart

as you know from the previous chapter we

know now that dart is the programming

it would be a good idea for us at least

to get a little bit of introduction to

dart how it works a little bit of its

different data types functions methods

this chapter as well um just like the

entire course i'm kind of assuming that

you haven't done any programming at all

before so i'm going to take things

very slowly uh take the concepts one at

a time introduce them to you

and i will give you some references to

read more about the topics as

that much of a time in this course to go

into detail about everything so

basically get you started with

dart uh and writing your apps then later

in order to do that we need to have a

and by project i mean you need to have

some kind of a playground set up so that

dart code and then you can try it on for

instance a telephone or a simulator or

um a lot of people would rather go to

dark pad as we saw in the previous

chapter and start writing their code in

that's one way of doing it but since in

this chap in this pro in this course

an application release it for ios on

um it is safe to say that that

we can literally start actually creating

so that we can then later build upon it

rather than writing all our code in dart

you can then by doing by writing your

code in an actual flutter project you

can get used to how we work with

so i think this is a little bit of a

time invested into later chapters as

well where we're gonna work and continue

working on the same project so we have

there is a little bit of a value in not

test code like what we're doing in this

chapter with what we're going to do

in the actual application if you know

so i think it would be better now for us

to set up just a test application

keep working on it and then later on

when we start doing the actual

application then we create a separate

do that together so i'm gonna bring

my face down here so you see the entire

i'm then going to create a new terminal

window and bring it up here on the

screen so you can see it and i'm going

to increase the font so it's a little

bit easier to spot what i'm typing

so let's go to a folder where you try to

uh projects for me i go to dev projects

and i have a folder there called flutter

then in order to create a new flutter

what you have to do is to issue the

and this create command is already

shipped inside flutter so if you say

this is going to go and find the actual

flatter binary if you remember from the

previous chapters where we installed

it's going to find the flutter binary

call the create command on it so if you

provide it with some sort of a name of a

that's the binary that's the command and

that is the name of the project okay so

uh this is the easiest way to create a

new floater flutter project in my

opinion at least so let's execute that

and what i'm gonna do then is to as you

so let's go and i'm going to say

and then i'm going to issue a command

i can actually bring this a little bit

to the right so you can and also

do like this so you can see what i'm

code dot and what code does is that it

brings up visual studio code so it's

command that you can issue in order to

bring a visual studio code and

if if i just bring up visual studio code

and for instance you can see it you

can't see it right now but it's because

i have a separate uh screen here i'll

bring up visual studio code as you can

there is a good extension where there is

for visual studio code to install this

shortcut for you in terminal in your

path so if you say which code

it just says user local bin code

so it's just an executable that allows

you then to open up visual studio code

with a path like so you can say open a

visual studio code in this folder

and you can do that in visual studio

code you can allow that to be installed

by doing um command shift p on macintosh

or control shift p i i believe in

and there is this little command here

that says shell command install code

command in path so if you execute that

once then it's already set up for you

you don't have to do that anymore so if

you'd like to be able to say code

within visual studio code without you

having to open visual studio code

manually and then doing file open

then i suggest that you do command shift

in visual studio code depending on which

operating system you're using and then

choosing shell command install code

command in path so i've already done

that so i can just say code dot

so as you can see this is the basics of

um flutter project that you create with

flutter create now visual studio code

has a built-in terminal so i don't have

to have this terminal window open

anymore so i'm just gonna close it okay

and i'm gonna make this full screen

increase the size a little bit so you

can see better and perhaps i could even

logo on top right so you can see the

content a little bit better as well

in order for this flutter project to run

application and like keep testing your

you would have to select a target and

you do that with command shift p

choosing flutter select device so you

can just say flutter select device

command shift p is on macintosh and ctrl

shift p i believe is in linux and

windows so do that command shift b is a

very important command you're going to

use it quite a lot in this course so

um then i'm going to say select device

since i'm on a macintosh and as you saw

earlier we have xcode already installed

xcode comes also with the entire ios sdk

and also with the simulator i can choose

to run our application on ios simulator

or i can choose to run it on an actual

i believe i don't know if you've talked

already about scrcpy to be honest with

search in my notes um to see if you've

if you just give me one second i'll just

check here i believe we're we're gonna

set it up in chapter six so we haven't

set up scrcp cpy yet so for that purpose

i'm just going to say select device and

i'm just going to say start ios

simulator so that is going to as you can

see start up by your simulator and that

for now is like the best way for us to

while this is connecting um i can show

you a little bit around as well

we have as you can see lots of files

here already created for us we're going

to go through some of these um

but one of the most important files that

you're going to need to get used to used

to is this lib slash main.dart and this

is where like the majority of the code

uh this is his contents at the moment um

let's see what it's doing with the

simulator i'm just gonna have a look

it's taking a little bit longer than

expected so what i'm gonna do is i'm

kill the io simulator manually this

shouldn't this usually doesn't happen

but that's okay if it does happen then

you know how to deal with it just close

go to command shift p select device and

then start ios simulator fresh so it's

okay so that's our simulator and i'm

actually going to decrease the size of

this a little bit since i realize that

this is our main dart file this is like

command line um command has created

it is the file that has been created for

us so we don't have to play around with

it too much to be honest with you at the

um for the purpose of this chapter we're

basically kind of like exploiting this

uh code so that we can inject our code

into it so we can learn dart a little

bit so you don't have to understand all

of this code the way it is right now

there's lots of comments and etc so

that part so now that we're here and

then you can see we have a little

simulator here and in order to run this

application on this simulator since

you've already done the flutter select

you just go to run and you say run

without debugging for now so

is already selected then it understands

that it needs to compile this project

and we're just going to give it some

time depending on your machine and like

what you have for specifications on your

machine this this command could take

a couple seconds to maybe 30 seconds

or even more and i'm not sure how long

it's going to take for a fresh flutter

project to be honest with you to start

running on the simulator but it took

about 21 seconds so or 22 seconds so

project now and this is like the basic

flutter project i'm not going to go into

details about how it works but you can

press the plus button if you want to so

but what i'm going to do i'm just going

to close this widget inspector that was

automatically and i'm just going to

bring this a little bit down so that we

can see the debug console okay

that's for setting up our project so

that part is done now the first thing

dart is the concept of keywords

now since i'm assuming that you haven't

done any programming language in any

you need to understand what keywords are

important in understanding any

programming language basically and

cannot use for anything else than what

the programming language intends those

i mean there's no real good analogy in

like if you're coming from figma if

you're coming from a design world what a

key word could be because in a design

world you're not really talking

in terms of code with your product or

software where you're designing your

when you come to programming language as

words mean stuff in in a programming

language so a keyword is as its name

indicates is a word that has a special

meaning in that particular particular

i provide a link here for you that you

can check out but i'm going to open it

bring it to the screen here increase the

size a little bit so we can see better

uh have a look at my screen here yeah

and you can see this is a part of the

documentation for dark programming

language that explains what keywords are

in dart and you can see there are some

words that have special meaning like

so you can say that the language the

dark language is made out of these

keywords that is pretty much it it's

just like series of keywords like the

things that you tell the language that

hey i want to do something and then it

says okay what do you want to do then

you say okay i want to do this or this

special words for the programming

language so that it understands what you

for now we don't have to really go into

so much more details about what a

keyword is but for now just understand

that a keyword is a special word

language's brain kind of so that you can

talk to it it's your interface with the

programming language to make it

understand what you want to do okay

and please check out the link that i

provided here to understand more about

okay so we've talked about keywords i'm

just gonna check it in my notes so that

we know we've talked about it

now the next concept that we need to

if you for instance come from a design

background then you have different tools

to work with for instance you may have

in your design system whatever you're

using if you're using product from adobe

or if you're using for instance figma or

visio or whatever tool you're using then

there's like a set of components that

you can work with for instance you can

drag in a text field or you can drag in

an image field or sorry an image or you

assign a color to a text so these are

all like things that you can do with

now a data type in in a programming

is that type of a thing for instance you

i have some data in my mind okay what is

of my friend okay his name is uh

and then you would say okay what type is

jack is it a number no is it like um

is it a list of things well yeah it's a

uh okay then it's that is this data type

okay what is 37 is it a list of things

well yeah it kind of is a list of

list of digits but it's also in itself a

then there has been this convention like

convention in different programming

languages and every program language

language pretty much that you can use

these days has this concept of data

types data type is as its name indicates

a specific name assigned to a data

that is bound to be of a specific type

as well so for instance in dart you have

data types called integers or you have

strings or you have arrays and sets

which we'll talk about soon but

a data type just for now though it's

just a stamp on a piece of data to say

that you're of this specific type

you could think of a data data type as a

nationality you could say like every

person coming from sweden is swedish

boom that's his data type so it's just a

categorization of data based on their

appearance or based on what they

for instance you can say here's a

university full of engineers and

these are software engineers these are

mechanical engineers so the software

engineer is a data type it or is a

person type a category type so putting

categorization is kind of what data type

you just have to know that it's just a

categorization of things based on

and there's and there's a website that

you can read about uh dart data types

i don't know if you've i've if i've

on the link below as you can see dart

um and here you can read more about dart

but we're not going to go into so much

detail about all these right now just

data type in dart is or any programming

language basically that has data types

data based on their appearance or

something called constants in dart

usually in programming language

uh let's say for instance the value of

it cannot be changed 10 is 10 and it

or your name that is a constant although

you can go and change it but as long as

that is your name it is a constant so

there are so many values that can be

constants which will actually be quite

abstract for me to be able to explain

right now but just know that a constant

internal data cannot change during

during where you're writing your program

and also during when you're running your

um that is kind of what a constant is

uh but there is also this uh notion of a

compile time constant and a runtime

you don't have to know about

like those different types of constants

right now just because like in dart a

constant is a constant whether it's

compile time is constant it's just just

a constant as you'll see soon but

i still believe that it's important to

understand the difference between

when you're talking about programming

and when you're becoming software

developer and i hope by the end of this

course you'll actually become a software

developer if you're not already um that

would be really amazing uh but

the notion of a compile time and a and

runtime is very important to understand

make a distinction between whether

something has happened during compile

time or something has happened during

or before i explain compile time maybe i

should explain compile compile is where

you take the program that you're writing

and you tell the computer that i want

so that process of packaging things up

in very simple terms it's called

compiling or a compilation okay so

from where you start writing your

program with the hand with your fingers

until where you package it you're pretty

but when you run it like we're running

that session from where you start

outputting your program into this device

and for it to run your program from that

you haven't compiled time and runtime

and a constant is a value that is the

same during compile time and runtime so

its value doesn't change so the value of

10 is 10 while you're writing your

program and also stays the value of 10

very simple explanation of a constant so

project that was created for you by

in this in this line of code as you can

see it says void main we're not going to

talk about exactly what that is but just

press enter at the end of it and just

and i'm going to tell you what final is

and just saying name is equal to foo

there's lots going on in here and i'm

what is actually happening here

but i before before we actually go

through all these details let's let's

add something here called a constant so

i'm just kind of saying const age is 27

or yeah 27. as you can see this is how

you write code in dart you start by a

keyword usually or a variable name or

something as we're going to talk about

is following here is a name right after

cons i'm going to write some name

and in that name then i'm going to

basically say okay i'm adding the value

h i'm sorry about this my dog also

what is happening here is that you're

putting the value of 27 into a constant

and you can refer to this age later for

you can say is equal to age multiplied

by two and this is also constant because

at compile time word dart is basically

trying to understand what you've written

it says okay you said 27 and then you're

saying 27 is a constant so its value is

never going to change and if you tell me

multiplied by 2 that also is a constant

both this side and this side are compile

so that's that's what we mean by a

constant it's a value that is specified

during compile time and it and it cannot

also it's important to know that notice

sorry i have to just take some items in

my notes to make sure that i've

explained all of those to you um

you can see here that every line of code

in dart needs to end with a semicolon

and that tells dart that yeah you're

starting a new line of code of course

you can put two lines of code like this

there is a program automatically running

in the background which is called dart

fmt which is the dart formatter which is

going to format your code and prefix it

so if i like put a lot of spaces in here

doing command s on mac or control s on

linux and windows upon saving dart

formatter is gonna kick in and format

those are constants so we've talked

now let's talk about variables a little

a value that is not a constant

i mean i think that's like the

simplest way of explaining what a

variable is um a variable as a name

and that means that the data that it

holds it doesn't need to be constantly

from where you start the program you may

assign a value to this variable and you

may also change that variable depending

on what type of variable it is

a final variable in dart which we'll

before we do that let's go to this main

function here and you could just say um

and here what i've done is that i've

whose value is foo or let's just say

and semicolon to end the line now if i

want to change this value all i could

say here is to say name is equal to

now this is basically us assigning a new

value to this variable saying anthony

so you could just say final name equal

to alex and it's it's a little bit

strange because final is also a variable

whose value cannot be changed so you may

be like okay what like what kind of a

now there's a little limitation because

you you may try to like say const

as you will see later in in the

final gives you the flexibility to

assign a value to your variable

a little bit later maybe in the process

but it still indicates to dart that the

value of this variable is not gonna

change after it has been assigned to

yeah it's it's it's just a little bit

confusing maybe at the moment so let's

a variable is like a constant but its

value can be changed let's just leave it

okay now that we talked a little bit

variables let's talk about functions so

um i didn't specify exactly what this is

just because we hadn't really come to

of code is a grouping of series of lines

of code one to n number of n lines of

and it can it has a few properties uh

one is its return value here indicated

the other part of its information is its

followed by a pair of parentheses

an open parenthesis and a closed

in which you will write something called

a box where you input things in it it

does some processing and then it outputs

that stuff whatever it wants to output

what we could do here is to create a

very simple function for for ourselves

as you see as you saw before or as i

what you write for a function in the

beginning is this data type i mean what

data comes out of this function

someone's first name and their last name

with a space between it so if i say foo

as the first name and bar as the last

name then the full name should be fu bar

as i said then you need to specify the

data type first what you're gonna return

and if you looked at the documentation

that i provided earlier there's a data

which is a series of characters

basically it could be a name a family

name address of your house or whatever

and that's a data type is string okay so

we say we're outputting string and then

you say okay what should this function

there's a convention in dart that your

functions should follow a camel case

naming convention basically in camel

cases if you for instance say

in english my function should be called

that's my function name but you cannot

have spaces in your function function

names in dart or pretty much every

programming language that i know about

remove all the spaces and then except

change all because uh cons all the other

uh first letter to uh to uppercase so

it was like this before you could

actually change them to uppercase first

and then remove the spacing so this is

this is how you should write your

we said that we also have to open

we need to uh specify somehow that we're

going to accept a first name and a last

what kind of a data type does a first

it's kind of like a string it's a name

it's a series of characters so let's

and then we want to take a first name

and we know about camel case now so

and then you want to go to the next

you take the first name and the last

now we also said that after the

parenthesis after you have accepted your

parameters you want to go and create

like your curly brackets here i don't

know actually if i mentioned that before

its body or its logic it's either

greater than sign which we're going to

is by curly bracket so we're just going

what you want to do here you want to

take the first name and add a space to

the first name and then follow that by

you need to you you need to tell dart

that that is the data you want to return

there's a keyword called return that

tells dart that you want to return some

then what you're going to do you're

going to say i want to return what the

first name and i want to add a space

this is a very simple implementation of

however there's there's actually a

better way of doing this in dart and

i'll explain it to you right now and

that is by formatting your strings

tell dart kind of like how your result

looks like and you want to ask dart to

insert the first name and last name into

and that's how you'll do it like this

okay i want to return a string denoted

by the single quotation marks here and

you can also do a string in dart with

double quotation marks but i'm going to

explain that a little bit later

return the first name in here but if you

what's going to happen here is that it's

actually going to take this first name

has you written in the string so when

you get this return value it's actually

not the value that you pass to this i

difficult to understand when i say the

value that you pass to this what does it

uh so let's put this actually to test

build function as you can see here on

line 16. now it may not be on line 16

for you but for me is at the moment on

line 16. just find this class my app

stateful stateless widget and find this

widget build stuff that's written there

what do we call our function get full

and it says okay what's the first name

semicolon so and ignore this call for

now sorry this uh warning avoid print

calls and production codes so

now we're calling that function this is

it's i mean it's called calling it's

it may have other names but usually

programmers call this calling call the

these are the parameters that you're

in in the programming world to explain

these parameters like with with name and

that is called a parameter or an

the meaning of them is kind of like

getting uh convoluted in to the point

that no one knows which one is which but

you could just use parameter or argument

and everybody would understand what

you're saying so but there's a little

bit of the difference which i'm not

going to go into the detail of but if

someone just says call this function

with parameters or arguments you know at

least what you're doing okay

now we're printing its value all you

have to do in order to execute this code

is press command s and you will see the

as you saw i didn't execute my code

again i didn't press like the run button

triggers an action called hot reload

hot reload in flutter is it's a whole

which i'm not gonna go so much into

detail of but what hot reload does

in your code hierarchy without

complicating it too much i'm just trying

it looks for changes that you made to

the code and executes only those changes

and in the process of executing those

changes it might execute everything else

by doing a save this function gets

called somehow magically which i'm not

which in turn then calls or invokes our

function called getfullname and

its value will then be passed into

another function called print

uh and as you can see the result isn't

really what we expected it just says

and that is because here we said return

first name and as you can see if you put

first name like this inside your string

it becomes its own string it has nothing

if you remove these quotation marks

then it says oh first name is this

you see it actually highlights it so

then if i press command s on mac or

control s on linux and windows you will

foo being printed to the screen

you can also say last name here and it

and know that no also notice that when

i'm changing these things it's not

executing immediately automatically i'm

pressing command s so just keep that in

that's for a function and but before we

move on explaining the basics of a

function i want to also explain

string formatting and that is we said

that we're going to put first name and

last name because this is what we did in

the beginning first name plus space plus

last name and this wasn't so pretty

because it's like doing string

concatenation in a very old-fashioned

matter in a very old-fashioned manner

yeah i think i said it right the first

but what you want to do here is to

uh use uh garth's built-in formatting

capabilities and you do that by first

saying that okay i want to return some

and i want to have first name

last name but as you saw this earlier if

it just returns those strings exactly as

i've written them not the parameters

what you can do is just to put a dollar

and you can see their coloring now

changes depending on the theme that

you're using or depending on the text

editor that you're using if you're using

android studio it may not color it the

same way or if you're using visual

studio with a different theme on a

different maybe platform you may not

even change the color but for me at

least you can see that the change the

colors change so as to indicate that now

the string exactly as you wrote

except on returning the parameters

and now you can see that the result is

so that is the basics of functions in

from functions i also want to explain

um a function doesn't necessarily have

you may have a function here that wants

uh the screen or to here to the debug

console and you can just call it

i can just write the name of the

data type to be returned but it's a

little bit of a convention that you

actually tell dark that this is a void

meaning void is a key word as we talked

about it earlier in the beginning of

void is a key word telling dark that

this is a function that doesn't return

dart is completely fine with this

function being completely empty meaning

that well yeah you said you're not

returning anything you're probably just

gonna do some stuff in here so i'm not

gonna bother you with some errors saying

but as soon as you change the return

value or the return data type of your

function to for instance string

saying that oh yeah the body might

complete normally causing null to be

returned blah blah you don't have to

know exactly what that means but

essentially what that means is you're

telling dart that you're returning a

string but you're not returning anything

looking for the return keyword

saying that oh you missed it so you

could silence that uh error by saying

i think this pretty much explains the

functions to be honest with you

there's lots more to learn about

functions and as i said functions can

this syntax is used when your function

it doesn't need to break into different

by a semi-colon so a function who has a

very simple logic you can just skip

and you can just say you see i will

remove the closing curly bracket

and then you can remove the return

that is a shorthand it's a function

simplify kind of your code some people

may like it some people kind of may be

code into two different styles some

functions are with uh curly brackets

some functions are with this pointer

thingy and uh kind of depends on your

and you on you and your team to be

we software developers like to follow

the developers may decide okay we're

just going to go with this convention

involves the ability to have both

complicated and simple return statements

in a function it's actually preferred

as a convention than using this syntax

simply because this syntax doesn't allow

you to split your code into separate

lines of code it has to all be in one

statement so if that makes any sense

so i think i think that's it for

functions and now we've talked about

functions arguments return values

we talked about variables constants

these are such important parts of

learning how to program with dark and

flutter that i think you need to spend

some time and experiment with them so do

some experimentations on your own for

not don't take just the first name and

last name just take for instance

someone's address someone's age

different play around a little bit with

different data types like integers

different numbers have a look at the

earlier which was here i'll bring it up

have a look at this link and have a look

at the different examples of different

data types because in this in

upcoming chapters and in the uh rest of

this course we're going to play around

with a lot of different types of data

so i think it's important that you have

let's leave this chapter at this point

and then in the next chapter we're going

to talk a lot more about more advanced

dart programming language features so

thank you for joining me for this

chapter and see you in the next one

hello everyone and welcome to chapter 4

in the previous chapter chapter 3 we

talked about keywords data types

constants variables and some basics of

and in this chapter we are going to

as you can see on the captions here

we're going to focus on control

um i'm assuming you're following these

um chronologically so that you're like

one by one so i'm assuming then that you

have your uh dark project set up and

that you've got some sort of a simulator

without further ado let's have a look at

bring up the captions here and then i'm

gonna put my face at the bottom there

and bring up our project that we created

up here so this this is running at the

moment so if i do a command s or control

then as you can see here there is a run

it's just gonna do a hot reload which in

turn calls this build function which we

don't yet know really how it works

because i haven't really explained it

called a print function here and then

our get full name function so

what i'm going to do here is let's

and let's remove everything that we

wrote here as well so keep the main

function as you can see here and then

keep your stateless widget which we're

going to talk about later okay

so instead go and create a new function

and then in the build function just say

the purpose is that in this function

we're going to write most of the code in

this chapter so we are going to

basically test some code that's the

let's talk about if and else if and l's

most programming languages that allow

branch your code based on a condition

so if we for instance in here create a

variable whose value cannot be changed

if you remember from the previous

chapter whose value cannot be changed

and end it with the same semicolon

an if statement basically allows you to

check the value or a condition

then it allows you to execute some code

append an else statement to it which

gets executed if the code or if that

condition is not met i'm going to show

the syntax for an if statement is just

and then you would open and close

parenthesis and then you would put curly

brackets like this that's the syntax of

if and in the parenthesis you would put

so i would say in this case if name and

i would like to for instance check if

uh we haven't come to operators yet

we're going to talk about operators

but this is um as you can see here we're

saying final name equal to foo this is

an assignment uh operation and that is

an operator in dart it's called an

and since this is an assignment we don't

want to actually assign anything to name

you want to check if it's of a certain

that is with this conditional operator

and then you will just say okay if it's

and then a semi colon to end it however

if this condition is not met you may

want to execute another piece of code

and then you can just do else

and then this would you would just say

all right and a semicolon so i'm just

going to do command s and you can see

the value or the string yes this is food

printed to the screen or to the terminal

you can have multiple statements in here

so you can have more print statements in

here you can just do anything you want

now there is a possibility to write if

the curly brackets but you don't see

them that often and i recommend that you

actually always try to as a convention

do with curly brackets if you can

however it is possible that inside a

code base that you will work on with

your colleagues it is decided that it's

okay to have if statements without curly

brackets where there are very simple and

an example of that you could just say if

you would just say print yes this is foo

and this is completely accepted as well

okay i want to have another line print

you can see it goes to the next line

will be executed no matter your

condition up there so this is completely

detached from your if statement up here

and i just realized that it is quite

important for me to be able to show line

and by default your editor probably has

line numbers enabled i usually disable

when i'm working myself basically

but when talking about code with other

people it's quite useful to have line

numbers because i can then tell you oh

look at line nine or look at my line ten

that's the basic of if and else

now you can also have if right after

an example of that is for instance to

and then you do some code all right

after the curly bracket then you would

and then you can then say another if

parenthesis and a curly bracket if you

it is the exact same syntax as it as it

so there's pretty much no difference you

and then you put your condition in here

and then you may just want to say is not

it's uh basically is a not operator so

it's checking to make sure that this

of the value that you provide to the

and then you can wrap it up and you can

accidentally ran into this issue

as you can see now the editor is kind of

going crazy and darts not understanding

as we talked about it previously um

strings in dart are preferred to have

to be kind of like created with single

if your string in itself contains a

single code for instance in this case

contains a single code then dart kind of

gets confused like okay does the string

up until this point is it's a green so

it's thing it's thinking that oh the

string ends here but what is all of this

there are two ways of fixing that either

that is a software kind of development

lingo escape kind of if you hear that it

pretty much just means that you're

that dart understands that you don't

mean it literally you don't mean that

i want to end my string here except that

this needs to be escaped and put in the

string as its own value basically it's

kind of difficult to explain but i think

you know what i mean um so that's one

way of doing it it's a little bit dirty

in case you run into this issue it's

best to actually wrap your entire string

in double quotes and this way

then dart understands that whatever

comes in here is okay like a single code

unless you actually want to have

double quotes in your string that is

enclosed with double quotes again so

you'll see if i put a double quote here

then dart goes crazy so you can escape

so if you have single codes and double

quotes in your string then you will have

to kind of pick a convention either you

enclose the entire string in single

inside that string and let the double

quotes live or you enclose your entire

string in double quotes and then you

escape your double quotes in the string

i hope i hope that makes sense

um if and else in um in a nutshell

but before i move on i kind of want to

explain an important concept here in

that when dart executes this code it

kind of goes by line by line so it

starts with line seven the execution of

function and then it come comes here and

it says okay name is foo all right

and it's actually saying that we prefer

const so let me change that to const

all right then it comes over here but

let's just change that to foo with

yeah let's no let's not do that let's

keep it as foo so it says if foo is if

name is food then it says yeah that's

and then it goes here however as you can

then it should execute this as well

and you can see that foo is not bar so

however this this this will never be

when dart goes inside these curly

brackets then it says okay i did what i

had to do i did my print statement the

so if an if statement is kind of like a

it puts a stop when it when it falls

into one of these if statements it kind

of says okay i did my job in this entire

if else block then i will execute the

code after that so if i clear the

console here and press command s you can

see it only says yes it is foo it

so however if you change this

basically the execution of the program

doesn't fall into line number 10 it will

eventually fall to line number 12. so

you can see it says this value is not

bar so when you're writing your if

statement and else statements just be

careful with that just know that it's

kind of like a as soon as the code jumps

into one of those branches it doesn't go

to the rest of the branches and checks

check that in my notes that we've talked

what we need to do now is to talk about

there are three different types of

operators there are prefix operators

infix operators and suffix operators

and i will explain them to you i mean

i think to explain operators probably

it's best that we talk about numbers so

let's go in this test function and

delete everything that we we've written

here and let let me just say final

now we've created a variable whose value

cannot be changed after spin assigned to

because we created as a final a variable

whose value is 20. all right now if you

want to calculate half of this value how

would you do that then well there is an

operator for that and that is a division

operator so you would just say for

half of age as you can see we're using

camel case as i explained in the

an easy way to do camel case is to say

half of it just writing in english

of like this here change the first

letter of all the words except for the

first word to uppercase and then remove

all the spaces that's camelcase

basically so half of age is age and then

there is a great operator in a dart

called a division operator and then you

and then you could just say print half

so command s and that says ten all right

so that's the division operator and then

multiplied by two it's kind of like a

that is an operator and you can see

the division and the multiplication uh

multiplication it's a little bit

operators are in fix operators and an

infix operator is an operator that has

two parameters one to its right and one

to its left i don't know how you can

yeah one two one to each side i don't

know if my video is like mirrored so if

my right hand is actually right hand on

your side as well so i don't know yes it

these are infix operators when they have

an example of that is for instance if i

change this to var i'll explain soon why

and if we said minus minus h

now this is an example of a prefix

operator and a prefix operator is an

operator that it comes before

whatever it has to do its work on and in

this case this minus minus operator what

it does is that it takes the value that

and then it returns its result back to

the left-hand side so in this case the

the interpreter comes here and says okay

you wanna calculate something okay it's

oh a prefix operator that takes a

variable here and it says okay what is

minus 1 is 19. puts it in here and it

also puts that minus 1 sorry puts that

i think so at least so if we say print

age and print age minus one now both

and you can see it says twice you see 2

19. so that kind of means it's uh twice

so flutter has this great ability not to

duplicate basically log statements or

we have i mean there are some really

great operators in dart and that is the

plus operator operator and then you have

the minus division multiplication and

then you have the logical kind of like

operators to check if a value from the

left is equal to the value to the right

these are kind of like the basics of the

operators in um dart so you don't have

to know so much more about these for now

you can get really far with these and a

lot of these operators actually work not

only on numbers but also on strings so

and for instance if you this is one of

the cool features of dart which i

absolutely love i think it was just such

a great idea for them to implement this

uh one thing i mean if you're not coming

from a software development background

um you may not know this but if you're

coming for instance from design

background also you would notice that

sometimes when you're creating designs

any any screen and you want to kind of

like show that design to someone like a

product owner you want to actually

populate the text inside your design

and lower mibsum is basically has a huge

history of where it comes from but it's

usually some sort of a dummy text kind

of that you want to place inside your

so that you can just like display and

a lot of developers like in many

languages when they want to display some

text and they don't know what to say

like we're just testing stuff i just

want to display some text they go and

grab lorem ipsum and then put it in

but dart has gone to the next step and

said okay we don't need that so what you

can do you can say for instance name is

that's a string name but you can say

is name times 20. you can literally say

multiply a string by 20 and what that

it's a great feature you can say foo bar

that's it copies it for you 100 times in

the basics of operators in dart okay

mark in my notes that we've talked about

we can also create custom operators to

i don't think it is completely

all right right now to talk about custom

operators i think it's kind of like a

topic to talk about later so i actually

just moved it in my notes that

we don't need to talk about it right now

because we have to know about a little

bit about a little bit about classes and

objects so that we can after we've

created our own class then we can create

appropriate to talk about right now but

just know that in the future you can

also create your own operators and then

like or you can also override like

different operators and how they work

with different objects so it's it's

but that's that's that let's just let's

just leave operators to that for now

now the next topic that i wanted to talk

similar to each other and they are

a list as you would have for instance a

piece of paper and you could write your

shopping list or like a christmas

um these are called lists in dart

and then bass as you can see dark

doesn't like this syntax at the moment

it says okay what are these like what is

the way to tell darth that this is a

list of things that are like in place

is by placing them inside uh square

brackets and then a semicolon of course

as i've talked about it before just just

indexes in that they all have their own

place placement inside the list

and all these objects as we call them

they have their placements inside the

list and you may think that object

object number two is bar and now number

three is bas and i kind of correct but

i mean all the programming language that

i've worked with c plus c rust

they pretty much all start at the index

of zero and that is so important to

is not one it's actually it's index is

and that is why lists are called zero

based and their indexes are called zero

based indexes so you've got to be

careful with that and we're going to

talk about indexes soon actually

final names is that now if i want to

extract foo from here i'm just going to

at the index of zero right i'm just

going to print it i'm just going to say

printfu and you'll see food printed here

i want to get past then i'm going to say

index of two because it's the third item

but since indexes are zero base then

it's in excel so i made the mistake

myself so command s and you'll get bass

i actually want to go back to this three

and then command s so you can see what

happened here you'll see you you'll get

a range error which is an exception

an exception in dart and many other

programming languages is when things go

so that the language doesn't really know

and in this case you can see this

through an exception at the language

level or at the library's level where it

there are no four items in this array or

in this list because the index of three

item number one in the list has the

index of zero item number two has the

index sub one item number three has the

and item number four has the index of

and there are only three objects in this

non-existent and that is why we're

getting this invalid value not in

that's how you access items inside a

and this is how you actually create a

list okay so you say list of items which

you can also there are some convenient

properties on lists that you can for

length so if you want to know how many

in this list you can also say

we're going to talk a little bit about

that now as well because i think it's so

important to understand what that is

dots in dart and in many other

programming language is a way to drill

something to extract something else from

it and in this case names is a list

and that means every list in dart has a

automatically calculated for you you

don't have to do anything as you enter

values in this list this length is gonna

then return the right value to you so

i'm gonna i'm just gonna talk about that

a little bit more so i'm just gonna say

it's gonna say you'll see here

let me scroll a little bit it'll say

three three items in this array

i'm gonna change the names list to var

change its contents and mutate it like

i just wanna add a new name to this

is a function as you can see because it

my name and then semicolon to end the

statement now if i say print names

length right after the statement

you guessed it oh i can see actually my

you may not see all the print statements

because this text is right there so

let me resize my visual studio code a

little bit so you can see things a

little bit better sorry about that

now we have names length here and you

can see the second time around it said

the name of a of a variable and that

means it can be a constant a variable or

a final variable after you put dot

after its name you're accessing

different properties or different

functions inside that thing okay so it's

kind of like an accessor it allows you

to drill down inside an object and grab

things out of it or maybe make that

object do something for you okay

i think i think that's good enough to be

honest with you about lists i don't want

to go too much into details and scare

people about like all the different

things you can do with lists and but

there there is great documentation on

dart's own website all you have to do is

just to google or duckduckgo or whatever

your way through and just search for

dart arrays documentation or just dart

arrays and then you will find lots of

or sorry dark lists because in dart

they're actually called lists in some

other programming languages they're

those names can be used interchangeably

to be honest with you lists and arrays

are kind of like yeah almost the same

that was lists in dart i'm gonna take it

notes so that we know we've talked about

the next topic that i wanted to talk

as you can see in the caption i've

written here is a list of unique things

lists were lists of homogeneous things

sets our list of unique things so

i think the best way actually to explain

sets is just to jump right into it so

the syntax for a set is with a curly

actually i think i think it is

uh names and i'm just gonna say curly

and then end that okay just like that

you will see that the suggestion

provided here or the information

provided by visual studio code says

we talked about this in the previous

or final something name for instance is

i'm kind of telling dart to create

reference name is name and its value is

fu and dart automatically understand

value is string because its data is

string so you don't have to say final

although you could do that but let's

change this to const as well as

you don't have to actually say this is a

string because dart understands it

automatically so you just remove the

data type if that's what you want to do

which is what i actually prefer to do

unless you have a really good reason to

provide the data type anyways let's go

means and that's and in the same way

that we created a string and then dart

automatically understood the data type

by putting uh square brac sorry curly

brackets here or curly braces here and

putting some data inside that dart

automatically understand okay this is a

set of some stuff in here and this stuff

for now just looks like a string so

art says okay this is fine but if i go

in here and i say foo again you can see

i automatically get then an error

message say saying two elements in a

constant so literally cannot be equal

because it understands that this foo it

okay so let's remove foo from here and

let's change this names to var so that

we can actually change its con its

then go to name and add to the next line

and then say names add bar and then set

and then we'll say print names okay and

i'm gonna clear the logs with this

and then i'm gonna press command s

and you can see that the set is still

full bar bass nothing changed really

that is one of the greatest properties

sets in dart and in pretty much every

other programming language that supports

sets only ensure always that their data

this is i mean there's lots of magic

happening in the background that i

haven't really talked about in i mean

for instance like the question that you

foo is the same as foo does it compare

them yes it kind of does actually

it's internally doing a comparison

between these things but we never told

it how that comparison should work

if you remember from operators when we

now we haven't talked about classes well

i'm just going to say strings in dart

already know how they should be compared

they kind of have this logic of hash

codes and comparison operators that they

given this string am i the same as that

like given sorry given what i am

and this new thing that you're providing

me like i'm foo and you're saying foo am

i the same as foo and then it says yes

that is what sets are doing internally

but we don't actually see that so

just know for now that sets in dart

allow you to create unique lists of

you may also be a little bit like

tempted to go and say okay i have things

here let's say const things is equal to

and this will also work and that is

the concept of object as well you can

see you'll see things and it'll say oh

we haven't talked about objects yet and

if i look at my notes i can see that

we're going to talk about objects in

and we're right now in chapter four

gotten to that point to talk about

and i don't want to really scare you

about objects and what they actually are

there is a hierarchy of data types so

you have object and then you have

data types that kind of derive their

here sits object and then here's its

double etc and then you have sets and

when you're here when you were first

here and you said i have foo barbaros

all strings then dart was like okay

you said oh i have a string and i have

now dart was like oops i have i can't i

i don't really i can't say this is a

list of strings and integers that's not

possible in there so it says i'm going

to take the common denominator type that

sits above them as their parent to

specify what these things are okay

and that is kind of like the same thing

that we do in real life in that if i

two candies like a twix bar then you say

this is a twix bar that's one thing

if i give you 10 twix bars then you will

say a lot of twix bars or 10 twix bars

if i just give you a bunch of twix bars

oh that's a bunch of twix bars but if i

blend like lots of twix bars mars bars

whatever all the sweets into a bag and i

give you that bag what do you call it

oh this is a bag of twix and uh snickers

and mars bar no you would probably just

say candy it's a bag of candies and

that's what dart is doing here saying oh

you threw a lot of stuff in here i i

like comprehend that this is a set of uh

we do that in real real life and that's

what dart is doing here so just when you

see object just know that oh dark

doesn't really know what this is anymore

or it kind of knows what it is it's just

that's what object in this case means

comparison maybe but i hope you get uh

and if you see me looking here it's just

because i'm looking at my notes to

ensure that i've explained the things

talked a little about about hash codes

and sets we don't have to go into

now let's go and talk a little bit about

one of my favorite data data structures

any programming language that supports

them pretty much almost all modern

programming languages support maps so

as you can see here maps are used to

hold key value pairs of information and

let's say that you want to explain

a person using their different

these are kind of like your keys

the properties of that person using

those keys and all those keys have their

if you say height then you say like 180

and if you say weight then you select 70

so these are key values the keys are the

properties of that person and the values

are the values of those properties so

and the way to create a map is very

similar so to very similar to a set with

actually this is just a name you don't

have to say person but yeah or you can

just say const so person and then you

open curly brackets and then you would

do your keys here and i would say the

key of age for instance i'll say 20

is it calling yeah it's a column

and then you end the whole set with a

semicolon so i just created a

basically here i created a map whose

keys are string and values are integers

now let's see if dart understands that

you see this is it's a map of string as

keys and means as values but now

as you saw before the analogy of candies

now if i say okay i have another key and

name and i say oh the name is foo

what is this person oh it's a map of

string as keys and object as the value

because it just looks at the common

denominator of the string which is foo

and 20 which is an integer and says oh i

don't know i can't create a map whose

keys are string and its values are both

string and integers so i'm just going to

go to their parent and be like oh the

parent of both string and integer is

object so your values are of type object

a bunch of candies basically okay

and the other property of a map is for

if you if you go and create an agent

you see it says two keys and a constant

map literal cannot be equal so it's

doing some checks here making sure that

the keys are actually unique so keys

need to be unique all right so however

if you go and change this and say var

person so and then you later go and say

name is equal to foo like just like that

and then you print the entire person

so i'm just gonna say print before

and you can see here it said first time

h key is 20 it has a value of 20 and the

name k has the value of foo with a

capital f then the second time around on

the print statement on line 15 then we

when we print the person it has

key of age with a value of 20 because we

didn't modify that and a key of name as

it was before with the value of foo with

like six i think uh capital o's

so this is how you would modify a

and then you would say equal to which is

an operator and then you would say the

um however if you added a new key here

and that will just kind of like get

the um to the map so age the same name

the same now you have a new key whose

and that is kind of like the basics of

there are lots of things you can do with

maps and i really encourage you just

like everything else that i talked about

in this chapter that you go and read

some of the documentations because

if you're following along with this

course and your goal is to become a

software engineer and if you're for

instance a project manager or a designer

i think you need to understand that

do not know all the answers you have to

go and read documentation you have to

practice practice practice and put time

countless countless hours you need to

i mean this course i think is going to

the the way i can i mean i can see

uh the planning for all the chapters

there's so many chapters i think the

entirety of this course is gonna go over

20 hours so you can imagine i can't go

into details about every single thing

this course is probably going to be like

we can't do that so what i expect you to

do now is just to open your browser and

maps documentation something like that

and you also need to know that now that

you're starting to google things you

need to be aware of the word dart and

that dart is an existing very popular

so sometimes depending on what you're

the classic darts that you throw is more

programming programming language which

in this case if you say dart map

you may actually end up in some sort of

explains to you how you can throw darts

i don't know i'm just trying i'm just

trying to bring it up because that i

actually ended up in that situation that

i searched for something related to dark

i actually ended up in a weird website

talking about darts as like a sport

all right now we've uh talked about maps

what's coming in the next chapter

we are gonna talk about a very um

important concept in dart and many other

programming languages such as rust and

swift and that is null safety or dart

calls it sound the sound noise safety it

is a very important thing to know about

and it will greatly help you in the

future as you write your flutter

applications and in this course i'm

make a lot of null references talk about

null quite a lot throughout the course

it is very important that we go through

that as soon as possible and we're

definitely not gonna leave that out so

that's gonna be for chapter five so

keep an eye out for chapter five that is

to follow so i hope that you enjoyed

this chapter chapter number four where

we talked about dark control statements

and collections and i'll see you in the

and welcome to chapter number five of

in this chapter we're going to talk

in the previous chapter chapter number

and before we go on to talk about

enumerations and objects and classes

it is very important to talk about null

safety which is a concept that is

available in most most modern languages

dart sorry such as rust and swift

so it is important to kind of like get

this out the way before we continue

maybe not even get it out of the way but

learn what it means and try to utilize

it so that we can write better code so

i thought to just bring up um

null values and why they're important to

i mean you've seen so far that we have

data types a data type can be for

instance a string can be an integer

and then you can put values in them

in programming languages you're also

have the concept of the absence of a

on one hand you have values so you for

instance have a string value equal to

foo bar or your name or whatever it is

and then on the other hand you can have

the absence of that value so you can see

okay i have a container i have a

variable that can contain the values of

a variable that can contain any object

however at the moment i don't have that

value so you will just tell dart that

this variable that i have right now

that can either contain a valid value of

integer or it can sometimes also

and this nothingness is the concept

it means that it's a word that you can

just write in your text editor as you're

writing your code and you say that a

variable's value is equal to null

and this tells dart that well okay this

variable at the moment doesn't contain

not really a value but it's actually the

absence of a value you should think of

there's a little bit of a documentation

uh on dart's website dart dev null

safety so i'm just going to click on it

you're not going to see my screen at the

i'm just bringing it up in a

a browser window i'm going to bring it

and increase the size a little bit and

window as well so you can see the

contents in its entirety um

as you can see in dart it's called sound

documentation about what this actually

look at what's not safety actually means

in dart and i'm gonna give you a lot of

examples of what that actually

practically means and there's

documentation here in dart's website

in its older versions and not in its

current versions it in its older

versions it didn't support uh all safety

so there was a lot of code written

manually by programmers in order to for

a value is absent in a variable

and then there is as you can see here it

says migrating an existing package or

app so there is documentation written by

the dart team in order to help

developers understand how they can move

their old code to the new code

um however if you're following along

with this course and you're it's like

basically just following chronologically

from chapter one to all the other

chapters i don't know how many chapters

were going to happen if you're following

along with this course you don't have to

think about migrating because the code

that we're writing in this entire course

is going to be null safe meaning that

we're going to take advantage of darts

null safety operators and meaning that

we are not going to manually check for

values being null and then doing some

branches of code whether they're null or

so what i mean is that if you read the

documentation for sound safety you don't

have to worry about the migration parts

with that out the way i'm just gonna

make sure that i take that in my notes

here that's why i'm looking in this

direction because i have all my notes

um let's close this window and bring up

visual studio code window that we had

from earlier i'm gonna put it here

and i'm just gonna ensure that it is of

the correct height as well so you're

gonna see it the window in its entirety

now that we talked about what non-values

are and that they're the absence of a

and if you follow along with the

with the course up to this point you

should have some sort of a simulator or

an emulator running and then you should

have done command shift p or control

uh depending on your operating system

command shift p in mac and ctrl shift p

in linux and windows in order to bring

this menu and then you can just type

flutter select device and then you just

select the device that you want to run

the code out so i'm kind of assuming

that you've already done that and that

your code is running and this is

something that we talked about in

earlier chapters so we're not going to

an iphone simulator which you cannot see

on the screen but i have it running in a

separate uh screen just because we don't

real estate i can bring it up to this

window but it will just take a lot of

space so i'm gonna bring it up to

another monitor so you don't see it

so this code at the moment is running

live so if i press command s then it's

gonna run and just print the output for

let's talk about making any type um

way to do that let's let's have a look

we talked about that null is a keyword

and that that's why you can see it is

highlighted here in a different color

so if you for instance say final

as you can see it says okay i accept

this as his name is foo but you can't

just say name like it's a null because

then it doesn't understand is it an

object is it's a string is it nil right

is it an integer and if you type here

name then you see it's just dynamic it

and we'll talk about dynamic a little

bit later um but what you can do is to

actually specify that okay i want a

normal names or strings as we call it

like series of characters or it can

sometimes be null and in that case you

have to actually specify the data type

not just this because you'll see you'll

and you'll actually get a suggestion it

says try changing the type of the

variable or casting the right hand type

but we're not going to do that wasn't it

it wasn't such a useful suggestion

because what you want here is to

actually make dart understand that this

variable right here or this constant

right here can sometimes contain the

and the way to do that is you

so this is this is the syntax which is

actually used in some other languages as

well it's used in swift as well

um this tells dart that well here if we

make it actually variable as you can see

or sorry like this so you say i have a

it's it's a string but sometimes it may

the string value may be absent

um and then you'll just say okay

and you can say now name is no

so this is kind of like resetting out

names so if i just say okay print

and then after foo i say print name okay

so let's just clear the console and just

run this application you can see the

and then the second time around it says

so this is how you tell dark that you

data type and you can do this with

pretty much all data types so you can

just say okay i have an integer

um of age and that's 20. but you can see

you cannot now assign the value of null

to integer because it's not nullable but

as soon as you make it nullable then

you can do different operations using

for instance we in the previous chapter

i believe we talked about control

so you can say for instance if age

and then you can encode or you can say

so they work as you would expect so

there is no difference really

i mean if you if you think about that

notability nullability is just like a

suffix to a data type you can also say

okay pretty much any data type can be

nullable and that's that's correct like

and you can say okay i have foo

and bar here this is a list of strings

i've talked about lists in chapter four

now you can you can see here that list

of strings there are two data types here

contents that it holds so if you want to

make the list in itself nullable then

you would put the question mark after

okay this means this list of strings in

itself can be absent so you say name is

null and that's accepted all right

however since you're telling dart that

okay the names uh value here can its

but its values are not supposed to be

so if you then go in here and just put

null in here then you see that you got

and that's because dart is saying that

okay you just promised me that

the list in itself it can be absent but

it is not absent meaning that as soon as

with some values it's the values cannot

you're telling me here that it is not so

if you want to make an optional

optional strings then you would put the

question mark after the data type of

i mean the way you should read this is

i have a list of strings and i call that

meaning that it can be absent

it can contain objects of type string

that themselves can sometimes be absent

meaning that okay like for instance if

fu bar no that's accepted but you can

see what i mean so both the container

which is called names and the values

that it contains can be optional

and the word optional is very important

for you to learn it's it's kind of like

industry accepted way of talking about

nullable values and optional values all

right basically you can use those words

if you're talking with a colleague

programmer you would say oh how would

you describe this okay this is an

optional list of optional strings or you

could also say nullable list of nullable

optional is also word that is typically

okay we talked about making any type

done that we've talked about it in notes

now let's talk about cherry picking

non-null values and what this means is

at all i'll explain what this actually

this is a constant all right that's

that's what the suggestion was you see i

wrote final because i was not planning

reassign this first name value to

anything else but then i got a

suggestion to actually use the word

final here or the keyword final sorry

the keyword comms as you can see here

what we want to do here then is to

and actually what we're going to do is

the first name is null all right

so first name middle made bar and last

if you have these values and you want to

i mean right now you can actually see

the values that you put here but

sometimes these values are passed to

your function so you don't know what

they are right now you can see what they

are so it's easy if i told you pick the

first non-null value then you would say

middle name because you can see it

however if you had a function for

instance test here that accepted those

you wouldn't know what those values are

or you cannot make an assumption about

what those values are except that they

are nullable or optional strings so

i hope that you get what i'm trying to

say now if someone told you to pick the

one way to do that is like the old way

of doing that is to say for um

um then you would say oh i again okay i

and then you say okay if first name

isn't null then we pick it otherwise

middle name is the first nominal value

and then else if again so last name is

then you would print the same thing so

very verbose in the in the way it is

there is a better way of doing this and

uh question mark question mark operator

dart which is available in some other

programming languages such as swift as

so the way to do that then is you would

want to pick the first non-null value so

or const first non-null value

and you would say that's equal to first

or or so this is kind of like question

and then question mark question mark

and i mean we're getting a warning here

just because dark understands already

that this middle name although a

so it's this is although an optional

so and that warning goes away but i mean

it would probably be cleaner if we

actually pass these as parameters into

this function so we don't get these

but the way the question mark question

mark operator is working is that it says

it is an infix operator just so you know

in in from chapter four you know an

infix operator is an operator that has

and one on each on each side the right

so in this case on the right side we

have middle name and on the left side we

have first name so what this operator

does it says if the value on my left

i'm gonna pick the value on my right

and let's now in this case say okay

middle name is not now so what it does

it says first name or you null yeah

you're not then i'm gonna go to the

right side middle name are you no no i'm

not no then it's gonna pick that and the

statement is not gonna be executed

however if middle name was also known in

this case then what happens is that it

begins from the left is a first name or

yes middle name or you know yes so this

and then so this entire operation will

let me know so it says okay now i have

left left hand side are you know yeah we

know that this entire thing was no

and then it says right hand side are you

nope i'm bass then it takes pass so

this question mark question mark

operator is a null aware operator that

picks either the left side or the right

whichever one is not null first in that

order so left side are you null

if you're null i go to the right side

so keep that in mind it is a very handy

shorten your code quite a lot all right

now if we then go in here and say first

non-null value you can see it actually

if these were parameters so if we said

and then string last name sorry middle

they were not provided to us like that

converter was okay and then we say final

if we say first non-null value in this

case since it is a normal case

where the dart compiler isn't working

it cannot resolve this to a constant

value at the moment so it says okay

there are three optional values i have

i'm gonna do my best to pick the first

nominal value depending on i mean based

however i may not be able to solve this

the final result here as you'll see is

and it's an optional string meaning that

well i may not be able to resolve this

meaning that this entire operation on

top on line 9 may result in a null

sorry about that sorry about my voice

that is the question mark question mark

operator so i'm just gonna mark that

that we talked about it in my notes

let's talk about the next topic uh which

is the null aware assignment operator i

think that's that's this actual official

um this operator is very similar to the

question mark question mark operator in

it's going to do its best um and let's

have a look at an example let's just say

and i'm gonna say actually let's just

and name is first name so we begin we

say that we have an optional name

and we begin by assigning first name to

this name might at the moment depending

on the value of first name it may be

if that is null you may want to assign

another value to it all right

and then you can do that with this

operator you would say last name

both trying to oh is it this yes it is

equal to so i actually should change

yes and i'm going to bring it up again

so that it is actually correct let's say

i'm actually a bit unsure right now so

let's have a look actually what this

and it's three positional and then we

middle name is bar and last name is bass

to be honest with you i mean this is

quite a lot for me as well it is

syntax of the programming language it is

something that you will kind of need to

live with you're not gonna memorize this

all just in in your head all the time of

course like the main parts of it you're

gonna you're gonna remember but

uh not all of it so and you can see for

me as well i'm just like at the moment

so i'm gonna test that so i'm to begin

with we say name is first name and

actually let's just say middle name

name here then use middle name and then

and i can see it says bar here so it's

actually question mark question mark

so i actually maybe need to edit this

text one more time so i'm just going to

say question mark question mark equal

bring it up because i think question

mark equal is not going to work an equal

question mark isn't going to work either

it's not a value it's not a valid syntax

a question mark question mark equals

what this operator at the moment is

doing it says that i'm gonna take the

value on the left hand side and check

whether it is null or not if it is null

then i'm gonna assign the value on the

right hand side to the left hand side

if it is not null i'm gonna leave it

at the moment first name as you saw here

the first parameter that we passed here

so what it says it says okay i'm going

to check then for middle name

if name is null and it is null and then

it says okay middle name are you

like presenter and i will assign that

basically it will be bar which is the

right we could have another operator

here that says okay if after taking the

middle name we are still null then take

and you can see bass gets printed to the

screen and that is because because bass

is the last parameter that we're

so you can see how like if i then went

here and actually said the first name is

bar then you will see that that will be

the value that gets printed to the

name or first name which is bar got

assigned to name so it is an optional

string but it has a value which is bar

then when you come to this line number

nine then you're telling dart look if

name is null then assign middle name to

name isn't null it is bar so i'm not

going to assign middle name to it and

then it goes to line number 10 and does

the exact same thing all right

so that is like the null aware

i personally i mean to be honest with

as you could as you could kind of guess

i don't use this operator so often it is

and i have no shame in saying that

pretty much in none of my programs have

i had to use this so it is present for

use it is available if you want to use

don't be like me but try to remember the

syntax this question mark question mark

and i'm gonna actually fix that in my

notes as well that it is question mark

and i'm going to check it in the notes

a little bit about conditional method or

property access or conditional

as we talked about in the previous

chapter with dart as like many other

programming languages you can

in order to access or drill down inside

properties and methods or functions

inside other objects as we saw for

or lists in dart you can say

i have a list and then you want to get

its length then you would say

the name of the list dot links and that

drills down inside that list and gets

however as you saw also earlier in this

chapter in chapter number five

even lists or pretty much any data type

in dart can also be nullable

properties of a null object so let's

let's say i'm gonna i'm gonna actually

delete these properties uh the

parameters that come here to our

and i'm to say and i'm going to go down

here and remove these parameters as well

and in here let's just create an

not optional list of optional strings

but at just an optional list of valid

strings okay so i'm just going to say

list of strings as an option i'm sorry

an optional list and i'm just going to

and that is equal to let's just say at

in here if you try to say final length

of names or number of names is names

if you then look at the data type here i

mean we could actually say this is null

here dart actually is allowed to

or is able to give you an error

knowing that this list it is null at the

moment however if you accept it i think

it's actually better that we accept this

value as a parameter so that dart

analyzer cannot be too smart about like

making assumptions about what this

analyzer is telling you it cannot be

unconditionally accessed because the

receiver can be null and that means yeah

exactly as it says it says names can

mean all i don't know if it's not right

so how do you access that one way to do

that like the old way of doing that is

uh in x okay so that tells dart that

look i'm actually checking for null

um or i'm checking that this list is not

then i would access its length property

and this is kind of it's called type

so in this case you can see on line

or now if i go and create a new line on

number online number eight and i say

you can see it is um it is typed as the

same but it is promoted to not being

null because you've already checked for

it because if you remove these lines of

code you can see now that you get an

error the exact same line but if you

check first for null and you don't get

the error it's a type promotion okay

so this is kind of like the old way of

so let's say that you want to have you

want to extract the length so you say

right you create the variable but you

when you say if names is not null then

the length is equal to name's length

otherwise length is zero okay so this is

trying to be smart as well and say okay

i don't need this else statement if i

and by default is zero and yeah you

would be right because length is zero by

default and then if names is not null

then you say okay length is equal to

however there's a better way of doing

quest dot question mark i believe or the

question mark that actually it is yeah

operator which conditionally executes

or invokes a method or a property inside

an optional if that optional value is

i'm going to show you how to do that so

is names and then you would put question

mark dot and then you would say links

and you would see this this code like

being executed without a problem

however if you go here you would see

that length is an optional value it's an

you may be like okay how do i solve that

null meaning that if it's names if the

names list is null and we can't extract

the length then i want this value to be

set to null and that is using our

question mark question mark operator

that we talked about the null aware

operator that we talked about earlier

so you could just do this you would say

if the names list is present meaning

that its value is not null then grab its

length otherwise take the value of 0 and

assign it to length and if you go to

line number nine now and i say length so

is not an optional integer anymore

so you could do the same thing as well

and you could do the same thing with

properties and you could also do it for

functions so you can say names add

right so you see this is a function

called add and then we're adding the

unconditionally invoke this function on

that is like a very very important

learning about optionals in dart how you

as you will see and we'll talk about it

many cases where you have to

take into consideration all values and

especially if you're working with

the library cannot make too many

assumptions and your code is dependent

you will have to take into consideration

okay the absence of a value means that i

personally have to like take some

decisions in my code consciously in

order to execute bits and pieces of code

depending on the absence or presence of

the value so try to use these optional

null aware operators that i taught you

um the null aware um basically like the

decision making on to pick like the

infix operator that tells you whether

the left hand side or the right hand

side depending on which one is not null

first it picks that one okay

that offer is very important and the

all over invocation operator which is

here so you say some object which may be

null then do something on it

operator which is a null aware

assignment operator that assigns the

value on the right to the variable on

the left should the variable on the left

be null all right so these are very very

now that we've talked about that i'm

gonna take that in my notes that that is

very very good official documentation

about null safety in dart so i'm gonna

bring up this documentation on a

and then i'm gonna bring it up here so

you can actually see as well all right

you can see here it says understanding

all safety and this is great great

about how null safety in dart works

as you can see a lot of examples um

i mean it talks about like from the

uh and you can see here null is at the

level of object so it's not novel itself

so you have lists and doubles and

integers here but null sits on top for

itself it's kind of like the absence

so there's lots of examples in in this

highly encourage you to have a look at

it some things you may not understand

for instance like this one you will

understand easily because it says there

is something called a thing like a class

but we haven't talked about classes yet

name parameter name here in this

function called showgizmo is called

thing and you can see it is

conditionally accessing a property on

and then if that property in itself is

null it conditionally access that as

well so if this property is nullable and

then it's accessing another property

inside that nullable property

if it's not null so it's i mean it's a

great way you can chain them as you can

then so if this thing is not null then

conditionally accesses this property on

that so it's it's beautiful i mean and

this thing is available on many other

languages like rust and swift as well so

it's nothing new it but it is kind of

uh such an important topic to understand

in dart that i think you shouldn't just

skim over it so you should just really

all right um we've now talked about null

value so i'm going to take that in our

now i think for chapter 5 five

this information is enough so that we

and in the next chapter chapter number

six we're going to talk about some

this is like chapter six is going to be

as i can see my notes are pressing in

topics such as enumerations classes

custom operators constructors factory

i mean inheritance and stop classing

apps subclassing abstract classes so

depending on what background you have

you may be like a product owner or

product designer a ux or whatever you

may not have like a software engineering

object-oriented programming language it

means that things in dart are objects an

object is an instance of a class as

we'll talk about in the next chapter so

for you to understand dart and how these

things work for instance we've talked

about lists and actually typing dots in

front of the name of the list and

getting its lengths but you may not

really know how that works so in order

to understand all those things what that

dot means you need to understand what

objects are in order to understand

objects you need to know what classes

are and when you understand classes then

you will learn about inheritance and

then you will talk we'll talk about

abstract classes properties static

what we're going to talk about in

important that i believe that every dart

developer needs to know about this and

we're learning all of these things to be

become good at doing flutter um so

uh although you can go and write like

servers or maybe server applications

with dart or you could write command

line applications with dart but these

dart is primarily used for writing

flutter applications and i don't have

data to prove that but i can see for

myself when i'm in the community that

most people are using dart primarily to

write flutter applications so we're

doing all of this to learn more about

flutter and i highly recommend that you

don't skip these chapters where we're

talking about art especially if you're

to flutter development so with that said

let's leave this chapter the way it is

right now chapter number five we're done

with that let's go to chapter number six

and learn about dart enumerations and

welcome to chapter six of this flutter

in this chapter we're going to talk

about uh dart enumerations and objects

and these are some of my favorite things

in most programming languages actually

if you follow along with the other

chapters then you should have a working

dart project set up now and maybe

running in an emulator or a simulator so

that you have the ability to press

command s on mac or control s in linux

and windows in order to rerun your

project so without you having to pretty

let's then get started i'm just going to

make that assumption that you're already

enumerations and i'm gonna bring up

the project from the previous chapter

let's just make sure that it's on the

screen so you can easily see it

now i'm going to go and to this list

function that we created remove the only

parameter there and remove that as well

so if i press command s now nothing

should happen on the screen because we

don't have any functionality in tests so

let's talk about enumerations and what

they actually are as you can see here

animations are named list of related

making a string written programmatically

so that it becomes an entity

and you would also say khan's other name

that's also foo they're both the same

string but they're not the same identity

i mean internally actually in terms of

const i don't want to go too much into

the comp how the compiler actually works

but they're going to be going to be the

but i mean that you've written it twice

so it's not the exact same thing you

so an enumeration try to tries to

a value has a name that can be

programmatically referred to so

um cons sorry enum and that's a key word

in dart that's how you create an

um i'm going to take this that we've

talked about some some other things

during the intro sorry about i have to

look at my notes anyway anyways so we

have the enum here that's how you create

and you would and then give a name to

your innovation and unlike variables and

written with camel case you'd have to

basically use another casing here which

is the first letter of every word in

your iterations name has to be uppercase

and the and the rest of the letters have

let's in this case for instance say

person properties okay the properties of

then in this enum you will write the

different properties for instance first

so what that basically means is that

you've now defined a list of related

things such as first name last name age

which are categorized under a particular

name which in this case person

and you can refer to these in your code

using the dot notation so you can say

and we can print it actually so i'm just

gonna press command s and you can see it

being printed to the screen so

i mean immersions are really really

great as we go on in the in learning

about dart and how dart works how we can

work with flutter how we can parse data

but for now it's enough for you to

understand that you can categorize

under an enumeration so that you can

and indoor you can also get the string

values using their name property that is

something that's created for you by

default so if you just say name

you now see first name being printed to

the screen as a string but before that

if you print the innovations

value here for first name it would print

short and sweet about enumerations we're

especially later where we go to more

as we develop our real application but

for now just know that this is how you

create an information using an enum

keyword and then the rest of the

properties you just put in curly

now we need to talk about switch

statements and actually let's bring this

change this to properties let's say okay

and let's just say for instance animal

dog and then let's say rabbit

let's say we have an animal type

and then we for instance get in our

animal type so there's a property that

we expect to be passed our function

we name that property animal type with

kennel casing here okay so if we do that

then we go to our function here we're

recalling the function you can see that

we got an error meaning that there is a

parameter expected of type animal type

the place you are calling your function

that's what a call site is known as in

programming so if you're coming from a

um anything that is not software

development related so you wouldn't

so much about the this kind of lingo but

a call site is where you're calling a

function so at this call site online

um we're gonna gonna pass an animal type

and let's just say uh cat in this case

so in here we could just print that and

i'm just gonna say animal type

i'm gonna press command s and you can

see cat being printed here okay

different types of code depending on

then you could you could which is not

recommended you could use an if

statement so if you just said if

animal type is equal to animal type cat

you say print all i left oh i love

else if animal type is animal

or you would say dogs are so fluffy or

so this is using normal if statements

you say if animal type is cat then blah

it is one way of doing it but it's not

the recommended way of working with

enumerations and the recommended way of

working with enumeration especially if

you're doing like branching code as

we're doing here is using a switch

let's convert this code to switch

you put parenthesis open close and then

open close curly brackets and in here

you would put your narration so you say

and the way to handle these different

branches then is with the case uh

keyword you'd say in the case of

this is i'm great i'm actually grateful

that we're getting this uh error so you

can clearly see what it says is the case

should not complete normally try adding

break or return now what this is saying

many programming languages just like

dark when the program comes here to the

case statement it kind of like falls

through to the next line and dart tries

to avoid that so it says okay if i

handle bunny then i'm doing some stuff

but it kind of feels like i'm like

falling down to the next line after this

because you didn't tell me what to do

after the print statement so you either

me to like completely go out of this

function go out of the test function by

putting the return keyword here we

haven't talked about return really yet

but you could do that you could just say

okay return right after all of these so

i'm just going to press command s

and you will see cat being printed to

but if you didn't have this return

statement statement here you would get

or you would use the break keyword now

there's a difference between these let's

put a print statement here and i'm going

to say function is finished okay

so i'm kind of expecting that

our code here our test function here

passing the value of cat at the moment

that we fall into the switch

we check that this is cat and then print

the cat and then we return okay

what it is doing it means that it kind

of skips over this print statement and

you'll see soon if i say command s it

will just say cat and then we'll return

so this is not really what i wanted i

wanted this switch statement to be

executed print cat and then continue

after switch okay and that's where you

or the key word here so if you say break

it breaks out of the switch statement

and then continues with the rest of the

function as it as you would expect so if

i press command s here you say cat and

then function is finished all right

switch is the preferred way of working

enumerations especially if you're doing

branches so you could also like

for instance if in this case he said uh

you could also in this case say if

and you would return okay you could do

this as well so this is kind of like

a conditional statement that you're

putting in the beginning of your

function making making sure that any

completely sure that the animal type is

a cat okay so in that case you may just

use a typical if statement so you don't

have to do switches okay but if you're

trying to execute spec special pieces of

which value this enumeration contains at

then i highly suggest that you use

switch statement instead of if statement

all right so kind of depends on your on

okay i'm just going to mark this item as

now let's talk about classes all right

which is one of my favorite topics to

uh dart and in many other languages

let's actually bring this back to how it

was before make it a test function all

and remove the animal type from here and

remove them i can actually continue and

are grouping of various functionalities

into one packageable piece of data

and and by that i mean for instance

let's say that you have a function

another function called breathe

and then you have a person's first name

of course you could go and define these

things like this you could say khan's

yeah something and khan's last name is

um just like that and then you could

have a function and sorry you would say

um and then you'd have another function

you can do that but these are functions

that are kind of like for us in this

particular case or at least in my head

at the moment i'm imagining these

and that person can run that person can

breathe that person has a first name and

last name so the grouping of these

the way to do that is you would say for

instance class which is a keyword in

say the name of the class now for the

naming of classes and enumerations and

entity except for variables and

you should use um just normal casing you

would i don't actually know if it's

called pascal casing or i think so

but you would just use your upper case

the first letter of every word okay so

okay this is how you would say a person

i don't think actually we can put const

in there i'm just gonna grab

these two functions and just place them

inside this person class all right

run function and with reading we're

and in the test function you would want

something called an instance of this

instances are objects and objects are

works in software development and this

is for any programming language such as

swift python javascript where

and now that you know what a class is

in order to use a class you need to

usually create something called an

instance of that class that means that

the programming language that okay here

is the class i know about that but give

can be instantiated meaning that the

dart compiler will create a copy of that

exact class with its data its functions

its properties and give that copy to you

that is called instantiation and it

works by using the equal sign and

creating putting a parenthesis

at the end of the name of the class as

i'll show you here so let's just say

which is the name of our variable in

this case is equal to as i said equal

sign then we would write the name of the

class and parenthesis just like that

so now you said a person variable in

this case is an instance of that person

now you'll understand using dots and

notation you could say person.run you

that function is now available on your

instance of the person class and you

functions that are available at instance

level of the person class i know there's

a lot of words that i'm just talking

about but i think you understand the

this is how you instantiate the person

class and this is how you invoke various

functions on that class so if i press

command s you can see it says running

if you said in this case person

and then without instantiating using

parenthesis if you said breathe

you will get an error here instance

member breathe can't be accessed using

that's i mean that is kind of like

instance member is an important term

also to remember an instance member

means some functionality that is only

available at the instance level meaning

that it's not available at the person

class level but you have to make a copy

of person in order to be able to access

you can do a lot with classes as we will

talk about soon so i'm just going to

leave that person class right there

just going to mark that as talked about

and let's now talk a little bit a little

objects are actually quite easy to

explain an object is an instance of a

when someone says oh here's an object of

type string it means literally that

there is a class called string i've

created an instance of it and

and that is an object so the word

instance the words instance and object

are usually used interchangeably uh but

if you hear someone say instantiate a

class then you would say okay what's the

class name oh it's person all right

is now i created an instance okay and in

this case you can see i'm just creating

an instance of person without actually

doing anything with it so that's got

kind of like a useless object all right

but if i put i say foo as a person

foo now is an object of type of person

and actually you can write its name here

and you'll see that it tells you that

and i can see my notes that objects need

are kind of like in the wrong place i'm

gonna bring it to the right place sorry

let's talk a little bit about um

and i can see constructors also at the

wrong place in my notes so i'm going to

bring those also to the right place okay

now what a constructor is at its name as

logic in a class that constructs or

initializes or builds that class's

you may say that okay let's go to our

function here as to our class here

and let's say every person has

a first name or name okay so let's just

define that we say final string name all

right as you can see now dart is saying

okay you said that every person has a

and it's a final meaning that after the

person has been instantiated or after

that person has been initialized or

created an instance from you cannot

change that name because you said final

if you said like string name is foo that

would be different because it means

every person instance that gets created

foo for its name that's a completely

in this case as you can see we're saying

that there every person instance every

copy that we create has a name now dart

to say okay where is the name then you

didn't tell me how to create it

and that's where you would want to use

something called constructor okay

constructors are sometimes you uh called

as initializers depending on the

background of the programmer they may

call it constructor initializer uh or

maybe some other names that i don't know

about but if you if you hear that a

constructor then you will now know what

now what you can do at least in visual

studio code when you get this error is

to just hover hover over it and then

press command on mac or control on

windows on linux and press dot

now you will see you will get some

and it will the second suggestion at

constructor for final fields okay and i

and what happens here now you see it's

that it creates something that looks

kind of like a function but it doesn't

its name is implicitly set to the name

so basically it says i'm a special

function with the same name as the class

and i expect a value to be given to me

which i will then in turn assign to the

it's kind of like a strange way of doing

things but it is quiet clean as well

after you do that so this is how you

create a constructor after you do that

then at the call site where you're

calling this person class to create an

instance of it it will complain saying

that oh i'm expecting an argument

and that's where you have to pass the

name so let's say in this case is foo

and then on the next line you can just

all right and press command s and then

you can see foo bar being printed to the

that is like the basic of a constructor

that's how you construct instances of

now you may be saying that all right i

i mean you can do many fancy things with

constructors you could say okay

this name for instance by default must

have a special value you could do that

there's lots of things you can do with

constructors which i'm not going to go

but right now just know that a

constructor is this special kind of

function that has the same name as the

and then parenthesis and then you put

your values in here all right

let's talk a little bit about um

i'm actually going to go here and say

we're going to talk about methods

and those at the wrong place in my notes

a method of a class we've talked about

already to be honest with you and a

is usually referred to as an instance

method meaning that the function is

available after you've instantiated that

class all right as we're doing in line

so is a variable that is available at an

instance level is not an instance method

an instance method should be a function

all right so let's go and create a

function here that doesn't return any

value denoted by the void return type

and we say print name all right

functionality of this function is only

class all right that's all it all it

and in dart you're also now that we're

talking about this i'll just mention

better not to prefix your instance

variables or instance functions

inside the class itself using

basically refers to the current instance

so you could either tell print name to

print this dot name or it's actually

better to remove this and refer to it as

name that's the recommended way of doing

it okay so avoid the keyword this as

and we'll come to those points hopefully

in this course why you may have to do

that while you may have to use this

all right now we have the print name

so let's just use it instead of this

print function that we're doing here

dot prints name all right command s or

on linux and windows and command sun on

the macintosh and then you get the

foo bar printed here or you could just

i will now print the name of this person

in single quotes we don't need double

quotes okay command s and you will see

that message being printed here

followed by the actual name of that

if someone says method or instance

method you will then know what we're

talking about is a function created at

the class level that does some stuff all

right so that's short and sweet

now that we've talked about that

let's talk a little bit about

inheritance and subclassing i'm gonna

bring a caption here so you know what

inheritance and subclassing are so so

and in any other object-oriented

programming language that i don't think

anybody should like jump over it or

um like for instance i know

developers working in various

programming languages that are object

oriented but they kind of steer clear of

the object oriented aspects of that

language and maybe they don't need it

and maybe they just feel like it's

unnecessary or they feel like oh it's

just too complicated but in dart if you

want to become a good flutter developer

or a good dart developer you need to

talk about inheritance what inheritance

to add more functionality to that class

we go into our test function here and

that code and also remove the person

living thing is breathing okay

so we created a class living thing and

we're saying that anything that lives

needs to breathe now this may be an

anything that lives and is above the

and it's above the ground and it's

basically alive is breathing okay

so that's our function on the living

any living thing may also have the

ability to move okay then we have a

function called move i'm going to say

so now you may say okay now i kind of

want a class called uh cats all right

one way to do that to go about creating

the cat class is to say class cat

and then you say um i kind of need these

functions and you'll go and copy it and

then you paste them here all right

and then you say okay i'm good to go now

developers do not like to repeat

it is such an important concept in

programming that you need to avoid

repeating yourself that you need to just

get it straight so that you don't

make this mistake as we're doing in this

the first thing you want to do as a

developer say how can i grab this code

and it's obvious that the cat is also a

that's where you want to use the extends

um keyword that allows you to inherit

the functionality inside the living

thing class into your cat class so

in this case i'm saying cat class

extends or read it in english as

you can see that the cat class in itself

is empty right now but if you go to the

uh you can see that now that the cat

class has breathe and move uh

functionalities or functions actually

so although cat itself didn't define

these functions but they're available

for the instance in this case called

fluffers of type cat to use so you could

just say move and then you can say

so if i run this code if i delete

everything in the debug console and run

this code you can see that the cat

instance called fluffer is the same move

or i am moving and it will also say

living thing is breathing okay

you could also i mean we could also talk

about now that we're talking about

actually maybe i shouldn't call a

subclassing but i also think it's

important for you to understand what

subclassing is subclassing is literally

the same thing as inheritance

subclassing is saying that you have a

class and you're creating a sub

it's a little bit of a strange naming

sub because sub means kind of like a

subset of things available in that class

but it actually is like a superset

grab everything like the cat at the

moment has every functionality in living

but it may not necessarily do that

it's kind of complicated to explain but

if you hear subclassing or inheritance

use the extends keyword usually okay

all right now we've talked about

move a little bit uh my notes around

sorry about that that i'm looking away

now we're gonna talk about abstract

there's good documentation about

is to just change this class living

thing at the moment to abstract

and you see that everything works as

a normal class and there's good

documentation about what an abstract

class actually is from a dart

perspective and you can see it says use

the abs abstract modifier to define an

abstract class class that cannot be

so an abstract class is just like a

normal class that can't have instances

in this in this case once we made living

thing an abstract class if you then go

it says oh abstract classes can't be

so an abstract class is a class that

with the sole purpose of other classes

using its functionality okay

so if you mark something as an abstract

class in dart you what you need to just

know in your head is that this is a

class that has some utilities that has

some code that is supposed to be used in

other normal classes all right

and no one is supposed to just go and

create an instance of living thing in

at the call side you need to instantiate

now we can say cat as we did before and

we can say thing breathe move or

that's what an abstract class is

just a class that cannot be instantiated

it's usually like a utility class that

other classes are supposed to inherit

i can see now in my notes and i'm gonna

take that we've talked quickly about

the next topic up which we're going to

i absolutely personally love factory

constructors to be honest with you

let's remove our abstract class i'll

explain to you what a factory

for linux windows on the name in visual

studio code at least to create a

constructor you can do that and say

create constructor or you could manually

create a constructor so you say cat

this name okay that's a constructor

and also know that um you could make

this a const because it is actually

using a final field but we're going to

now we have a cat class here that has

a constructor called just cat meaning

all right so now you're creating an

instance of the cat class and the name

of the variable is called fluffball

and the name of the cat is fluffball

is just normal constructor it has

nothing to do with a factory constructor

but what a factory constructor actually

is a way for you to construct instances

and using convenience functions

so what that means is that if you in

you are creating instances of this class

like 20 times 30 times different places

in your application using this exact

you need to then create a factory

constructor that is a clear sign that

your usual use case for create an

that's where factory constructors are

useful for and as their name indicates

a product like a factory does uh super

fast for you okay so it's the speed at

which you can create an instance of a

class that the factory constructor

so let's now look at a factory

constructor that gives us an instance of

cap whose name is always fluffball all

the way to do that is you would say

and you would say cat dot fluffball

so you say any class called cat which is

this class has a function called

fluffball which is this factory

constructor and then you would put your

and then what you need to do is to kind

set up your class instance in this case

like if you say curly brackets and say

like that that's how you're basically

creating an instance of your class but

the usual way of doing that is you say

see that i've kind of like forgotten the

syntax for factory uh so let's go i'm

gonna bring up safari here and let's go

and say guard factory constructor

i'll bring bring up here factory

constructor so let's say factory

and let's go and see an example and you

can see here it says factory logger like

that okay and there's a factory logger

are basically so what what it's

basically saying in here is saying that

this in this function you need to return

something okay so let's close that

safari window and what we're going to do

in here we're going to say return cat

and as the name we're gonna say

fluffball all right so that's how you

would create like a factory constructor

so what you're doing here is saying that

i have a constructor called fluffball

whose return value is a cat

but inside i have some special logic

that kind of packages it up just like

let's go in here instead of doing cat

fluff ball like that then you can just

say cat dot fluffball okay so it kind of

it became like a convenient function in

that you can just say cat fluff ball and

name and you can see by default it is

fluffball 2 print and it gets printed to

so that's how you would create a factory

constructor and a factory constructor is

really really important when you're

talking about class clusters

we haven't talked about class clusters

and to be honest with you i don't think

that we're gonna talk about that in this

i don't think anywhere in this course

in the context of dart and abstract

classes a factory constructor does not

have to return an instance of the same

class all right so it can actually

but i highly suggest that you actually

go and read about factory constructors

dart and you will see some examples of

they are really useful if you're working

with a lot of data and you're doing like

i don't think it's so useful right now

but know that it is there available for

i leave it up to you to go and read more

and we've now talked about factory

now let's talk a little bit about

custom operators so i'm going to bring

a custom operator in dart is

an operator such as an equal sign or

equal equal sign for for instance

um checking equality um of an instance

of an object with another instance of

um a custom operator allows you in dart

to override the ability of your class to

be compared to or added to or

subtracted from multiplied with

with your own logic now let's see what i

you have final uh cat one and that is

equal to cat with the name of foo

then you say okay i have cat two now

and then you'd say if cat one is exactly

the same as cat 2 prints they are equal

otherwise say print they are not equal

these two instances have the exact same

and if you run this code now you will

that dart is said it says that they're

not equal although internally you may

for me in my project anytime

i want them to be considered equal and

things get interesting because then you

function or operator at the language

level only for your class so the way to

do that is you would go and start by

bool operator equal equal covariance i'm

going to explain all this don't worry

about it cat and you say cat and then

name is me okay and then we get a

so don't worry about all of this um i

so let's start by looking at what i just

overwrite is very important term for you

to understand in object-oriented

inheriting from that class in in our

case for instance class cat you can see

that it doesn't have any extents

but by default in dart every class

inherits implicitly from the object

class so you could just say extends

and that is the exact same thing as

just know that cat comes from object

an object internally already defines an

operator called equal equal that returns

a boolean is a value that can either

that can either be true or false

and it's great just for saying that is

is this this or not kind of like that

so a boolean is a data type all right so

that operator an operator is a keyword

as well in dart basically saying telling

dart that we are going to change

the functionality of this equally equal

operator that is defined at the object

let's actually bring the extents here

and go into this object definition just

select it right click on it and say go

and search for operator equal equal

you'll see that it is defined right

and there's lots of documentation about

so that's this syntax we're overriding

we're changing the definition of that

then since this is a simple function an

operator in itself is a function it

actually you can see it starts it has

in the parenthesis you get the value

that that operator is comparing your

that value that your class is being

compared to also needs to be a cat

because you cannot in dart is not

recommended that you compare tune

classes of different types with each

here we say covariance covariance

is a keyword that you merely use in dart

but i think it's important for you to

that it tells dart that although

we said that the parameter that comes in

is of type object but in our case we are

sure that the value that comes in this

function is actually a cat all right so

forget what the super class which is

object defines as the parameter type for

this parameter because if you remove

but if it's a covariant you're kind of

assumption all right so we say okay an

equal so we're mean compared our

instance of cat is being compared with

and what we're doing is that we need to

return a boolean saying whether they're

equal or not and you can see i'm just

i'm just comparing the name which is our

with the other instances name all right

now when you do that as you saw then we

get a problem here which is kind of like

a warning that tells you that okay

now that you've you've overwritten this

operator you also need to override the

to honestly i don't think like hashcode

is such an important thing to talk about

right now but just know that hashcode is

to your or a special identifier that you

assign to your instance of classes that

then used inside collections for

instance if you put your instance of of

then or sorry or inside a map as it is

called in dart which we talked about i

yes in chapter four so if you didn't

watch chapter four i strongly suggest

knows that the the keys inside its map

or the values inside the set are

actually unique it's using this hash

if you see if i go here and say command

dot to get a suggestion how to fix this

it says create method hash code

that is what is required to fix this

so you can see that it's an override

which means that this hash code

getter was defined on the object class

if we go to object and look for that you

can see that it is actually defined

and we're overwriting its value

and here it says i'm going to go to

super is our object so as super class

that sits up above us all right

but if you want to overwrite that in

case you in this case you can just say

okay don't get the supers hash code just

get the name hashtag and to be honest

very technical stuff which i don't think

belongs right in this chapter six but

just know that here we're creating an

identifier for our cat class

which allows dart to understand

cat classes instances are placed inside

collections such as a map or a set

if they're unique or not okay

so now that we've done all of this we

and you will now see that it says they

that's that's all we wanted that's

but there was a lot of code actually i

don't know it's like four lines of code

this is not even considered a line of

is a hint to the analyzer but uh

you could just say it's pretty much just

two lines of code but it is quite a lot

new things to be honest with you for you

so i leave this here so you can have a

for this chapter to be honest with you

we've talked a lot now in this chapter

about enumeration switch statements

classes objects uh constructors

abstract classes inheritance a lot so it

was quite a heavy chapter this chapter

go and read the also the official

documentation for dart because as i said

we don't have the possibility to talk

otherwise this course will just be

enormously big and that's not what i

please go and read the documentation

about the things that we talked about

especially especially object oriented

in the next chapter we're going to talk

about some advanced features in dart

async operations streams and generators

please have a look about at the

documentation and i will see you in the

hello everyone and welcome to chapter 7

of this flutter course in this chapter

we're going to talk about advanced dart

things such as extensions futures

async await generators and um

uh i'm kind of assuming that you've

already set up the project that we've

talked about in the previous chapter so

i'm not going to go through that again

and then i'm assuming that we have like

some sort of an iphone simulator so

or an android emulator or any device

that you may be able to test your

i'm going to bring up my project here so

i'm going to place it right there

this is how we left the project in the

and then i'm going to do command shift p

on mac or control shift p in linux and

windows in order to select the device

and i'm just going to say iphone 13 pro

which is a simulator that i have here

right there and then i'm just going to

run without debugging okay so this is

going to take its time and i just

then use this time to explain a little

as you can see here extensions are

the programmer and dart in order to er

are there the ability for the programmer

or add functionality to an existing

class in chapter six we talked about

classes and objects so i kind of um

wish for everyone who is in this chapter

to act actually have followed that

uh i'm actually going to go here and go

to do not disturb yeah i am actually

there so let's have a look at a simple

extension in dart and how we can use

that i can see that the programming

program is running i'm going to delete

the old code that we had and i'm going

to bring my face to that bottom right

and i'm just going to be a little bit

captions that i'm displaying on the

screen and that they're blocking the

screen so i'll just make sure that you

um let's also remove all of that and

then let's just say that we have a

simple cat class here who has a name

and we can go in here and say final

is yeah an instance of cat and i can say

actually we have to provide a name i can

see here and let's just say fluffers

dot's name okay so we print that name

just like that and um perhaps gonna

bring up visual studio code so you can

actually see the output so command s and

where are we getting this there are

equals oh that's an old command so

command is and you can see fluffers is

printed to the screen so that's because

we have the name here okay so i'm also

going to get rid of this caption right

now so you can see the entirety of the

code so like that bring it down here i'm

simulator and bring it to another screen

okay so now let's say that you want to

add a functionality to this or a

that allows a cat to run or allow the

cat to jump so one way to do that is to

cat class class itself and create a

function in there but what you can also

do is to go and say extension

for instance run on cat that's the

syntax for creating an extension what

a new functionality that is called run

now this is not the name of the function

itself it's just the name of your

and you don't have to really know about

the name right now so much it's just

when you can go and become more advanced

in dart and you for instance create

create extensions on different classes

for instance in your library and then

people or programmers who use your

specific extensions that you've included

in their code or they can exclude them

just know that it's just a name on the

extension so it doesn't mean so much

right now okay so then you can just

create a function that has no return

value called run and then you can say

and you know this syntax from the

previous chapters that this is how you

format a string and then in here you're

basically doing um spring interpolation

interpolation i think it's called

and you're including that name inside

your own string so the result is going

the name of this cat instance

then you can every cat instance in your

that function called run so you can just

and command this and you can see that it

says cap fluffers is running so

just know that extensions are

they're a great tool for you to use if

functionality that you're adding to an

existing class which it doesn't really

it may for instance belong in the

current source file that you're working

extensions are very very useful and

but i also believe that they need to

kind of be used with care kind of like

sparsely so when you really need an

extension you could just go and create

an extension and they have limitations

and as you get more used to

programming in dart you will understand

their limitations a little bit better so

can be used another example of an

extension is for instance if you had a

so this is an instance property and then

and then you say command dot individual

studio code on mac or control dot in

linux and windows and you create a

constructor for your personal class okay

so that's how you create an instance of

your person class then you can go in

final fou is person whose first name is

who and whose last name is bar okay

and in here let's say you want to be

able to calculate a person's full name

all right so what you could do is to you

and then here you could just say i have

a i want to calculate the full name so

that the result type is going to be a

and then you want to create a getter now

we haven't talked about getter so much

but just know that it's kind of like a

property it's a property that can only

be read forever but it cannot be written

as the name of the property and you will

so what you're saying here is that i

have a getter whose return type is

string and whose name is full name and

it returns the first name and last

memory with the space in between and

then in here you could just say print

and command s then i will bring the

i'll remove the caption so you can see

that foo bar is printed to the screen

so that's for extensions and i'm gonna

note that here in my i'm gonna mark it

in my notes that we've talked about

now the next thing to talk about the

and as you can see here future is a data

to be returned in the future as its name

and that is part of something called

asynchronous programming if you haven't

uh been doing uh programming before you

familiar with the term synchronous or

a synchronous task is a task that

happens when you ask for it and it

returns with the data that you ask for

um what is 2 plus 2 and then we'll say

okay it's four that's the synchronous

task but if you for instance say to your

go to the grocery store today please and

that is not gonna happen in this instant

it's i mean even if you even if you're

the grocery stores right next to your

house or your apartment then your friend

get get ready put put on shoes go to the

store get the mail can come back so

um that that is an asynchronous task so

an asynchronous task is basically a task

whose results are not returned

up until this point we've looked at

functions that i'm actually going to

remove all of this code from here so

that we don't have all of that

now we only have the void test function

all the functions that we've written so

far have been synchronous functions in

that for instance you would say

two and then it gets an integer of a and

it just says a multiplied by two all

and actually sorry hint so it returns an

integer the function call the function

name is called multiplied by two it

takes an integer as a parameter and just

multiplies that integer by two and

returns it it's a synchronous operation

okay however in dirt if you wanna work

with asynchronous operations that you

let's have a look at that um let's say

multiplied by two it which it may take

some time in order to multiply a value

okay this is hypothetical because yeah

the multiplication is going to be done

immediately but we're just going to

assume that yeah this is a complicated

multiplication and it will take some

time all right so let's say future and

then you would say what is the actual

future what does it contain what data

type can we say integer and then we say

and it takes a value of int a heavy

multiplies by two something like that

so it says i return a future okay now

responsibility is to create and package

up an integer and return it inside a

if you for instance in here say okay

you see that it says l10 isn't

compatible with the future of integer

because 10 is a synchronous value it's

right there it's present so what are you

doing here then you could say

okay what i do return is a future

and then you could say oh i'm going to

by a duration of three seconds okay

and then you'll see there's a second

parameter to this delayed function

uh if we have a look at delayed function

in here you see there is a second

parameter called future or a computation

in here what you're what you need to do

my second parameter is a function i'm

going to ignore its return value well

i'm just going to return the value of a

so let's actually see if we say

future delay duration seconds and then

we say the parameter is let's say e

and then i'm just going to say return a

what is this value going to be then

you know what we could actually look at

the documentation for future delayed so

so i'm going to go and open a new safari

window and i'm going to say future

this is the type of stuff that usually

happens anyways if you're programming

with dart i'm also going to increase the

size so that you can see it a little bit

and let's have a look at a future delay

here we can see how it's constructed uh

so you can see here that there is a

function that it doesn't basically take

i think the problem was that i may have

just created like a function that um was

this is how you would do that and i mean

it is a little bit strange argument like

i'm actually going to clean it up a

and then make this a constant as you can

see it's suggested here and then return

so i've written a lot of code i haven't

explained really what i've done here but

i will do that now so let's see

uh we're saying that we're returning an

it's not going to be returned

immediately it's going to take some time

for it to do its calculation okay so and

then here let's say a multiplied by 2 as

we as we promised in the function

signature okay so that's future int

this is the name of the function so

nothing magical about that and then it

takes a parameter that says integer a

in the function body itself we're saying

okay we're returning a future but we're

delaying its return by the duration of

three seconds so duration as you can see

is a class here if you go in it

actually is a constitution okay and then

there is a class on top probably

constitution in blah blah blah

constitution duration operator i believe

this is i mean the duration dart it's

probably just a class duration

if you look at here class duration so

so we're saying that we're creating a

duration as a first parameter to the

delayed function of the future so we're

saying that we're delaying this future's

return value by three seconds and then

it says okay i'm going to wait three

seconds but then i'm after i waited

three seconds i'm going to call this

and this is kind of like a shorthand for

creating a an inline function you could

also do it like this you say okay my

function that i'm providing to this

function so it's like you're passing a

function to the future delay function

and then in here you could just say okay

i return a multiplied by two and then a

semicolon so this is probably a little

we could actually use this function in

i mean now that actually we we've now

talked a little bit a bit about future

future then you need to know something

are very related to each other but quite

different in their meaning and

i just want to now explain actually

async is a key word in dart that marks a

function as asynchronous in that

remember synchronous is something that

returns immediately and asynchronous is

something that does not return

immediately takes some time however to

mark a function async in here it means

that this function internally

can execute commands that do not return

ac marking a function as async it

it it means that this function

internally calls other functions that do

let's now say final um result is

now that we've done that let me just

print the result and you'd be surprised

when we do that and you'll see that it

is not what you think it's not going to

so i'm gonna get rid of this caption so

that you can see the the result and i'm

gonna clear the results in the console

and you'll see that what got printed to

the screen is actually the future is not

is not what you think it's not

the value 20 which should be a

multiplied by 2 which should be 20. so

what happened here is that when you call

a function that returns a future you're

actually getting the future back you're

so how do you get that data back well by

prefixing the function with the keyword

so as its name indicates this

keyword is just going to wait for

the result of this function to be

calculated and then it's gonna go to the

these two are very related to each other

and you'll see that if i remove async

then i will get an error saying that

called test is a synchronous function it

basically means it doesn't return

anything and it asynchronously does its

have to wait for anything so

but then inside the function you're

saying wait which means yeah i have to

wait some time for something and that's

what you need to do then is you mark

your functions with async if internally

in that function you're using a weight

the weight itself then is used for

waiting for the result of the future

okay so if you remove this async and

then you remove this await everything

synchronously getting the future of the

heavy future that multiplies by two and

printing it so it's not doing any

asynchronous work in here you can see

it's just getting that instance so now

that we're calling that let's command s

three seconds and then printed the

result 20 to the screen okay

that for us was async and in weight and

we're going to use async and in a way

and await quite a lot in this course so

it would be really good if you could

have with this information that i gave

you if you could just have a little bit

a read about future like documentation

dart um and maybe async await and

read a little bit about them because

they're so important in doing

asynchronous work in dart that we just

all right um so now we've talked about

and we've talked about async and awaits

so i'm just gonna mark them as

um the next topic to talk about

so as you saw here a future in dart is a

class that controls the computation of

an asynchronous value in order to be

returned in some point in the future

in your client's work or even server

work you need to do work that is

asynchronous however it is continuous

work for instance if you if like i have

the time uh displayed on top of my

screen on the right hand corner

it is a it is a stream because it

doesn't have an end ready it it's a

continuous pipe of information every

up on top right it's gonna increase and

it's gonna go to zero six fifty zero six

it is continuously calculating the

current time and like sending it down at

now in asynchronous programming and in

which you may also get into if you're

following with this course or if you're

following some other course you may

actually be interested in learning about

a stream is just a pipe of data

actually it completes successfully or it

never completes or it errors out and

um a stream of time up there you can see

it's not 0 6 50 in the morning and it is

a stream of data that never completes

because time is just just continuously

so when we talk about streams we just

sends data down this pipe that

as you saw in the case of a future a

future ends it calculates its data and

it returns and it says i'm done

is a future that just continues working

okay so it calculates some data in the

future and it also sends it down the

stream and it says oh well i'm not done

here's another data here's another data

let's have a look at this uh stream and

see how we can work with streams okay

so let's go and create a stream of um

and then we say get name okay

you your job is to create a string so if

see that hello is not compatible with

the return type that you promised it's

um so you it this is very similar to how

future of integer you couldn't return an

integer in that future but you have to

create a future of integer and inside

return the actual integer which was the

computation if i go back you will see

the future delayed and inside this

function you're actually doing the

how do we create a stream and you could

okay periodic for instance or a value

okay if you say we return a stream of

what this means is that you have a pipe

but the only value that it contains is a

foo is the value of food that's it all

so let's now go into this test function

and try to consume this uh stream if you

and then i'm going to clear the logs

here and say command s you'll see that

just like future it just says instance

of controller stream okay so it is not

the actual value inside the string so

the question is how do you wait for

inside a stream you could just say okay

actually we could read this a weight

applied to stream string which is not a

dart is understanding that okay you're

this is this is not just like a future

that you're gonna wait for there's

nothing to await like it's not a single

for awaiting for values inside a stream

then you could say wait for final value

and then you could just print the value

so this is a little bit of a strange

syntax but if you read it in like in

english it makes perfect sense you're

waiting for values in get's name

if you just ignore the final in here

but read it in english from left to

right await for values in get name

and then at the end i'm going to say

and you'll see it immediately said foo

and then stream finished working i'm

foo stream finish working okay

so this is an interesting concept but

it's still not a stream really i mean

we're packaging the full string inside

it's only one value we could have done

that with a future so let's take

continuously so what we could do in here

periodic it means periodically produce

values and in here you can see the first

parameter is a duration so let's say

of seconds every second okay and then

there is a second parameter in here

that you'll have to provide if i move my

mouse over periodic you'll see that the

second parameter is this string function

int okay so it means that give me a

function that accepts an integer

and then it returns a string all right

and it understands that it needs to

return a string because you're saying

that your stream is a string if you

change this to an int and then went here

um to the documentation and the

documentation will actually or the

method signature will change to say that

uh your you should support you're

supposed to take an integer in this

function that you provide to me and then

you need to return an integer okay so

that string i just wanted to show you

that that string that was shown in the

function signature there it's because we

promised to return a string in our

basically the function signature said

that you need to accept an integer so

i'm just going to say value

i'm just going to say return foo

conform to that function signature we

said we take some value and you see the

and then we're returning a string okay

so now we can consume that so if i clear

this log and i say command s you see

that every second the value of foo is

going to get printed to the screen and

actually i need to remove this caption i

you see that 10 times 11 times 12

um i'm sorry about that the caption was

blocking the screen i wasn't aware of

that um or actually i was aware of that

but i forgot that that was the case in

so you can see that every second the

stream is sending a value all right now

that's that's basically the gist of

i'm wondering actually if we're gonna

use the streams in this course i believe

i need to probably look at the um

yes i can see that we're actually using

if you don't fully understand streams at

the moment because we're gonna talk

because we're gonna actually talk about

streams and stream controllers later in

just know for now that a stream is like

continuously or periodically can return

values and then you can wait for

those values using the await for

in this chapter is generators so

generators are very very interesting in

some other languages also support

but not not all modern languages do that

a generator in dart is a function

i don't want to say iterable but it

internally calculates that data in a

that's the best explanation i can come

up with to be honest with you let's have

i think the best way to do that is

actually write a function that does uh

and then we have a test function here

let's now go create a generator and

create a function that returns the

a way to do that is would be to say i

want a list of integers okay and my

or get one two three like this

and you could say return one two three

like that okay so that's completely

another way of doing that is to use

and iterables i mean you need to

understand what iterables actually are

and they're kind of like lazy

collections and when you get used to

doing more software engineering you will

why we use lazy collections

but for now just know that an iterable

is a prepared and packaged up list of

it is not completely calculated when it

it's kind of like how a restaurant works

in a typical night a restaurant might

have for instance 50 customers

when that shift begins during the night

not all food is ready i mean it can't

possibly be like when cut the first

customer comes in we can say that the

food for the 50th customer is already

that's how a restaurant works it it

listens to orders of its customers and

then it generates the food based on the

orders that's how an iterable works okay

however a list in dart is an already

packaged list it means that it's as if

like you go to a supermarket and then

food that's already packaged 30 packs of

that that is a list that is 30 ready

readily packaged food items and then you

take away that's how list works but an

it's a list of like things that gets

just know that for now so we just said

either well and as you can see dart

understood that okay a list is also an

eye trouble so i don't have to worry

about that so it didn't give you an

so let's go and actually instead of

doing one two three let's go and mark

uh a generator and you do that with

so and this would be a stream like

now the difference between sync

with a an asterisk an async with an

it is a generator function that returns

a list of things but it calculates that

asynchronously and as you can guess the

async equivalent of the sync asterisk it

does the exact same thing but it returns

and which means it's asynchronously

calculating its result okay so

when you mark a function as sync you

like this because you can see that you

can see that it says you're creating a

generator function so you have to kind

of calculate your results now you can't

just return a bunch of things to me okay

to do that you would use a keyword in

a very interesting keyword that you

would use only in generator functions as

and in here you're telling dart that

okay the first value that i'm outputting

in my iterable is the value of one so

i know or say we say four value in

and then you could just say print value

you can see it only prints the value of

1. i'm actually going to get rid of this

caption you can see the output

it only prints the value of 1 just

because we yielded the value of 1. okay

so you could just send then say yield

one yield two and yield three

then you'd see the values one two three

in this function internally then you

could do a lot of other important things

maybe some synchronous uh some other

synchronous calculations and every time

you would do a yield and you could also

print the entire return value

yes you don't have to do a four loop

so you could just say print it and then

it would say one two three okay

but if you do a for loop then you're

actually taking advantage of that lazy

capabilities of an eye turbo so you

could break out the loop at loop at any

so let's clear the logs and command s

you'll see only the value of one and two

gets printed and then as soon as you're

at the value of two then you're breaking

and that means that this yield

was basically never calculated so that's

so you could also create asynchronous

generator functions as i mentioned and

that means that you're kind of like

creating a stream of iterables

to be honest with you asynchronous

generators i've i've maybe used them

uh in in the many years i've used dart

i don't think you're going to use them a

lot but just know that they're there and

you could use them by prefixing your eye

saying that basically you're returning a

stream of eye troubles and then

suffixing your function with async just

so and then here it says okay you said

that you're returning a stream of ideal

integers but you're turning only one

value in here then you would just say

um but then you would say yeah then you

have the ability to do whatever you want

here like return an actual eye variable

okay so i'm not going to talk about

asynchronous generators to be honest

with you in this course because they're

kind of like outside the scope

so just know that they exist and you can

okay i'm going to mark in my notes that

we've talked about generators so

the next topic to talk about are

and i'm going to bring up a caption here

programming languages that do support it

there so that you avoid writing the same

let's say that you i mean this is a very

example i know it's a little bit cliche

i think it's cliche for a reason and

that's because it's such a good example

a pair of data let's just say class

and then in here you could say okay what

pair of data do i want to store okay i

value one as a string and i want to also

store value two as a string and then you

create the constructor for it okay

all right that's that's great it's a

pair of strings but how do you then

pair an integer like two integers then

i have to have another pair class and

but then you have this problem because

pair is already defined as a class up

so you cannot reuse that you cannot have

the same name then you would say okay

and then here you would say pair of

and you make sure that the constructor

i mean you may have also i mean in this

point at this point we don't have logic

at all in these two classes you may have

actually quite a lot of logic in your

as i mentioned i think during one of

these chapters i think it was chapter

one or two program one of the main

characteristics of software engineers is

um writing the same piece of code over

that's where generics can come in so

what you could do is instead of doing

let me bring this here let's go and

create a class that is generic and you

and then a format for creating a generic

class is to write after the name of the

class oh just to a less than and greater

than sign okay and then open your square

names like the data types with usually

with single characters let's say that

what you want is a pair of any data type

let's call the first data type a

and the second data type b because

there's two values so let's call this

one a and this one b okay you would just

write them as we just say we say a and b

so then in here you would say final

value one so you're telling the compiler

that okay whatever pair i'm creating

the first data type that i accept is a

and that should be placed here

and then we say okay then the b is the

and then we create a constructor for

so how you would use this then is you

then you would say foo and bar okay

and then this is just like a simple it's

very similar than to pair of

strings that we wrote up there you see

it worked as well but now in this case

dart is smart enough to understand that

names is a pair of string and string

meaning that the two values that you

pass to this pair generic class were

actually then placed for you

magically inside the a and b templates

that you provided up here okay

so if in if in this case then you said

and then i have the value of 20

then dart smart enough to understand

that oh now it's a pair of string and

that's how you would use uh generics

basically so i mean there are so much to

talk about about generics and how

uh basically utilize them in order to

very simple classes so that they're

so that they're reusing as much

capability or as much code as possible

without duplicating that code so

and talking about generics to be honest

with you it could be it's its own entire

course we could go on and on four five

six hours i could talk about generics so

just know that generics are created like

this you say class pair and then you

your generic data types which then in

then in turn get placed inside the

definitions inside the class itself so

all right now that we've talked about

generics um i believe that we could kind

chapter where we talked a little bit

more about advanced topics in dart

async awaits streams the weight for

now i'm actually really happy that we

went through chapter number seven which

is this chapter because up until this

point we've kind of been like preparing

it's now time that we put everything

that we've learned into practice

and actually start building our project

so i'm actually getting goosebumps

because it's such an important part of

this course that we've actually gone

through the basics we've talked about

dart we've talked about like some of the

basics of setting up the simulator etc

etc that it's with great pleasure that i

can say okay we've gone through that now

and all you need to do right now is just

to practice and what better way to

than to put what you've learned um into

flutter project that we've been aiming

to do from the beginning so

without further ado let's then

prepare for the next chapter which is

chapter eight and in chapter eight we're

uh project setup and then we're actually

gonna add some dependencies to our

project which we're gonna use

let's aim for that and i'll see you in

hello and welcome to chapter number

in this chapter we're going to talk

project setup in the previous chapters

up until this point to be honest with

you we've been just working with dart

um laying the foundation for learning

the programming language that actually

programming language that you're gonna

need to be quite comfortable with in

order to be able to write your flutter

applications so you're gonna learn more

and more about dart as we go on in this

course but it is very very good if you

look at the intro chapter and then just

kind of like follow along on the

chapters up until this point so that you

get the general idea of what dart is all

about and then how you can use it

at a very shallow level i mean i know

there's lots of material that i put out

we really didn't like go so deep in

every topic so i just wanted to give you

the different available options in dart

if you haven't watched those chapters

please just go ahead and skim skim over

them even if you're comfortable already

in this chapter we're going to talk

about the project setup and this is the

like one of the absolute most important

um an application for flutter so if

if you're thinking of maybe skipping um

over this chapter that's also okay if

you know what you're doing but if this

is the first time that you're setting up

a flutter project that then i think it's

follow along with this chapter

so i'm going to go now into um

let's do some setup here so what am i

going to do i'm going to bring my face

to the bottom right here so you can see

and then i'm going to bring up the

caption for the next item that we're

and in here well we have a um

as you can see there is a command that

you can issue in the terminal to create

every flosser project has different

properties it has for instance a name

which is the entire like the name of the

main properties of flutter project is

now the identifier wouldn't be so

important had it not been that flutter

can actually deploy to ios and android

an ios app and an android app is

what defines that application as unique

as on the app store where ios ios users

and ipad os users can download

play store where android users can

android apps so these identifiers are as

i mentioned in one of the previous

chapters are kind of like reverse domain

identifiers so it's kind of like if your

foobar.com and your application is

then your reverse domain identifier for

your application will become dot

you take your domain name and reverse it

so if foobar.com becomes com.fubar and

then you put dots after that and then

you put your actual application name

so these identifiers need to be unique

on the ios app store or google play

store is already gone and registered

the reverse um basically that item

for any of their applications so they

said okay here's my application called

image gallery but it has a completely

random identifier of com.foobar.pass

then you as a new developer even if you

want to do the same funky uh deployment

to the app store you can't register that

name anymore because because it is

think of the identifier of your project

what is gonna carry on from the start of

where you create your project all the

it is quite important that you actually

choose it wisely because if you don't do

that wisely from the absolute start

unfortunately you will have to do some

to go and update that yourself so

so i would i would really suggest and

recommend here that you take a little

bit of um time to think about what that

what you prefer that identifier to be

and what you're comfortable with and

what for instance if you have a domain

the app store and for google play store

so if you have a domain name already

registered on your name i suggest

strongly then that you use that and if

you have domain names personally and

and for your company then you need to

now know whether you're going to release

this application under your name

personally or if you're going to release

so these all play a role but

without further ado let's just go and

i to be honest with you i personally

haven't really thought about whether i

want to release this application as a

private person or if i want to create it

at apple and at google is under

my company's name which is pixelity ab

in sweden then i'm actually going to use

that company's domain name which is

because s is like the swedish domain

so i think i will do that so let's go to

and open a new terminal let's go to

i don't see my screen right now but i'm

just going to bring up a new terminal

and bring it up so that you can also see

and i'm gonna increase the size of the

text so it is clear what i'm typing okay

so let me go ahead and create a project

so i'm gonna go to my development um

folder where i have all my projects and

and then as you can see is flutter

and then and then dash dash org as an

and i'm going to see say se dot pixelity

now as i said my domain name is called

pixelity.sc but your org needs to be the

reverse of that okay so remember reverse

identifier so reverse domain identifier

then if your for instance organization

hello dot com then here you would have

to write com dot hello alright

so i'm gonna say s epixody but you

shouldn't do this so if you're following

along with this course please just

choose an identifier for your domain

that it makes sense to you and if you

don't have a domain if you if you're not

bothered by all of that if you're not

going to release your application to the

app store you don't even have to care

about this just put anything in here you

if that's what you want so it's not a

big deal to be honest with you so just

go ahead and pick an identifier so

i'm going to say s epixody because

and then in here you have to write your

what should we call this application to

be honest with you i i mean i personally

made up my mind what this application

should be called maybe we should call it

my personal notes or my notes

or notes list i don't know not my notes

sd pixel in my notes yeah why not

let's just call it my notes then all

let's go ahead and do that flutter

and i can see i mean actually i'm very

grateful that we got that little

notification on top so let this do its

it did its work and it's done and it

called something and it created a folder

and on top of this window if you saw

then there was a little message printed

a new version of flutter is available to

update to the latest version just run

flatter upgrade so that was not a part

of this course i didn't mean it for this

to happen but i can't control it either

because flutter is a tool that is being

developed by google it's an open source

tool when there is a new version when

you run any of these flutter commands

um with the version repository to see is

there any new version available and if

there is then it's going to give me this

um as i mentioned in the introduction of

i've planned this course quite a lot but

i haven't i can't plan it 100 so things

will happen that i hadn't planned for

and then we just have to roll with the

punches and i'm actually glad that this

thing happened right here so you can see

how to upgrade flutter as well so

as you can see it's very easy just copy

just say flutter upgrade okay so i'm

going to go at the bottom of the

terminal i'm just going to say flutter

right so this is going to actually take

some time depending on how big the

different kind of engines as you know

binaries or applications for ios it can

output it for android it can do it for

and basically desktop searches and mac

windows linux and then you will have web

quite a lot of things involved in

flutter as you can see in here it's like

downloading everything necessary in

order for you to be able to create

so after that is done you see it goes to

the ios tool so it's downloading but

it's also i believe after it's done

it also needs to make sure that it can

this is a process that might take some

and in order to avoid us having to wait

as you can see it's now going to web sdk

so we don't have to necessarily wait for

this so i'm just going to create a new

oh it actually finished so that was

quite fast all right so it it finishes

work we don't have to do anything

um so that's how you upgrade flutter so

just run this command as suggested by

the flutter tools itself flat upgrade

we've done that step now so we've set up

our project i'm just gonna move to my

and i'm gonna make sure that that topic

and for the next item what we're gonna

do here is we're gonna talk about um

we're gonna basically have a quick look

the environment set up by flutter when

you run photo create because the flow to

create doesn't just like create an empty

director it actually creates the

skeleton or the scaffold of your

flosser project but pretty much

everything necessary for you to be able

so in this in this application i mean in

this in this step of chapter 8 we're not

actually going to run the application on

any device that's for chapter 9 and for

but what we are going to do is to have a

project structure so let me go to my

notes here and what i'm going to do is

extension which is provided in the path

so i can just say code dot which opens

up visual studio code in the current

then once that is done i'm going to

bring a visual studio code here i'm just

going to take a little bit of care to

important parts of the screen

okay and i'm going to increase the size

quite dramatically so it's visible for

you as well it is very big on my screen

a nice size on the on the actual output

alright so as you can see here is the

folder created by flutter create

and there are quite a lot of bits and

a bit about a few of these folders and

one thing that you need to understand

about flutter is that it actually is not

it's not really like react native

uh if you're familiar with that flutter

on ios for instance it for those who

have done ios development uh flutter it

outputs a native binary on your on your

fat binary basically for your uh

ios application and it just puts one

view on the screen and then it

graphically renders all its contents

using metal okay so if you're not an ios

developer that probably doesn't make so

this part that i'm going to mention now

should make sense for everybody but

when you create a flutter application

and the flutter create command basically

spits out different parts that may be

necessary for your application to run on

one of those platforms one of the key

platforms that flutter runs on is ioso

that is the folder that contains the

native bits and pieces necessary for

in an ios simulator or on an ios device

such as an iphone or an ipad okay

so this is like as you can see it's the

project or the workspace and sorry and

the workspace because for those of you

who are ios developers you will know

there's a thing called cocoapods and

flutter internally actually uses

cocoapods for ios if you're not an ios

ios or android or web application

can bring with itself dependencies and a

dependency is a way for your application

to bring in code from other people in

order to be able to achieve special

there are various tools available for

ios developers android developers

web developers to be able to bring in

dependencies for web for instance if

you're writing a node application you

will just use npm which is a node

package manager if you're using swift

you will probably just bring in for

instance spm i think um swift package

and there's another a third one

um which i've kind of forgotten the name

which i may remember later if you're

using android you're probably familiar

with gradle and that you can like use

bringing in external dependencies so

this is a platform of android and this

is a platform of ios and here's web and

flutter sits on top of these so it can

all the small bits and pieces for these

platforms to be able to be packed

packaged inside one flutter application

and all these different platforms down

excuse me they can have their own

dependency management so the dependency

managements kind of sit under one layer

flutter then talks with these dependency

managers and says okay you need to

install this dependency for me to be

the reason i mention all of that is

that is the reason you can see a

workspace here and an xcode project and

that's because flutter internally is

cocoapods which in turn creates a

links together the main project and all

if you're not an ios developer if you're

not interested in all of this just know

is just so that your application run can

the next part which is important is the

test folder which we're actually going

the test folder is where you create your

if you're not familiar with software

development from before if you don't

have a background software engineering

the ability for programmers in order to

be able to make certain assertions about

their code and in order in order to make

sure that they can automatically run a

series of tests against their own code

to make sure that everything is

functioning as the programmer intended

that to if you are if you if you are

coming from software engineering

background that know that we're gonna

put our integration tests we're gonna

widget tests and unit tests inside this

test folder okay so i hope that covered

everybody that's that may be watching

then you also have a folder called

android and this is as you would expect

it is putting all the necessary files

and folders that is required for your

hosting your flutter application so

just know that flutter kind of

is a series of tools is like a mobile

that gets injected into these native

applications and natively also renders

and just like we had a host ios

application here you will also have an

android folder which contains all the

for your application to be run natively

phones and on android tablets

this is as you can if you're an android

developer you're probably like already

familiar with this like you have your

app and build great gradle inside the

app folder so there's nothing like fancy

going on here it's a simple android

application which you can actually

uh if you have android studio installed

on your computer if you want to you can

open that folder and actually have a

look around and even run that

application as a native and android app

that is our android folder and as you

would guess then we have a web folder

i think i mentioned this before but

flutter supports uh deployment of flash

applications to the web as well so you

can actually create web applications

with flutter it's nothing that we're

going to discuss in this course

particularly but if you're interested in

writing web applications with flutter

so have a look at that if you're

interested in web applications because

though web applications in flutter are

relatively new but foster has actually

come really far with with that so people

are creating all sorts of websites with

okay um then we have a little file here

and um as you can see it says this file

if you are not coming from a software

engineering background then you may not

know what analysis actually means but

a way for a flutter to be able to

have a look at the code that you write

sees fit so where it sees that oh you've

made a mistake in writing something that

could be written in a better way then it

consults this analysis options yaml file

and then it says okay what are the rules

that i have to adhere to like do you

want me to be very strict about certain

rules or do you want me to be like less

strict about other rules or do you want

certain mistakes that you're making so

the analysis options yaml file as it is

basically define the roles that make

in this course we're not going to talk

about so much analysis options to be

honest with you but just know that it's

the project structure here again

um and the next thing that we need to

have a look at which is very very

important is this file pop spec dot yaml

now um this is a file that i mean

one of the things that you you'll need

to know about flutter and the basic

structure that it creates for you is

that there are tons of documentations

and documentations are like so so well

done in my opinion in in the flutter

world where i personally come from like

the back-end developer development

background like i'm doing django or

where i'm doing ios development

sometimes documentation can for instance

on the ios native world be very kind of

flutter has gone like well above the

line of what is required from a

developer's perspective in terms of

documentation and they provide a lot of

and if you're not coming from a software

development background the documentation

information provided by the developers

who created the tool for you in order to

help you get better at that tool okay as

you can see here there's a file created

for you pop special and you can see

there's lots of gray lines here prefixed

if you remove them you'll see that they

become normal sentences but if you put

them back they become something called a

documentation and a documentation if

you're not from software engineering

background it means just piece of text

provided as an information block to you

which is not code anymore so the program

turn this into any sort of sort of a

code it's just going to ignore that this

is just for you to learn okay

so let's go back to this pop specky ammo

and talk about what it actually is pop

spec yaml is such an important part of

flutter that i think that you need to

ignore i mean don't ignore the comments

go and spend some time and read the

comments just to understand what they

um what i'm going to talk about here is

a little bit about what this pop spike

yaml actually is it is if you're for

instance from coming from a web

background and if you've worked with

node.js then we will have some sort of a

json file or if you're coming from

django you'll have settings.pi file if

you're coming from native ios world what

would be the equivalent of the config

it kind of will be kind of like your

i mean it is your it is kind of like a

what your project should actually be

looking like its icons the version

number its name all your dependencies so

these things will be all placed inside

when you change this file if you're

already running your application then

understands changes to this file and

then reconfigures itself if it can on

with your new configurations if it can't

then you may have to restart your

application like if you make drastic

changes for instance if you bring in a

then the project cannot be like re-run

immediately it needs to actually

recompile and link against that

dependency it's just like humanly

or computerly impossible for it to do so

so let's have a little look around in

this pop specky ammo file as you can see

there's a tag here called name and it's

and it's a value it's my notes and if

from the terminal if i bring back the

bring up the text a little bit

uh this is what we created right this is

the project this is how we created the

we said flutter creates an organization

of seda pixelity and then my notes all

that is what the my notes is for this is

your project name my notes all right

and this is a little just a little

description of what this application is

curious about what word is actually went

s e se.pixelity or whatever you created

now you can see i search for it i said

command f in visual studio code on in

mac or control f in linux and

windows and visual studio code and i

don't know actually what the shortcut

android studio i just now heard studios

a little bit peculiar about its uh key

mappings so it may not be command f on

mac or controller for linux and windows

so i search here now for sepixology and

you can see that there are no results so

this particular thing that i stressed so

much in the beginning that is very

is not actually something that flutter

itself needs as i mentioned it is

something that the different platforms

that you'll deploy to need so if i now

actually say command shift f in visual

studio code which searches in the entire

project say se.pixolity you will see

that it is found in different places

inside this project for ios for instance

you can see here is in the project pbx

and for android as well in our build

gradle so you'll see the application id

became se pixelity my nodes

and for ios if you look around here as

well you'll see that it is s e pixel in

so the other thing that you'll need to

know about the pop spec yaml is this

version number here and this is the

if you're not from a software

development background um if you haven't

done software development before

versioning is a way for you to tell

various places that you publish your

application on for such as ios app store

if you have something new in your

so for instance if you and this is this

is how software is actually actually

labeled like a software has different

what you're deploying what you're

developing here is a fluster application

but from the point of a store such as

the app store it's it's just a package

with some properties like its name

identifier and its version now this

version is very important because it is

or i know that google play store

actually supports also four digits

these numbers actually mean something

if you begin from the left and then you

go to the middle and then to the right

the left number is something called a

the middle number is called a minor

number and the right one and then most

the rightmost number is usually called

in normal software development the

process is kind of like this that

you begin with an idea you say okay my

idea is to create a notes application

that's that's the first idea that's idea

number one then you put one as the major

number then you begin by zero and zero

okay so that's how a version number is

so you say one zero zero that's version

then you release that application you

say okay i'm fine with that version one

and then you're in the kitchen cooking

some food and then you say okay um it

would be great if i could put like um if

the ability for users to be able to

it's not a huge functionality it's just

a little bit um improvement on what i

then you will go and say okay is that a

hmm it's not a major idea a major idea

would be like a total rewrite of the

application adding massive number of

features fixing massive number of bugs

etc so it's not a major idea then you go

to the minor idea and that minor idea

corresponds to this minor version here

so you say okay the previous one was

zero this one is how big of a difference

hmm it's just a small future so let's

not major enough to be a major idea but

but quite a big minor idea then you

from zero to maybe two or three it's not

so popular to do that usually

would go chronologically in that order

like one two three four but you're also

in special cases so let's say then you

and i'll now make it build and send it

just remember that your previous build

depending on how your project is

structured like you may decide that okay

every build that i make i'm going to

actually increase this build number so

the previous one was zero now it's gonna

be one then it's going to be two three

four five six blocks so every time you

make build and send it out to your

consumers even if they're a group of

your only consumers may actually just be

people who are downloading your

application directly from the app store

or from the web they may be interacting

with your application as well

then you may say okay every time i make

a new bill and send it out that's when i

actually increase this build number

or depending on your project setup you

come with into an agreement with your

teammates to say okay we don't increase

the bills chronologically but every time

we change the major or the minor we

actually reset the build back to zero

and then we go up chronologically so

i i don't want to go to be honest with

you too much into detail about the

interested in software development and i

think if you're watching this course

that kind of means that you're

interested in software development

you'll need to know about this so just

know that version is your way of

labeling your software and its features

but you don't have to play with this so

much to be honest with you so i think in

this entire course we're actually not

uh the next bit of information in the

pop special is the environment as you

now when you see sdk just think of

and this sdk is referring to the flutter

if you share your source code with some

other developer who's sitting maybe on

if they get your source code and they

want to for instance be able to test

this application on a simulator or an

emulator on a real device then they are

or less than this all right so you can

actually get your flutter version by i

believe if you run flutter dash dash

it will tell you that i'm plotter 281

and that as you can see here it says

yeah the sdk required in order to run

one five zero more than or equal to that

at least at least two one five zero okay

so that's your sdk the flutter sdk

the other part that you'll need to know

about is this section in the pops wiki

ammo and that that is called the

dependencies and this is what we're

going to talk about actually

and dependencies as i mentioned before

uh are ways for you as a software

developer to bring in code that other

people have written in order to make

your application application function

better or function in a completely new

um you need to kind of be careful with

depending on what dependencies or

libraries you bring into your project it

can actually make your life better or

basically when you bring it in a

dependency they're usually code written

by somebody else or other people that

may be working on a library so

when you're if you're not coming from

software development background then you

will need to know this and i'm just

going to warn you from from now so that

you've heard it at least from somebody

dependencies when you're picking

dependencies just be a little bit

it may be that they initially make your

since dependencies are code written by

and other people's priorities change

their lives may change so that they

don't have time enough enough time to

continue working on those dependencies

i have personally run into the issue

that uh we brought in a dependency into

a project and then after a while we just

actively working on this and maybe even

the developer made that library um

deprecated and deprecated is the world

that a word that you'll get to know when

you work more with software development

and deprecated kind of means that the

library is not supported anymore the

is not actively being worked on anymore

and the developers are encouraging you

when you bring in dependencies what i'd

like you to do is just to have a look at

and prioritize your picking and cherry

if the dependency is written by a single

um be a little bit careful about that

priorities may change and they may not

like continuously work on a

even if if it's an open source project

they may not be able to continuously

um if independence is written by an

organization especially an organization

faith in then prioritize it a little bit

if a dependency is written by a bunch of

under an organization prioritize that

also higher than a single person who has

who has a library under their private

that doesn't necessarily always mean

that a dependency created by an

organization is actually better quality

it just means that the chances of it

being deprecated are a little bit less

chances of the same library being

deprecated had it been written by a

single person under their private name

so these may actually to be honest with

you sound a little bit high level at the

think okay why do i have to need all

this it's just that it is very easy for

newcomers to flutter to get

dependent on dependencies in that it's

so easy to bring in a dependency and

just work with it that people forget

this is actually code written by a

single person sitting in there in their

room just like me sitting here and

telling you not to listen to people who

but i believe it is very important to

your thoughts towards a little bit more

constructive dependencies that are good

for your project in the long run but if

you're writing an application i just

want to release it and don't care about

after you've released it maybe

maybe it's okay to bring in a dependency

that that dependency that you don't even

care about but i would even challenge

that idea of releasing an application

which you may not care about after the

first release but because that's usually

okay a lot of talk about dependencies

but i think that had to be said

so we're talking about dependency i'm

just gonna bring in the captions so

now here you can also see there is a

dependency dependency here by default

brought into you by flutter itself

and cupertino icons is a dependency that

i believe that the flutter team itself

you may be thinking okay what are these

dependencies like where do they come

from they actually come from normal

companies so i'm going to bring up a

and it is called pop.dev i'll bring it

up so that you can actually see it

you can see that in this website popped

up there you can search for dependencies

so i'm actually going to copy this

and i'm going to paste it right there

um kupertino icon just enter and i'm

gonna press on it and you'll see that

it's published by the flutter team

pop.dev is the website where you will

search for dependencies so you just

search for a package and then it will

bring up results here for you so

um this is how you'll search for

now that we talked about that let's also

talk about something called dev

dependencies that will bring into your

which are useful only under development

if you're familiar with software

engineering the normal dependencies will

get linked to your project and then you

will they will be shipped with your

application whereas dev dependencies

there are only dependencies that

under the development time will use in

order to make your software better and

as you can see here one of the

dependencies for instance is flutter

or flutter lens in this case as well

okay so there are lots and lots of

things to talk about here and as you can

see here in the future actually we'll

work with this that you can bring in

assets and images and bringing them into

this is a quick look around at the pub

i'm just going to tick in my notes here

that pops back yaml we've talked about

we actually in our application we're

going to need some dependencies in order

to be able to continue working with the

we haven't talked so much about firebase

before but just know that firebase is

kind of go serverless but also have a

server now serverless is just a fun

funky word that is being used nowadays

to describe a server written by somebody

else so a server that you don't

personally have to write if you don't

come from a software development

background for instance you're a product

a server is where your data sits in the

you as a developer sitting in front of

your computer right now you're writing a

flutter application and your flash

application is going to be installed on

ios and android devices and that is the

client the client is the consumer of the

data sent by the server okay so the

server is where the logic sits on a

computer in the cloud okay and firebase

is a computer in the cloud just think of

think of that that is written by google

so you control it with simple commands

on your computer but it controls your

data so your client your flutter

application can connect to it and grab

the data and read the data and

manipulate the data on the client side

now in order to talk to firebase we

dependencies and firebase um will i'll

bring up my safari window here

now let's have a look at firebase core

click on it firebase core as you can see

it's written by the publisher is

and just remember that flutter is

i personally think that anything related

to firebase is completely okay to bring

in into your flutter application has a

um i'm going to go here and then say

for this particular project okay so

if you're in visual studio code you can

the terminal up uh i actually forgot the

command for bringing the terminal i

think on my mac is control backtick

but i believe you can also always bring

up terminal advice going to terminal and

new terminal okay now i can see there

are two terminal windows here okay now

i'm going to get rid of the explorer on

the left hand side so you can see that

the data a little bit better here

there are four dependencies that we need

to bring into our project all right and

i want you to follow along with this

previously what we had to do in order to

i mean previously in the previous

versions of flutter if you wanted to

bring in a dependency then you'd have to

you go to your in your pop spec and then

add your dependencies manually with

you have to go to those dependencies top

dev websites to see the current version

but with the latest versions of flutter

you don't have to do that all you have

to do is just to say flutter pop add

i'm going to do that right now

so that's how you bring in a dependency

the first dependency that we need is

firebase core so just enter this command

then say the same command but say

off i'm gonna have a look at my notes

basically here to make sure that i'm

entering the correct dependencies

and i'm not going to talk so much right

now about what these dependencies

because that is going to take a lot of

time as well so let's just bring the

dependencies in there are four

dependencies so the next dependency that

cloud firestore is the third dependency

and then we say firebase analytics

so that is the fourth dependency

we've brought in four dependencies at

the kernel the main important parts

parts of firebase which again is what

we're going to use as our server where

all the nodes for all our users are

auth is the short form let me see where

did it go um here firebase off that is

um i haven't yet shown how that our

application is actually going to look

authentication is where our users will

uh log into our application and log out

and also get email confirmations to send

to their emails in order to be able to

auth is for authentication and that's

what we're gonna use it for in order to

are interacting with our application

they're actually logged in okay

the next part is cloud firestore

and this dependency is used for when we

actually store a logged in users notes

it's just funky names to be honest with

you they're just names decided

by developers just like me and you so

and the next part is firebase analytics

if you use firebase analytics when you

basically set up your firebase backend

you will get some free analytics in for

screen did the user go to which button

did they press and you can have a look

at these analytics when you then look at

your firebase console which we're gonna

i mean i know all of these are quiet um

maybe a high level if you're not if

you're not familiar with firebase you

may be like what the hell did we just do

and that is okay you don't have to know

all of this just know that we are these

four dependencies are stuff we need in

order to make our application function

all right so now that we've added these

dependencies you can actually go back to

your popspakiano file and kind of have a

at the dependencies that we added and

you can see all of them were added here

automatically for you with their latest

versions okay so previously in previous

versions of flutter we had to do this

manually but now you can just say

flutter pop ad and it will add the

dependencies for you directly to pop

great a lot of things we discussed here

it almost took 50 minutes to go through

all of these basics but i believe

actually basics should take more time to

explain than the more advanced stuff

the more advanced you get the less

explanation you need so that is why all

these basic things basically take time

i'm just going to take in my notes that

we've talked about all of these

and i think this is actually a wrap for

chapter number eight so chapter number

how to set up our project we've actually

set up our project now we've set up our

dependencies had a look around uh the

default flutter template and we also

that's great stuff in chapter number

nine we're gonna talk about my favorite

which is the ios app setup and in this

chapter actually we're gonna go through

a lot of things profiles certificates

we're gonna talk about app ids

a lot a lot a lot i can see here in the

list so i'm really excited actually for

go grab a cup of coffee or a cup of tea

and i'll see you in the next chapter

hello and welcome to chapter nine of

in this chapter we're going to talk

about the setup of our ios app and as i

mentioned it i think it was in um the

uh chapter in the absolute first

actually it's not a chapter it's just

introduction to this whole course

um we talked a little bit about what

we're planning to do with this

application that we're developing here

and um two of the things that we're

going to do is to actually release the

app in the app store and in the play

store now if you're not planning to

potentially skip over this chapter

but i still believe that if you're

planning on becoming a flutter developer

you need to know how these things work

being a flustered developer depending on

what kind of flutter developer that you

um with me assuming that you want to

become an actual flutter developer where

you can for instance work on different

applications and release them personally

or you can work in like a team con

concept uh and in the context of a team

work with other developers inside a

company for instance in order to work on

their applications and release them than

if you're if you fall into any of those

categories that you actually want to

release your application then i strongly

believe that you should know how to do

although you may be a part of a part of

a team of a huge organization where the

release process is its own like process

that you basically hand over your source

code to them and then they basically

build it and repair it and release it

but if you want to become like a

full-fledged flutter developer or a

mobile developer for that matter you'd

how to actually release your

so in this chapter we're going to talk

releasing your app or actually we're

going to talk about preparing your

is how do you set up your flutter

application so that you can actually

later and release it in the ios app

and if i bring up the next caption here

in order for you to be able to

build your application and then deploy

it in the app store you need an ios

and i talked about this previously um

how what a developer account is and that

you'd have to apply for it i think it

was in chapter one we talked about this

but if you've jumped over that chapter

you'd need to know that you have to

apply for a developer account at apple

and once granted that developer account

then you're going to be able to get

access to a portal portal called the

app store connect is your portal for

and uploading to the app store

downloading some debug information etc

which i'm not going to go into so much

detail right now and it also has a side

note as a developer you will get access

something called i think the developer

portal or something like that i think

i believe so i think we just call it

developer portal or developer developer

so you'll get access to that and you'll

be able to manage things such as

certificates and profiles okay so

which we're going to talk about soon

let's say that you have your developer

account and if you don't have your

developer account then please just go

and search online for register developer

account or just watch the first chapter

i have to look at my notes actually here

and see if that's what we talked about

actually yeah i can see here chapter one

was titled developer accounts and in

that chapter we talked about how to

register for an ios developer again in

chapter one if you haven't done that and

if you are planning to actually release

so now you know that you need the

developer account and it costs a little

bit of money i think it's about 99 so in

sweden it's about 990 swedish crowns

something like that or 1000 swedish

now that we've talked about the

developer account let's talk about the

certificates and profiles because this

is the thing that trips up a lot of

mobile developers when they come to ios

um i mean i've been doing ios

development since late 2000 2007

ios sdk as such it was like just a set

of tools and very little library support

because originally ios apps by steve

jobs definition were supposed to be web

apple just transitioned to disbelief

that yeah we actually have to have

native applications so they released

some tools and xcode was there so you

could build some simple applications

with ios opengl es what's there so you

can build some games as well

apple wanted to make sure that the

applications that are developed can only

be distributed through the app store so

if i give vandal for instance a

developer account he shouldn't be able

to create his own app store because they

i'm not going into the details of what

why they're doing that there's a whole

topic and what we could discuss like a

few days we could talk about that

whether it's a monopoly or not i don't

know so i'm not going to go into the

detail about that but what you need to

is there is an app store the um

basically just called app store but you

could call ios app store mac apps or

and apple has control over that so it's

who sits there and like controls the

measures that apps that are published on

the app store they're of a good quality

for instance okay so apple themselves

have a certificate now a certificate is

like a piece of paper uh just imagine a

piece of paper certificate that they

hold onto and they said okay whatever we

it comes from us okay so every app on

comes actually from apple i don't mean

that the apple has written the app i

mean that apple has signed the app using

their certified that piece of paper okay

and then when the app gets downloaded to

your iphone your iphone actually checks

is this a trusted application where does

ios as an operating system it can

contain and you can install many

different types of applications that

come from many different types of

the ios app store or you could actually

download application that comes directly

all these applications need to be signed

they need to be signed with a

certificate that is just to identify

where they come from so certificate is a

piece of paper that you as a developer

excuse me every application that you

develop will be signed using that

certificate okay so that certificate is

your identity as a developer and it gets

carried around in with your application

to the destination so if you develop

this notes application that we're doing

in this course and you sign it with your

certificate then your application is

going to have that certificate signature

inside it so when i send it to apple and

then apple is like aha that's this

developer who created this app okay

says okay your application's fine you

can't release it to the app store then

apple re-signs your application with

that is just to make sure that your

application after it's been signed with

apple certificate can be distributed

into the ios app store and downloaded by

millions of users around the world so

it's just sir just know that certificate

is your identity as a developer okay

now now that we talked about

certificates let's talk about profiles

because that also is a tripping point

um especially if they don't come from

like a native ios development background

you see a certificate identifies you

in short profiles identify your app

very short way of saying it so you as a

10 20 30 applications that you're

developing or you have developed

each of these applications will have

and that identity at the end is tied to

you as a developer so you say here's my

but when you then create an application

then that application also needs to

identify itself it will be like here i

am i am an application signed with this

profile using this certificate so

just know that a profile is kind of like

an identity for your application

and different flavors of that

and a certificate is an identity of you

as the person who developed that

and if you notice i just said different

and by that i mean that if you're not

coming from a development background

um if you're for instance coming from a

design background and you have a figma

file or visio file that you're designing

your wi-frames and whatever if you're

coming from a product owner ownership

background than your probably may have

working with jira or excel sheets or

whatever wherever you put your

requirements you may not be familiar

with different flavors of an application

worked a little bit close with an app

team then you'll know that there are

different flavors of every application

those flavors are usually i mean they're

one is a development flavor and the

other one is a production flavor a

development flavor is the application

you see if you sit with developers with

software engineers that are working on

on a daily basis they're coding they're

fixing things they're fixing bugs adding

new features and then they will provide

the product to you as a software uh as a

product owner for instance or a designer

and you will download that flavor on

your application and be like okay this

all of a sudden you press a button and

that button crashes the application so

the application just disappears oh

well at that point if the developers

were doing their job correctly then they

had had to put some crash analytics into

as soon as the application crashes or

something bad happens to the application

of that flavor of the application that

tablet or whatever and they will get

something called a crash report

a crash report is as its name indicates

it's just a report where the crash

information is completely visible and

they probably even know which button you

tapped at what time and what was the

that your app was carrying at the point

that it crashed so it helps them

now these flavors of the application

that you install on your phone on a

daily basis were working mobile

developers are usually called debug

applications and a debug application

it's just a way of saying that the

developers who created it it created the

application have the opportunity then to

fix any bugs that may arise with more

information than they would usually have

had they released this application to

that is a flavor it's a debug flavor or

is a development flavor okay and it just

means that it's a daily it's kind of

updating regularly application that only

very close circle of people close to the

project can download so that's a flavor

another flavor of an application that

gets released by developers could be the

flavor and the product production flavor

the same as the debug flavor but

some stuff maybe removed from it some

sensitive information that may be logged

otherwise maybe removed from it it's

just like a stripped-down version

for security purposes not stripped-down

version of like features or anything

they make it tighter they make it so

that it is a little bit more secure like

some extra stuff may be removed from it

extra stuff that otherwise developers

when it then gets packaged into this

yeah beautiful little package basically

then it will also be a new flavor called

so now you have two flavors one is like

for a close circle people sitting next

room or now that everyone's working

remotely maybe people are sitting at

home etc and that is like the product

team closely developers testers product

owners designers uxers everyone that is

they get the development builds usually

sending your application to apple for

or to google for review then you would

get the production flavor okay the

reason i'm talking about flavors is that

these different flavors on ios at least

assigned with their own specific

profiles so then you'd have a

development profile and you would have a

production profile and these prof

profiles dictate to your application

what it what it can and it can't do

for instance one of the capabilities of

a development profile in the ios world

is that your application can actually be

installed on a telephone hooked with a

without a cable and debugged remotely so

this is one of the cool things you can

do with ios in that you can actually

like if i'm a developer sitting here

get the designer's telephone and say oh

yeah you want the application like do

you want to actually see what i'm

working on yeah she or he would say

connect your their phone to your

computer and enable something called

and then you would disconnect it and

then give the phone back to them and

whenever they want the application

running live on their phone as you're

developing it you can actually run the

that is its own flavor and the profile

which is the development profile

dictates to that application that you

can be debugged but if you then want to

sign your application with a production

that profile dictates that this

application is not allowed to be

create your application and send it to

apple you need to make sure of two

certificate and profile wise you need to

the application is signed with your

production certificate and the

application is signed also with the

production profile which is hooked to

the production certificate so first the

certificate should be there using the

certificate you create the profile with

the profile you sign your application

and then you send this application to

apple apple then looks oh everything is

a production profile and the certificate

linked to the profile was also correct a

production certificate identifying you

information about profiles and

certificates for ios but i think they're

in i mean it's so important to

that you shouldn't really jump over

these concepts as if you're if you want

to become a mobile developer it's so

concepts now let's talk a little bit

the developer account and here i

actually have a link which i'm going to

and then i'm going to bring it to the

foreground so you can actually see

so here is the developer account as you

can see on apple's website and i'm gonna

bring my face a little bit to the right

bottom right so zoom into the window

and this is actually on developer

then you would go into accounts okay so

after you've registered an account

then you will be able to go in here and

sign in with your account and i'm going

there we go and then it says okay we

sent you a verification code and i have

apple watch here so i'm i'm just gonna

say i didn't get a code and text me the

in a short while i should be able to get

and it is important that you don't show

this verification code to other people

it's just you shouldn't do that so i'm

gonna remove the screen from where you

can see it and i'm gonna enter the code

that was sent to me it is six digits and

it is uh just basically digits and

bring the phone i bring the browser up

now and i say trust this browser okay

here you will see that um license

agreement has been updated okay so we

should be able to review that later so

space that this screen is taking at the

moment so you can see it in its entirety

and you can see that now that you you've

logged into this account you should be

overview membership people's

certificates ids and profiles okay

so and then what i talked about earlier

which is your app store connect okay

what happens here basically is

in the membership people's certificates

ids and profiles is where you will

manage your certificates and all your

profiles as i mentioned before

here it is very important that you

basically set up a good ground for your

uh certificates create the dev

the production survey and then you

create your profiles after that which

we're gonna talk actually about in this

here are the missing pieces for us in

so we need as i mentioned before

certificates profiles and app ids app id

is something that i didn't mention

before so i think it's just important

that i mention what an app id is

additional to the profile that you

create an app id is an identifier that

apple and you use in order to know which

if you for instance in the in the future

features such as push notifications

now if you're not familiar with what

push notifications are they're basically

remote notifications remote information

that you can send from a cloud somewhere

to a user's phone so when they get their

phone they will see oh here is a message

you can think of it as remote messages

just as if someone sent you an sms or an

or for instance if you're using whatsapp

or telegram someone writing a message in

a chat and then you're getting a

notification on your phone that is

called a push notification so

an app id is used mainly in order to

in order for you as a developer to be

able to specify different capabilities

of your application for instance that it

receive push notifications that it can

for instance store secure information on

so when i previously mentioned that you

need a certificate and profile in order

to sign your application you also need

an app id in order to identify your

application and its capabilities okay so

we're going to talk about that soon

what we need to do here before we

actually get started creating a

if you're if you're if you have a

developer account here and you are

planning on releasing your application i

kind of can basically assume that you

a macintosh so that you have registered

and that you want to be able to sign

your application with a certificate and

however you may be in a group of people

who doesn't have a macintosh and xcode

etc but you still want to be able to

release your application to the app

store so you may want to for instance

create your certificate profiles an app

id and then later send that information

to some sort of a cloud hosting service

for for them to sign your application

and then send it back to you something

like that i have never done that myself

but you may be in that group and uh

for the sake of being inclusive i think

it's important to talk about that

let's talk about what i've put up here

as the caption and that is like the

certificates in the keychain

certificate gets created by you as a

developer sending a request to apple

you basically creating a digital

then your request you will send it to

apple apple says oh you're asking for a

certificate okay here's the certificate

and then you download that certificate

and then when you double click on the

certificate it gets installed and hooked

to your original request okay so here's

the certificate and here's the private

the private key is just a piece of

information that your computer stores

digitally on only your computer so that

later the downloaded certificate can

actually be hooked to it creating a

your application when it gets signed

with your certificate that you then

it actually contains some information

about the certificate and the private

key and then you send the application

that was signed using these two pieces

there's a lot of information i know but

i think it's important for every mobile

release something for ios appstore to

private key and the certificate they

both get stored inside a program on your

computer called keychain if you have

and i can bring up keychain actually

now let me see which i have three

screens here so i don't know which one

i will bring up keychain here um

and i will show you how it looks like

here is an example of keychain and you

can see here there's a distribution

certificate and a development

and these certificates i didn't create

them i downloaded them but the things

under them this is the chain i was

talking about this is the key that i

so when you request a certificate from

apple you actually create this thing on

your computer and you upload this thing

certificate hooked to that kind of not

you don't actually upload exactly this

but something that is related to this

for us in order to be able to continue i

think it's important that i actually

existing certificates from my computer

so i'm just going to go like this and

delete two items all right and delete

okay so now they're gone now what we

here let me put up the captions so you

so that was the certificates and now we

we also need to talk about actually

deleting the profiles now this is an

interesting part if you already have

like profiles installed on your computer

you may not want to do this but i'm just

going to show you this step so that we

start with a clean slate okay so you're

not supposed to do this if you exactly

know what you're doing with your

certificates but if if this is the first

time you're doing this and there may

already be some certificates for you on

your computer for some reason then this

is the way to actually get rid of them

and i'm gonna bring it up here

and what we need to do is to go into a

i believe it's called library and then

and then something called provision

and you can see here um and i will show

you this path again so it's my user

library mobile device and then provision

so after i've gone into that folder i'm

going to delete these profiles that are

so you don't have to do this if you

don't want to and you know exactly what

you're doing but i'm just doing it to

show you that profiles are always stored

in that location for your user okay

and what you can also do which i really

like is to if you say add columns here

and kind of like drag it into your

favorites so you don't have to type that

path every time so let's just put it

here okay so that every time i want to

install the profile i can just click

here and put my profile there all right

now that we've done that the next step

as the caption shows here is to delete

our existing certificates and profiles

development account so let's go to

certificates ids and profiles here on

the left hand side and you'll see here i

have quite a lot of things stored right

here okay you see distribution

development development blah blah

so what we can do here is to go ahead

and delete these certificates on the

left hand side you see it's a

certificate so there are quite a few of

so what i'm going to do is just to tap

on this one and just say revoke revoke

tap on the next one and just revoke them

one by one so and again if you're new to

ios development and you've just gotten

your development account you don't even

have any certificates so this screen is

going to be empty for you so revoke

revoke so your screen is gonna look like

so now that we don't have certificates

i'm also going to go into profiles and

delete these profiles so if i just go in

here and kind of like say all my

profiles and then just delete this is

going to be fine as well so sort of

problem all right so now i've deleted

and that was the goal of this part of

development and production certs

then that is done with the profiles as

so what we need to do now is to create

something called a development

certificate and just to recap a

a certificate that will allow you as a

developer to run and test your

while you're developing it on real

so it's it's not necessary for releasing

the application but i personally after

many years of experience developing

mobile applications i've come to the

conclusion that i prefer actually

running my application testing my

applications are real devices as i

develop because you also have emulators

and you also have simulators that

simulate and emulate the capabilities of

android phones or tablets but i've come

to the conclusion that it's actually for

application real phones or tablets

so in order to be able to do that and if

you have for instance an iphone

um and you want to test your flag

application on that iphone then the

first thing you need to do is to create

a development certificate so you need to

identify yourself as a developer to

apple so let's go to the certificate

section and then just say create a

certificate and then choose apple

development actually sorry ios app

yeah so it says apple that's very

interesting so you can basically use

something called apple development but

we're not going to do that we're just

going to say ios app development at the

let's do that just choose ios app

development and just press continue and

here it says create a new certificate

and create a new certificate is it's

waiting for you to tell it that you're

asking for a development certificate and

you need to choose a file now this is

the magic part you need to now go back

keychain so let me see if i can bring up

just go to keychain access menu

a certificate assistant and then say

request a certificate from a certificate

so i'm gonna press that and i'm gonna

and the common name i'm just gonna leave

and then i'm just going to say save to

then i'm gonna say continue and it says

okay i'm gonna write a file on your

desktop or wherever you want with that

request so save it somewhere that you

know where it is actually saved so i'm

gonna save that and then say done all

that certificate request in itself

didn't create a certificate it's just a

certificate request but what it did is

that it created a private key

and you can actually go to your keys

here and you'll see that there was a

if i say kind private key so one of

these keys is the one that was just

i don't exactly know which one because

it doesn't have a date but it's just one

of these so every request for creating a

it creates with itself a private key

okay so keep that in mind let's go back

now that that file has been saved on

your desktop just say choose file and

and pick that certificate request okay

and it's you see here certificate

and then it says okay it expires in a

year and you need to keep that in mind

because development certificates do

always expire in a year and you need to

by basically renew them okay

so but for now you don't have to worry

about that because we're not going to

take a year to develop this application

so let's just say download and it got

downloaded to my downloads folder so

i'm gonna bring up my downloads folder

the file that got downloaded you see

it's a cert file all right now this

certification in itself it doesn't

contain your private key remember the

private key is in the keychain so what

you need to do is just you need to

double click on this all right so

double clicking on it you see it will

then create a certificate in your

keychain under my certificates and login

keychain that is linked with your

private key you see so this is what you

downloaded from apple this is what you

created on your computer by requesting a

certificate and when you double click on

the downloaded certificate these two get

so that's it that that is what you have

to do to create a development

certificate and the key related to it

now let's go to the production

certificate and we need to kind of do

in order to create our production

certificate so let's go back to all

certificates and i'm just going to say

i'm gonna say ios distribution app store

and ad hoc okay so choose that option

and sorry i'm just gonna not also in my

notes here that we talked about the dev

so let's go ahead and press continue

here and you'll have to do the exact

same process as you did for the

development certificate and create a new

let's do the same thing just basically

kind of copy and paste the same process

certificate assistant request a

certificate from a certificate authority

and just be careful a little bit with

this because i've understood from what

i've what i've seen is that depending on

what you've chosen here this menu

it could be that you kind of need to

make sure in your keychain that you're

so just make sure that nothing is

selected and then go to um sorry then go

certificate assistant and request a

certificate for certificate authority

company's or your developer accounts

email there i'm just gonna pick solid a

and then save to disk and then say

and then save it to desktop and since

there is a file already there with the

same name from the previous step it's

going to say are you sure you want to

and it got saved then i'm going to go

here and then choose the same exact file

actually is a new file which got

and you'll see now there is a download

i'm going to download that and if i go

here i'll bring it up so you can see as

i'm going to bring it here you will see

that there is a new file called ios

distribution that is your production

certificate okay so double click on that

keychain it's open again and you'll see

now you have two certificates here

iphone distribution and then iphone

these are your certificates and keep

hold of them kind of like try to save

them and if even if you don't save them

it's okay because they're now placed

here so you can always export them okay

but it's also good practice just to keep

now we've created a developer and a dis

and a production or distribution

let's talk about the next step and that

is required for us to be able to release

let's go back here and to identifiers

and in here is where you create your

application identifiers and you can see

that they're actually tied to a specific

organization and identifier which we

in which chapter was it that we talked

about i think it was actually in chapter

yes if you have if you don't know what

an identifier is please go back to

chapter number eight where i discussed

and say that you want to create a new

app id okay press continue and then you

will choose app here not an app clip

and then you will be presented with this

explain to you what all this is so

in here the description um we're just

gonna print some information here that

describes our application and to be

honest with you i don't remember what we

actually called our application when we

in the previous i can see it was called

so i'm just going to say my notes

flutter application sample or flutter

here the bundle identifier is very

important that you actually specify it

correctly as we created it in our

in chapter 8. so i'm going to bring up

the my notes application here i'm going

to increase the font size so you can see

um if you remember where we created the

with this command you see we said

se.pixelity and then my notes meaning

that the application identifier from

se.pixelity.mynotes okay with a dot in

between all right so if i search for

that in our project let's say

you will see there are some results here

you see so depending on how you created

your floater application depending on

what organization you specified this

identifier may be different for you but

since my identifier in this case is s

epixody my notes i'm just gonna copy

and i'm going to bring it here make sure

explicit is selected and just paste that

bundle id in there okay so yeah it's

now if you remember what i said before

an app identifier is not just the

identifier the bundle id itself but it's

also like a list of capabilities that

your application can have now if you for

instance want to have push notifications

you will also need to enable that in

here now push notification is not not

something that we're going to do in this

course so you don't have to do that but

all you need to do here after you've

entered your app id prefix sorry your

app bundle an identifier and a

description just press continue

and you can see that says okay are you

sure everything's fine yeah explicit

yeah great and then i say register

now that identifier got created all

you don't really have to do anything

with that identifier right now it's just

that you have now registered that

identifier so no one else can basically

tick these items in my notes so that we

know we've talked about it all right

uh your application so that it can

actually be installed and debugged or

you can't see my entire setup but here i

have an iphone 12 pro which is just

right here it's a little bit dirty

screen but that doesn't matter it's just

is connected as you can see with a cable

to my computer and it is available for

my computer to see so i'm just going to

unlock this phone right now with my

you can see that it is available here

it has a special identifier and if you

want to get your device identifier which

is what we need to do here as you can

see in order to debug on a real device

we need a uid to register for our

when you i mean this is a kind of like a

big thing to talk about because it takes

a lot of time but what i'm going to say

here is that when you created that

development pro and development

certificate the next step is for you to

basically register your device with

apple so that apple knows on which

devices you actually want to test your

and those devices they're stored in here

and there are ways to get your device

identifier such as going to finder as i

just showed here and just tapping on

device now i'm kind of going to do it

off screen so you don't see the entirety

let me see if there's any way for you to

actually get your device identifier yes

and it is i can actually see here

so what i'm going to do is i'm going to

actually bring finder up here so you see

what happens i just tap on my phone now

you need to register your device on

identifier under this devices tab before

you create your profile okay

i'm not going to do that because my

phone is already registered but you need

to do this on your own and the way to do

that is to connect your phone or your

tablet which you want to test your

flutter application on to your computer

go into finder and tap on your phone and

then just click on this section now i'm

not going to do that here and the reason

behind that is that every device

says identifier really identifies that

device so you could go and register my

and it's just not a good idea to show

your device identifier to others so i'm

not i'm not going to be able to do that

unfortunately in this course but

the steps you have to take is to click

on this label and it will show you a

copy that uuid and go into devices

section of the certificate identifiers

and profile section of apple developer

account and add that uuid with a name to

okay so i'm just gonna assume you've

done that and if you need some time to

go ahead and do that please pause this

the key is just to get the identifier

from here okay there's a way also get

your identifier your device identifier

from xcode um and that works exactly the

same you just have to open xcode then go

to um i believe go into menu and then

pick devices and from there you pick

your device and you'll see it's

so that was a lot of talk let's say that

so what we need to do now is to go and

create a development profile all right

so i'm just going to tick these items in

so this is the exciting part now we're

going to go to the profile section and

create a new development profile so

click on generate a profile and i'm

going to say ios app development and

then it says okay choose an app id you

see now your profile is going to be

do this drop down here and you can see

i'm just going to say my notes and this

and for you this id maybe a little bit

different the description maybe a little

different but just choose the

app id that you created in the previous

steps so i'm going to choose that i'm

now it's going to say okay which

certificate is this profile connected to

do you remember i said that a profile is

linked to a certificate this is what

granted that you've created your

development certificate in as i talked

about in this chapter just select your

certificate so and then say continue

which devices do you want this um

profile which which device do you want

your application which is signed with

this profile certainly to be able to run

on now these all these devices come from

the devices section i've registered many

even some of my co-workers devices

which allow us to basically debug an

application on their devices as well so

see those devices in this list

right so i'm just going to say select

all just make sure my application can be

run on all those devices that i've

then say continue and then you will give

it a name so i'm going to give it a name

i'm just going to say generate

and you will get some information about

when it expires etc also expires in a

so and then you'll have to say download

and we're going to do the exact same

thing now for a distribution profile a

distribution profile is the kind of like

the same dev profile but you cannot

debug your application with it all you

can pretty much do with it is to sign

your application with that profile and

send it to apple so that you can deploy

your application in the app store okay

so press plus profile and in this and

this time go to distribution and say app

store you see distribution subsection

then go here and then choose your

so that was the development profile

sorry now we have to go to production so

i'm going to bring the window a little

bit up so that you can see it in its

then i'm gonna choose my notes

and then i'm just gonna press the

i'm gonna take it in my notes so we've

talked about the dev profile okay

so now that you've done that uh

choose your assertive again you see it

says okay now you're creating a

certificate a profile for a distribution

then it should be hooked with some sort

of distribution certificate and since

ios distribution certificate is the only

one that we created if you remember i

deleted all my other certificates

so that's the only one left here just

pick that and press continue

now give it a name i'm going to say my

and then i'm just gonna say generate it

okay there you go and you can download

now that you've done that you need to

downloads folder where your profiles got

now you see these are the two profiles i

got downloaded except with their

extension of mobile provision provision

you need to install these somehow on

your computer so that you can sign your

applications or your ios application

so what you need to do now is to copy

these two files i'm going to copy them

and then bring them into your provision

profiles folder i'm just going to

cut and paste them there okay so they're

not in the downloads folder anymore so

there are other ways of installing these

profiles some people rather drag it into

xcode some people double click on them

and those are all fine but there's a

little bit of a problem by doing those

methods compared with the method i

showed you here if you double click

mac os knows how how to install them but

mac os just messes up their naming so

they will be installed on their very

random names so if you come back to your

provisioning profiles folder they may be

under some sort of a cryptic name that

you don't recognize anymore so in this

basically keep their original name which

is very descriptive of what they

okay that was that so now we've created

a um dev profile and a prod profile

exciting stuff so what we need to do now

is actually work we can say that we're

done with this screen here so i'm going

and what i'm going to do here then is to

what we need to talk about now is to set

in xcode so that xcode understands that

our application needs to be signed with

the correct profiles and certificates so

what i need you to do is to go to the

ios folder in your flutter project and

just right click on it and say reveal in

after you do reveal in finder double

click on the workspace in order to open

flutter xcode workspace in xcode

and what you'll need to do now is to

make sure that your signing of your ios

application is done correctly so choose

this icon on top left in your um i think

it's project explorer or something

choose your targets and then go to

signing and capabilities and just remove

for this course we're not going to use

here in my notes that i've talked about

the next step is for us to be able to

tell xcode that for debug purposes in

order for us to be able to run our

on a real phone and debug that

application which profile and which

certificate it needs to use

so what i'm going to do here is to go

into this section here as you can see

debug on under signing and capabilities

and then i can see that actually it is

it's already using the automatic signing

for debug and i'm going to remove that

so what you need what you need to do

here is actually pick the right profile

and it says my notes dev and my notes

profile sorry prod and you can see it

that is because we don't have a

development team yet and alex and i'll

explain that soon but for now just go to

your provisioning profile and say for

debug purposes we're gonna use the

and then go to your release and then say

i'm gonna use my notes prod okay and

here's a little error here you see it

says producing profile my notes pro

doesn't include signing certificate

apple development blah blah blah okay

that's that's fine don't worry about

what we need to do now is to actually

tell it um so i'm going to actually pick

profound search setup release profile

so what you need to do here is to

go to your build settings and make sure

here is actually selected you see

pixelity is for me and then for you it

um now what i'm gonna do i mean

sometimes uh and i can see signing

certificate here is actually not really

selected sometimes it can be that xcode

kind of goes crazy when we play with

certificates and signings so i'm going

i'm going to do the same thing here go

finder open up in another window here so

i'm going to open up the workspace again

okay i can see we're still getting the

problem provisioning profile minus that

doesn't include signing certificate

apple development and let's open up our

keychain again and have a look a little

and i can see unfortunately there is a

profile you can see previously we had

two profiles and it is very unfortunate

so in here you can see this this

certificate was created by us you see

they're very tightly close to each other

these two we created but this is

something that xcode has created and

that is because xcode tries to do

automatic signing as you saw it was

saying automatically manage signing so

by doing that it created a certificate

for me on my behalf which i don't want

so the error that we're seeing here is

xcode is now saying that this this

profile that you have here is not linked

which xcode created itself no one asked

it to do that i didn't ask xcode to do

that so when you're working with is a

woman just know that xco tries to do a

so what i'm going to do here is i'm

development certificate because i didn't

i believe actually that's the right one

yeah so i'm going to say delete delete

and now you can see that error went away

simply because xcode was like ooh now i

understand which one you're talking

and then the provision profile of the

what i'm gonna do is as you can see here

i've opened the project here and then i

have my actual iphone selected here to

be able to make sure that your

application can actually run on this

phone now after all of this hard work is

just to press the play button here

so i want to do that and i want to let

it do its thing and if everything works

um it's going to basically then um allow

us to run the application all right

now and this is a dialogue that you're

what's happening here is that it's

trying to sign the application and all

development profile and since that

linked to a development certificate in

the keychain and that keychain is

password protected you see the login

keychain it says i can't access that

certificate give me the password for the

login keychain so i'm going to type that

and then i'm going to say always allow

so let's do it let it do its thing

and this may depending on the machine

that you're running this uh process on

i can see it's saying now building so um

okay then i got an actual failure here

it says cloud firestore wasn't found

and this is very interesting um

actually i mean i didn't plan for this

to happen but it did happen i'm kind of

when you add new dependencies to your

projects such as these big dependencies

but they're not really linked to your

project yet so the way to fix that is

let xcode be here okay i'm gonna close

i'm gonna bring a terminal uh what i'm

going to say here is flutter

so this is basically going to clean up

how the ios project was set up and all

those dependencies all right now i'm

going to close actually xcode as well

then what i'm going to say is to say

and flutter pop get what it does is that

it sets up all our dependencies from the

beginning and just to make sure i'm

folder and i'm going to say

could not be compatible version okay pod

uh let's see if we can do an update repo

i'm just gonna do that uh without like

explaining it right now so much and see

if that fixes our problem i'm going to

bring up a new safari window and say

pod install update repo let's see what

the command was but because i've

repo update it's called okay pot install

repo update let's see if this fixes our

and if cisco could not find compatible

version for podcloud firestore from blah

specs satisfying from dependencies were

found but they require higher minimum

deployment target and that's very

you see the deployment target that we

have for our application um what it

when we created the project with flutter

what it does internally is says

this flutter application should be run

on these ios versions and these android

versions and what we're seeing here

what we're seeing here is that we are

using cloud firestore and cloud

firestore as a dependency is expecting

our application to have a minimum

deployment version it means that cloud

firestore cannot be used in applications

that for instance are trying to run on

ios 7 for instance okay so what we need

to do here in your um flutter project

just say command p in visual studio code

and open up a file called um

here we have some stuff set up let's go

in here and just say platform ios and

what we're going to do is just to say

just just now i mean 13 it's really good

because right now is ios 15 is available

so you could just say you're supporting

15 14 and 13. so i'm going to do that

and then i'm going to run pod install

and this time i can see that things are

going a lot better and it's installing

all our dependencies without a problem

um what you need to know now what i did

here was something that you probably

would need to do if you're comfortable

with ios development so you need to fix

but before i explain what i actually did

you need to know about something called

and i explained this in the previous

chapters about when we started in

chapter 8 when we talked about

can in can create ios applications ios

applications dependencies are

basically using uh cocoa pods

so cocoapods is a dependency management

you need to in order to be able to do

the trick that i just did you need to

install cocoapods and there is a good

website for that i mean you can i'll

bring up my and i say install cocoapods

and then i go here and you just say

cocoapods and then there is a command

that you need to issue in your computer

in order to install cocoapods okay

so um after you've installed cocoapods

then you can go into your ios project

ask it to reinstall your dependencies so

the key here though was for me to

uncomment this platform line in the pod

file where my dependencies are managed

now i'm supporting ios 13 at the minimum

all right and then i manually ask the io

the project to be recreated the ios

project to be recreated using pod

after you've done that your dependencies

are generated and then i'm going to

and i'm going to say oh i can say open

in xcode that's interesting will that

work i don't dare to be honest with you

revealing finder and then i'm going to

do that and open a project so

i'm going to go now do command

do i do command b maybe not let's just

i'm gonna then bring up xcode and press

run again and let's see if it can then

those dependencies that it couldn't find

and it may take some time as you can see

because there's lots of dependencies we

and all i think there were firebase off

we had firebase core we had cloud

firestore and also firebase analytics so

themselves can bring with them a lot of

as i mentioned in the previous chapter

in chapter eight bringing dependencies

butterflies and balloons in the sky it

is actually a serious process you need

to consider what's bringing in a

dependency means to you and your team

in this case we've only brought

dependencies that were officially done

by google and google is behind flutter

you can basically trust anything that

has to do with firebase at least so

if it's released by the google team that

um so we're gonna let it do its thing

i'm gonna just tap here and i can see

it's building quite a lot of files

if everything goes according to

the result is going to be that

application run on this phone

it would be very exciting actually to

and as i mentioned depending on the

computer that you're using this process

so if you have a powerful computer it

may take less time and if you have a

little bit less powerful computer it may

um now that we're waiting i should also

probably mention that this process of

once the build has been done once it

kind of like its artifacts will be

so that you don't have to rebuild the

entire project from the beginning okay

i'm gonna let it do its thing

and uh while we're waiting actually we

could talk a little bit about quicktime

which is a caption i brought here

if you're like me and you like to like

debug your applications on real phones

then you may want to see or show that

on your computer so for instance if

you're sharing your computer as a screen

with a co-worker and he or she wants to

also see your application running on

your phone you will need to use

something called a quicktime network

so we're going to talk about that now

but before we do that let me just show

that here is now our flutter application

now that we've done that all of this is

done you don't need xcode anymore so i'm

just going to press stop here and what

i'm going to do i'm actually going to

run our application from visual studio

code or flutter application on that

iphone all right so command shift b or

control shift b depending on which

platform you're using and say select

i'm going to choose my iphone 12 pro

then i'm going to go to run and say run

you don't have any extensions oh not

this file open up your main darp file

and then say run run without debugging

and you'll see it says launching

so this is going to actually consult

xcode and say that hey xcode here's the

flutter application run it on this

and to be honest with you i actually

didn't like this that it's using

it what may have happened is that when

we did flutter clea clean you may have

profiles to be honest with you

and this is not a good sign it could be

that when i did flutter clean it

actually messed up the profile

so i'm going to open up xcode again and

bring up our application again and let's

and i can see debug no it's fine it's

you don't have to worry about this

message that was printed to the screen

by uh by flutter so i don't think this

something that we need to worry about

so now that you've set that up then you

could actually run your application

visual studio code or android studio

depending on which environment you're

flutter applications or debugging your

okay now let's say that that is done um

then what you need to do if you want to

screen on your computer then you can

bring up something called quicktime

player on your macintosh and then go to

file and then say movie recording now

this is probably going to hijack my

no it didn't hijack anything then i'm

iphone 12 pro and see if it can mirror

is it not able to do that is it because

i'm recording my screen or something i'm

wait for this debug process to continue

let us do its thing first i think i'm

probably trying to do too many things at

i proxy i don't really know what i proxy

connecting to the vm service taking

longer than except expected and that

could be because my macintosh is

actually blocking something that flopper

needs so i'm going to go to privacy here

which is security and privacy and just

so that may help flutter then get its

yeah that could be it because maybe my

macintosh just blocked that eye proxy so

i'm gonna stop this process and i'm just

going to say run run without debugging

again let's see if it can do its work

launching and this time since it's

actually built the application

previously it shouldn't take long this

time before it can run the app

so it has already built the app once so

it shouldn't really take as long this

i can now see it says installing and

so let's see if we can get that to work

xcode build done in eight seconds

and to be honest with you this is taking

longer than i expected it shouldn't take

this long to run the application and i

can see nothing was blocked this time

mac os cannot verify the developer of

iproxy and i'm just going to say open

i think there is something wrong with

the latest versions of mac os and how it

flutter is using internally but

everything went fine at the end i could

actually launch the application from

visual studio code and now it's running

now i'm gonna stop this so now the app

as soon as i say stop the app is going

to stop working there what i'm going to

and see if we can get quicktime to

this iphone i'm going to unplug it

the phone and then plug it again

if it understands that it has to mirror

i can see my quicktime is also giving me

i mean this is live uh recording of this

session so you can see all the problems

a developer will have to fix and this is

so let's go to um and see if we can

and to be honest with you i mean i'm

actually doing this on a separate screen

so you don't have to see my face so much

but i can see that my macintosh for some

reason is not recognizing this telephone

so i cannot record it basically on this

but if you're doing this at home it's

probably gonna work for you so uh

connect your phone with a cable to your

computer and then go to quicktime player

and then with quicktime player say new

movie recording and from movie recording

just from the drop down choose your

phone and you'll be able to mirror your

now that that is done i mean we actually

got to a lot of hurdles that i hadn't

planned for we saw the iproxy thing

installation which is the dependency of

our project because there was no minimum

version set up for our flutter project

we fixed that we saw a problem with the

automatically because xcode had created

the certificate automatically we fixed

for instance now go and filter these out

from the video and kind of like when i

actually output the final course for you

then everything will just work perfectly

you don't have to see any of that

but i don't want to do that to be honest

with you because i think it's so

you will get as you develop your

thoughts or applications it is important

i don't want to polish this um i don't

want to polish this uh course so much

that you think everything is perfect

from the absolute beginning and if

you're and if you're making mistakes

then something is wrong with the way

you're developing things but these

things happen you need to understand why

they happen then you need to learn how

i think then we're good to go uh for ios

everything we needed to explain

uh everything worked except for the

quicktime thing and i think that is

um i'm actually i have a lot of software

open here i am playing stop playing in

stuff recording stuff so it may be

because of that is a little bit confused

and who knows maybe my computer needs to

so with that said let's prepare

ourselves for the next chapter and that

to do the exact same thing with it for

ios hopefully with less explanation now

that we've gone through the basics for

uh grab a cup of tea cup coffee whatever

you want and i'll see you in the next

hello and welcome to chapter 10 of this

in this chapter we're going to look at

or any android device that you may have

at hand in order for us to be able to

run our flutter code on it and now in

chapter nine we looked at how we can run

and basically run our flash application

on an ios device and we set up the

provisioning profiles we set up the

i mean there is a lot of work to do and

you know that chapter took about an hour

the android side things are a lot easier

i thought in this chapter we're gonna

have an android phone for instance in my

case here i have a oneplus pro 7 pro

that is connected with a usb cable to my

computer so there's nothing special

about it it's just an android phone and

i prefer to actually as i mentioned in

the previous chapter in chapter 9 that

i prefer personally when i'm developing

developing floss applications to run my

applications on a real phone or a real

um you may not know this if you're

coming from like a design background or

a background that's not really related

to mobile development in previously but

if you're developing applications for

only ios then you have something called

um an io simulator is a program that

runs on your macintosh that comes with

xcode and the ios sdk that allows you to

simulate how ios internally works and it

allows you to install your applications

from xcode directly or from from flutter

directly into the simulator and simulate

basically how your application will be

perceived by your actual users

if you're developing applications for

android then there is something called

an android emulator now an emulator is

quite different from a simulator in that

an emulator as its name indicates it

actually tries to emulate everything

about the operating system and the

device so for instance an android

emulator for an old device for instance

that you may get a hold of a device

than an android emulator for a very

but had you done the same thing for an

ios simulator and simulated an ios

at today's like at your computer's uh

speed because it is simulating ios it's

not actually emulating it the way it

when it comes to android you have this

possibility to run your application on

an emulator which is a lot closer to the

actual device that your user will be

so it is not the exact perfect copy in

most cases so it's not gonna be like

working exactly as a real physical phone

but it's a lot closer to the actual

physical device that an ios simulator is

given that background i still prefer to

run my flutter applications on a real

if you're interested in that if you're

if you have an android phone and you

want to for instance deploy your flutter

application on an android phone and test

it while you're programming it then this

now i also have to say that um

you don't have to do this but for the

entire entirety of this course i'm

as we're developing the application the

notes application i'm personally going

so as we basically do hot reloads and

then we write some code and we want to

test it i'm not going to show any

emulator i'm not going to show any

simulator i'm actually going to show my

now i'm not going to show it with just

i'm not going to install the application

here and just show you like this because

this is not going to work it's not a

good way of showing things to uh to

someone watching this course so what

task in this uh chapter we are going to

install an application on our um

many thousand stars and it is

not like a dependency it's not something

that you're going to build into your

flutter application but it's actually

utility you're going to install on your

your computer will will then be able to

phone or your android tablet on your

and this scr cpy is absolutely beautiful

it's one of my absolute favorite

utilities to have when doing mobile

and the reason behind that is that

solution that i showed in the previous

chapter which is quicktime quicktime

player where you mirror your ios

telephone on your computer but you

cannot interact with that mirrored image

you still have to bring up your

telephone and interact with the

telephone and see the interactions

either on the phone itself or on your

screen unlike that scrcpy allows you to

actually interact with your phone or

your tablet or your android phone or

from your computer screen so you can

actually take your mouse and then go to

that screen and tap on a button and it

will actually tap on that button on your

it is magical it's beautiful it's open

source and free so if you have an

android tablet or an android phone and

you're following along with this course

i highly recommend that we install

scrcpy together actually as we're going

i'm just going to take in my notes here

installing scrcpy we need to

i believe it actually stands for android

debugger or something let's see what

a safari window here as you can see adb

stands for android debug bridge and adb

is a great tool if you want to for

instance be able to talk with your

android telephone all from the command

line so you can send it a message and

hey do this or click here or yet

close this application whatever so you

basically send commands to your android

telephone or tablet through your

terminal it's um it's fantastic

adb i mean having adb install your

computer then you can actually install

which uses adb in order to talk to your

telephone and send commands to it and

receive images from it etc so

with that said we need to install adb so

i'm going to close this turn window here

and i'm going to bring up terminal

i'm going to increase the size of this

terminal window so you see what i'm

so in here then i'm going to say

cask android platform tools okay

so this will then allow you to

using android platform tools then um you

will be able to grab adb from that so

installation actually includes adb all

um i can see that i mean for me you can

see that i've already installed android

platform tools so i get this message

here saying that well you've already

but if you have not installed android

platform tools before you will running

this command will actually install it

for you now i don't want to reinstall it

so i'm just not going to do this

suggested command here but just know

that before you install scr cpy you will

need to get adb up and running okay

and that comes in android platform tools

let's let me just go into my notes and

say that we've talked about adb so after

you've done adb we need to go and i'm

going to bring up safari again

let's see if i can bring up the window

here so you can see what i'm doing as

well then i'm going to say scr cpy

okay and then you will see that the

first suggested website is on github and

this is exactly where you need to go

so go to scrcpy here and you will see

information about how you can actually

install scrcpy and it says on linux you

can do apt installer crcpy on windows

and on mac os then you can do brew

i've already done that so i've already

actually installed scrcpy so i don't

have to do anything special

and um you can see it actually tells you

here i'm going to increase the size of

this window so you can see a little bit

and it will tell you here that you need

adb accessible from your path if you

don't have it yet then do that command

that i mentioned to you okay

after you've done the installation on

your computer then you should be able to

bring up a terminal so i'm going to

as you can see here i have my android

telephone and it the screen looks like

this right now so it's just on the home

if this is the first time you're doing

this process you will probably need to

enable something called usb debugging on

what your android phone looks like or

the usb debugging when you plug your

android telephone it will kind of show

so i'm going to enlarge this a little

so this dialog will pop up on your

android telephone saying that oh do you

want to allow this computer to do

debugging on this um on this telephone

and what you need to do is just to say

always allow from this computer and then

press the ok button this is only so that

you will be first of all able to install

all from visual studio code or from

android studio right on your android

and also it will allow you to run scrcpy

in order in order to communicate with

so what we need to do is actually bring

in terminal i'm just going to say ser

and as you can see here it's going to

talk to my android telephone and it

brought up a window which i'm going to

slowly bring here to this screen so you

i'm going to leave the terminal here

because the terminal is actually fueling

this thing so if i close my terminal

this is also going to be closed so just

keep this terminal open or if you're

using item for instance like i'm using

then you can bring up a new tab and

command line otherwise you can just

close it or you can just minimize this

if you're if you're bothered by it so

as you can see now i have my android

mirrored on my screen i'm actually going

to do this so you can see it a little

bit better i'm going to bring it right

here in between so this is my actual

android phone so if i click here with my

mouse it actually interacts with my

i can bring up my phone here

so you kind of see them side by side

if on the scrcpy screen here i press the

you will see that my android screen

so it's really interacting with my

i highly suggest that you actually

install sdrcpy to be honest with you

it's a great great tool if you're into

mobile development or if you want to

and regarding what i said earlier about

you will get really really far with the

ios simulator and the android emulator

i personally should suggest that you

and invest some money into getting

devices for for yourself they don't have

one android telephone and one ios

or even tablets will do but preferably

telephones you don't even have to have

sim cards in them just just the

telephone device physically itself so

i mean if you're getting into mobile

development you will kind of after many

years kind of have a lot of telephones

anyways because you will get like this

year's new telephone and then two years

later you get another telephone so you

and you could use those all telephones

then as test telephones as we call them

that's that part now what we need to do

next is to now that our android phone is

what we need to do is to go to visual

studio code into our project

so choose our let me see bring up visual

studio code here if i can visual studio

this is i have so many screens here so

it's a little bit of a challenge to

line them up all here so what i'll do

here is i will get rid of the side

window all right and i will bring up

then scr cpy on the right hand side and

then just resize the screen a little bit

and then like this so i have you this is

like my usual setup so i have visual

studio code here on the left and then i

have my android phone mirrored on the

so what then you'll need to do after

you've done all of this work is in

visual studio code just say command

shift p on mac or ctrl shift b on linux

windows and if you're using android

studio i don't to honestly know the

commands there to select a device in

flutter they may be like a drop down or

so here i'm just going to say command

shift b and i'm going to say flutter

and in select device i'm actually going

android telephone which is the one being

choose an android phone and then i'm

going to say run run without debugging

that you can see here it says launching

dart on gm 19 blah blah in debug mode so

since it's an android application now

all of a sudden we just switch from ios

to android previously our application

was being like our source code was being

and now since we're trying to deploy to

an android telephone it's the gradle

it's gradle basically that's taking care

of the build process so if you're an

android developer then you know that

basically gradle zero build system and

it is basically doing the build in the

so i'm actually so glad that we got this

error right now so i'm gonna take here

in my notes that we've talked about in

vs code select android and then show

android phone mirroring working okay

you see here we got some errors

actually when we talked about in chapter

what chapter are we on we're on chapter

10. in chapter 9 when we talked about

running our application on ios we

actually got something similar

there was an error saying that oh your

dependencies firebase they need this

version but you're on that version and

and the code that actually solved it if

you remember we went to our pod file i

just put this platform here saying ios

13 because you see we have four

dependencies at the moment we have

firebase auth we have firebase core

analytics and something else which i

don't remember let me have a look at the

there were core auth cloud firestore and

these four dependencies they have their

own requirements so they say that we as

dependencies cannot be installed on an

application that for instance supports a

very old android os or a very old ios

version so these dependencies are

putting requirements on your project so

and we fixed that yes uh in the in

chapter nine we fixed that um by going

commenting out this basically removing

the comment from this line and changing

to 13. so we fix it like that for ios

but how do we do it for android now we

get a lot of great information here and

it says that you kind of need to find

this debug default config and min sdk

version okay so let's look for default

config so i'm going to copy that text

and i'm going to then command shift f in

visual studio code and search for it and

as you can see here we have a little um

flutter version name and then flutter

information about flutter versions like

if you go to our build gradle

there is a flutter version code to

and the where's the main sdk here min

sdk version okay so i'm going to search

and here i can see it is 19 here it is

19. and android min sdk version

19 so there's actually quite a lot of

and the error itself let's read it

requires a higher android sdk version

fix this by adding the following to the

file build gradle android default config

if we look at the default config here

it's talking about this thing min sdk

version i can see that previously this

used to be a number and recently it has

been changed to flutter min sdk version

so i'm going to bring up a safari window

and i'm going to say change flutter min

sdk version so let's see what people are

actually suggesting is there a good

command that allows us to do this

you see people are still saying that we

need to do it like that by changing it

to a specific version but i believe

there should be a better way of doing

this instead of hard-coding it um

with the new flutter project with the

flutter style you're unable to change

the mini sdk version and local

great okay so if we go to a file called

local.properties that's what they're

try to find local properties and i can

but there is no min sdk version

we probably need to just go and fix that

up so i'm going to copy paste and i'm

just going to say flutter.sdk version

19. okay save that file then i'm going

to go back to the main dart and then say

run without debugging let's see what

local properties change that we just

and it's still saying that it won't be

uh what we could do in here to be honest

with you is just troubleshooting so

let's just say go back to the root

folder of your application and say

why is it doing the xcode workspace

so if this works properly then it should

have cleaned the android code for us and

like put the version 19 in our build

gradle like this should actually resolve

to 19 so let's go to main dart and just

give it one more try if this if this

solution doesn't work then we

unfortunately have to go into our

build gradle file and and do what was

recommended and put the min sdk version

there as a constant value of 19 just to

let's have a look here at um

what our gradle build is gonna do

i don't really know what happened with

i it doesn't seem to really be doing

anything so one more try run without

debugging and see what happens launching

i'm gonna have a look at my android

phone here as well running gradle task

and for me it's not running anything at

the moment on this on this phone so what

we're gonna do is let's go to

i mean this solution didn't work so

i'm gonna remove that and i'm gonna go

to build gradle and put the

target sdk version i think that was the

and here we're just gonna say 19 instead

like that like it was actually suggested

um let's then go to main dart and then

say run without debugging one more time

and if this solution doesn't work i may

actually have to like restart the visual

studio code if it's kind of confused for

because usually when you say

gradle like when you start the build

process it actually gives you some

feedback it either says that something

it then ran successfully and in this

case i can see it's not running so i'm

just gonna say quit visual studio code

and then i'm gonna bring up visual

studio code so i have a lot of projects

minimize all of these things and i'm

to our my notes application and let's

give this a try one more time i'm going

to go to run without debugging and let's

oh now it's choosing iphone 13 pro in

debug mode so that's because i restarted

visual studio code and it doesn't know

which device to run on so i'm going to

say select device and then choose my

and hopefully crossing my fingers here

version number then it's going to work

i see so now it's com complaining about

multi-decks so i mean this is great

stuff i'm so glad that we're seeing all

these errors because usually we don't

have the possible i mean usually you see

in tutorials that yeah everything's

working fine uh he clicked there and

clicked there and everything worked but

here we're actually getting to the point

where you see every issue that could

arise and then we're gonna fix it

together and this is like a day in the

life of a software developer things go

wrong but then you'll have to fix it so

um this multi-dex is something that

configure and we're going to say

i'm going to go to safari and i'm going

um and then there is a solution

hopefully somewhere in our default

config you see it says multi-dex enabled

build gradle in app which is right here

you see android app build gradle in your

default config as it says here

multi-decks enabled just bring it here

and then go to your dependencies at the

bottom of this file right here and bring

implementation multi-decks right there

okay so i'm just going to paste it right

there go back to my main guard file here

and then say run run without debugging

and there are some warnings here that

are printed in red you don't have to

worry about them so much right now

there are warnings as their name

suggests so um you don't have to worry

so much to be honest with you as i

so there we go here is um our flutter

application now working and running on

i'm gonna bring then the phone here

and you can see it is showing the exact

same thing so if i with my mouse go over

you can't see that because you're

um and then you will see the value 3

here as well so that's that's great

oh it's because my phone is actually

rotated so i'm gonna rotate it back so

it's not rotated in the wrong

orientation great so we got a lot of

problems to be honest with you there um

but that's okay that's usually what

happens when we're working with mobile

development at least in the beginning

when you're doing the setup so i'm

grateful that we're getting these errors

so you see them so you don't just think

everything is going to work from the

introduction i haven't planned all of

this that these errors come up i don't

want things to be perfect so even though

that is happening but i'm still quite

grateful that they are happening so

what we need to talk about now is

something called screen sleeping and um

as you're developing your uh application

on your android telephone or tablet

you'll notice that you will run your

application on the phone or the tablet

after a short while your screen will go

to sleep which means the screen will be

and then when you try to then rerun or

rerun your application or re refresh

your application then you will get an

error from flutter saying that it cannot

deploy the application because the

that is quite annoying that the

telephone does it but it is for a good

reason the telephones like for security

purposes they have to lock the screen so

that if you leave it somewhere on a

bench or something in a park and you

just forget it and you go away then it

is locked so no one's going to get

data with that said what we need to do

is disable it while you're developing

what you want is a telephone that's

always there is available the screen

doesn't lock so you can always deploy a

newer version of our application to it

you don't lock it yourself manually

so what we're going to do is i'm going

to bring up the phone here so you see

what i'm doing i'm going to go here

i'm going to go to the settings

you will probably need to i mean in

order for you to actually even be able

to run your application and do funky

things with your application on your

telephone you need to enable something

called developer remote so developer

mode on android and on ios is a series

of development tools that the phone

provides only to developers and in order

to get those tools you need to perform a

series of actions like a monkey or

something on your telephone and

um i'm not going to provide instructions

exactly how to do that for all different

phones because depending on the

manufacturer of your telephone

especially if it's on android then

into life in a different way so what you

need to do is to find out the

manufacturer of your telephone and the

model of your telephone here is a

oneplus pro 7 i believe and then google

and say oneplus pro 7 developer options

then you'll get some information about

how to enable that i've already done

that so if i go to i believe it's

utilities or sorry i think it's system

you can see there then i have an option

so in order to disable screen sleeping

you have to go to developer option and

and that is by default disabled all

we've now then talked about um

developer tools and we've talked about

that you can interact with your

telephone uh using scrcpy so

to be honest with you i think i think

that's all you need to know for

um for the android setup there is not

much more to talk about the rest is just

developing our application as usual and

then running it on the android phone and

then mirroring the screen using a crcpy

so that's what i'm going to do for the

entirety of this course i'm going to

primarily run the application run our

application that we're going to develop

in this course on this telephone and

mirror the screen using scr cpy

but you may choose to use an ios

simulator or an android emulator or an

ios phone or a tablet whatever

descriptions about how to do all of

those things because that is a complete

course of its own but at least now you

have the tools and the necessary

information in order to understand how

you can actually deploy to an iphone and

with that said now we can say that we're

actually good to go on android

um and in the next chapter which is

chapter 11 we're going to get to some

juicy stuff which is uh setting up our

project on firebase and if you remember

from the introduction we're going to use

you know what's coming in the next

chapter and uh now you have the tools

necessary in order to get the app

running so with that said then let's go

configure our firebase project in

hello everyone and welcome to chapter 11

in this chapter we're going to talk

about our back end setup which is with

um and i'm as i as i've said it before i

kind of assume that you've gone through

course chronologically so you started

from the absolute beginning introduction

you're following along so there's lots

and lots of lots of information as you

can see it's about eight hours of

information before this chapter

so i feel like since i've explained

everything so thoroughly in all those

chapters i'm not going to go through all

so i will jump over stuff that i've

already explained so i if you haven't

really suggest that you at least skim

over them a little bit so you see

um now i'm looking at my notes and i can

that in this chapter as the caption

shows here we're gonna set up our back

end our backend is using firebase and

while developing this course i

a like as a part of this course have a

custom backend as well that we do with

django i personally do django

development uh for back-end and websites

like rest apis and also for

but to be honest with you if i then go

and create a simple back-end with django

and then show you how to integrate with

it really has nothing to do with flutter

like the backend part has nothing to do

issue in the beginning of this course i

was faced with a challenge of do i go

into the rabbit hole of creating custom

and walk you through also creating a

custom package which has nothing to do

with flutter and flutter is the reason

you were watching this course so i

was faced with that challenge of whether

i should do that or just use uh firebase

and i choose and i chose firebase simply

because it is a product by google it is

kind of like serverless so it is a

server without you actually having to

so i picked firebase for its simplicity

so that we can get the backend working

up and running without so much work and

i hope that you understand that that is

the reason that we're not doing a custom

back-end but firebase is a very reliable

back-end created by google and it has

all google's financial backing for

developments and for support so you

don't have to worry if you're picking

firebase and if you're thinking oh is it

going to continue being supported

the quick answer is yes it is going to

be supported it is so big everyone's

using it and it's too big even to fail i

would say right now at least for

uh upcoming uh next few years i would

future for 10 20 years in the future but

for now you don't have to worry about

so that's what we are going to do in

this chapter i'm just going to take it

now previously when uh flutter came out

like in year 2020 or even the beginning

firebase you have to do a lot of custom

in the recent versions of flutter

a command that you can issue from your

terminal it is called flutter fire cli

is amazing because like the work that

you have to previously do manually a lot

of custom work dragging files and p

lists and jsons configurations app ids

undertaking that a lot of developers

would make a lot of mistakes during that

process and it was just not good so

there is now a command that you can

issue from from your terminal which

allows you to do all that custom work

but it does it for you so you don't have

as i provided here there is a link i'm

if i can somewhere let's see if i can

wrong screen i'll bring that screen here

enlarge that screen and also enlarge the

so you can see it says fluffifier

and it says get to know firebase for

we recommend starting with the get to

know firebase for flutter code lab and

video okay so there's a video here if

and uh and it says okay if you're

migrating your existing project then

look at the migration guide migrating if

you're not familiar with that term uh if

you're not coming from a software

engineer background migrating economy so

you have an existing thing and you want

and put in new stuff in it so you kind

of migrate your information from the old

but in this case we don't have to worry

about that because we're we've created a

brand new project so there's no existing

firebase installation in our application

that we have to worry about okay

there's a lot of information here you

can see it says using the cli etc etc

and that is actually what we're going to

we are going to have a look at how we

can install the flutter fire cli

and you can see here it says you should

execute the dart pop global activate

and then you issue flutter fire

flussifier config so let's start by

copying this code from here copy it and

i'm going to bring up my terminal

and i'm going to increase the size of my

terminal so you actually see what is

happening here okay so i'm gonna paste

that command in and i'm gonna let it do

i've already done this installation

before so for me it may actually go a

little bit smoother or a little bit

faster but for you it may take a little

bit longer depending on whether you've

already installed flat of rsli before or

so now that that is installed the next

thing you will have to do is you will

actually need to make sure i mean it's

not provided in the documentation but

it's something that i'm providing for

you because i know that i've personally

this flutter fire cli it will give you

this command as you can see here flutter

fire okay and if i in my terminal say

you can see that flutter fire is

installed in this folder so it's under

my personal folder on my computer

slash dot pop cache slash bin and then

right there so unfortunately when you

install lots of fire cli it doesn't

it doesn't tell your terminal where it

is installed so if you then immediately

after that say flutter fire and then

blah blah blah as it is mentioned here

classifier configure your terminal will

most probably say that what is flutter

it's not provided here in the

documentation but i'm telling you here

as you can see in the caption that you

need to tell your terminal where flutter

fire is actually installed okay

then what you'll need to do is uh to do

as i've mentioned here you can see i've

said that you need to change your path

and include your home folder slash pop

cache slash bin so if i go to my

terminal configuration if i say um

you can see at the top here somewhere i

should have there you see it says export

path and i say okay my new path is the

old path plus using this uh double

this folder as i've mentioned here in

the captions at the bottom of the screen

so you will need to do this as well so

i'm going to quit vim now and then after

you've done that make sure that you

configuration so in my case i would have

zsh rc and that will read the paths

fresh otherwise you could also take the

close your terminal completely

terminated and then start it again which

in turn reads the configuration and

if you don't want to source that's what

now we've talked about that now let's

actually talk about what the firebase

make sure i tick all of these items that

right now let me just mark them as done

so what you need to do now is what we

need to do now is to talk about firebase

as you can see here is a cli to help us

interact with firebase right from our

this this used to be done manually

previously in that you would have to go

to firebase and like create a whole

separate project and then integrate that

project into your flosser application so

you don't have to do any of that anymore

um what you need to do now is as the

next step is to install the firebase cli

which does all of that work for you

so i've provided here as you can see

there is a command here that you can

and then you can go to a firebase google

com docs cli install cli mac blah blah

so i'm actually going to go to that

in my web browser here so you can see

and you will see there's a lot of

information provided here i'm going to

bring up the uh i'm going to make the

size a little bit bigger i'm going to

bring my face maybe to the bottom right

as well so you can see more information

and you can see for mac or linux then

yeah let's go here mag you can install

the firebase cli for macro linux using

so standalone binary blah blah so you

documentation on on how you can install

the firebase cli on your on your

computer whether you're using mac or

whether you're using linux or windows so

after you've done that after you've

cli you will actually need to

in your into your account using that

let's let's do that let me actually in

here um let's bring up our project uh in

visual studio code so i'm gonna bring it

and bring up the right caption as well

so you see what we're talking about

we're going to talk about firebase login

and log out you see when you

want to integrate your flutter

application with firebase you need to

firebase project on something called the

so this project is pretty much the

configuration of your firebase backend

on firebase's console on their website

so you need to configure a backend so

what we need to do here is now before we

can actually configure it back in

in your terminal you need to tell

firebase what user you have because i

personally have many google accounts and

any one of those google accounts can

potentially have many flutter sorry many

because firebase projects are linked to

now in order for our firebase cli to

understand where it needs to create the

project you need to tell it to log in

with an account all right so

the way to do that is to bring up

terminal and as you can see here is my

and i'm going to clean this a little bit

i'm going to bring up the font as well

so it's quite ginormous and that's okay

so what you need to do now is to tell it

so i'm going to say firebase

it's gonna do its work and it's telling

me i'm already logged in with this

account if you haven't logged in with an

account then you're gonna get a prompt

telling you uh okay which email and

password do you wanna log in with so

um it may be actually worth it to be

honest with you for me to log out right

now so that you see the entire process

i'm a bit hesitant to log out because

uh i actually have protected my google

account with a security key

i don't have the key right here and i

for the sake of for the sake of actually

going through this process together with

you so you see how it works i'm gonna

so i'm saying firebase logout

and it says there is a new version of a

firebase tool so let's copy this here

and i'm gonna see if we can install

global so let's copy that here global

if it can do its work then before we can

and npm is something called a node

package manager and it is kind of like

if you're working with node.js if you're

developing for instance node

which you which you don't have to know

about it's just a way it's like a

tool kit for creating applications uh

remove the existing file and try again

so it's it's like a dependency

node applications and firebase tools is

a node application so that's all you

need to know really i mean there's there

are courses available about node and

node.js then you can actually have a

look at how they work etc so i'm not

going to go into details about that so

before i could i mean i could have

actually done a firebase logout without

all of this but i just want to show you

that things aren't planned like i can't

perfectly plan things here and when i

tried to log out it said oh there's a

new version of node available blah blah

now that i think sorry there's a new

version of firebase tools available that

you can use that you can install with

i did that so let's now say uh firebase

okay so the logit actually was

so let's now say firebase login

and it says allow firebase to collect

information i'm gonna say as a developer

you may you may be tended to say no like

here but if you are a developer you can

put your shoe you can put yourself in

the shoes of another developer working

at google working for firebase and they

are trying to get some information about

how you use the cli and whether they can

learn from your usage of the cli in

order to make the cli better so i

usually say yes to these things

especially if there's a developer asking

for permission so but you can say no to

this if you want to so i'm just going to

and you can see here then there's a

screen provided here asking me to log in

with one of my google accounts all right

i'm going to pick my company's google

account because that's what i usually

use all right so i'm going to choose

that and it says firebase cli wants to

access your google account and it says

okay what permissions it's going to use

you can have a look at this information

if it concerns you so if you if you're

concerned about any of these things

i'm just going to say allow

and once that is done you will see that

it says firebase cli login successful

and then you can pretty much just close

and now it says logged in as pixelityav

gmail.com so i can say firebase login

again and that would be the prompt that

you saw in the beginning of this video

that you are logged in alright

that was a lot of information now now

that you are logged in with the firebase

cli you actually need to configure a

firebase project all right and we do

that with the flutter fire cli which we

installed in the beginning of this

chapter using this command dart pop

so what you need to do now is to

command as i've shown here down at on

the left hand side so i'm going to do

so it will fetch all the projects that

google account and it says okay these

are the projects available flash chat

fluffer note guessing chords random

project testing or you can create a new

now i'm going to choose create a new

it says okay enter a project id for your

new firebase project so what i'm going

to do here is i'm just going to type my

is the name of our flutter project as

well so my notes now i'm going to say

okay i'm going to create the same

project called my notes okay i'm going

i says yeah i'm going to create it

i mean you can see that we immediately

this project already exists and you can

command blah blah blah yeah fail to

create a project because there's already

with id mynotes please try again with a

this is basically telling us that hey

someone else has created my notes and it

wasn't one of the projects that we had

created because if you if you have a

if you open uh your web browser and say

and uh let me make sure that i'm logged

in with my pixelity account yes

if i have a look let's see dismiss let's

get started firebase helps you watch

yeah we are logged in with that account

so i can actually see maybe i don't have

any projects set up here which is a

we actually saw that there were some

projects set up under this account so i

don't understand why the firebase

console so it's not showing them

firebase console backed by google

yeah there they are okay so it is on

and i can see that my notes application

is not an application that i own i

what it is saying is that globally

firebase projects have an identifier and

now i've entered an identifier that is

what i'm going to do then is i'm going

to issue the same command uh

firebase flutter fire configure and this

time i'm going to give it a little bit

more information about the project name

so that makes it a little bit more

unique so i'm going to choose

and then in here in the name of the

project i'm going to say mynotes

maybe someone has already taken this as

so it's doing its thing it's doing its

magic basically so let's have a look

this is okay that is taking some time it

is doing a lot of work it's setting up

like the ios project and android project

this thing used to take a lot of time to

do by hand like maybe 10 folds the

cli is taking so i'm not so bothered by

the fact that it's taking some time so

and here it will actually tell you okay

which platforms do you want to select

and as i said like flutter allows you to

create web applications android

applications ios applications and also

desktop applications or four platforms

and then here it says okay which ones do

for our project right now you can just

say android and ios you don't have to

mac os or linux or windows and web but

you have the ability to do that if you

want to so choose android and ios for

and now this is this is the amazing part

that you had to do manually before you

and register like your application with

apple and then go and register bundle

identifier and then put the bundle

identifier manually in firebase and then

download some files put those files in

your ios and android project now

now you don't have to do that anymore

here it just tells you which bundle

identifier are you using for your

project and if you remember from before

when we created our flutter project from

the beginning we said flutter create and

then an organization which for me was s

e dot pixolity do you remember that

i mean if i bring up terminal maybe i

can even go back to it flutter create do

you remember this command i will zoom

into it a little bit so you can see

better this is how we actually created

our project we said flutter create.org

as he pixeled in my notes so the bundle

identifier for this application will be

however since sc pixelity is the reverse

domain for me this won't this won't be

go back to how you created that

identifier for a project using your

organization name and you now you have

to paste that in here so you will see

and it's going to configure your ios

set up everything necessary for your

project to work so i mean you may you

may just think oh well this was this was

so little and what did it actually do

but for me who's been working with

firebase and flutter for a very long

this is all magical because it did a lot

of work it configured your application

on the firebase console it actually

registered an android and an ios project

hooked into this firebase project

downloaded the configuration files place

them in the exact correct place in your

so it did a lot of work but you don't

really have to know about that so

um now if you want to kind of see the

result of it if you see here the output

of this says that there is an identifier

associated with your ios app and then

there's an identifier associated with

so that's what we're going to do now

let's now make sure that these

identifiers are correct and that the

bundle identifier that we provided to

the cli is also placed in the

configuration file correctly so

copy this for instance ios identifier

that was created for you so copy it

and then search for it in your entire

project and then you'll find a little

file here and let me bring it down

so this is where ios is configured and

let me bring this like that so you don't

and this is where the android project is

configured you can see the um

app id is right here and the api key is

right there so don't worry about this i

mean you should not show your api key

and app id to anybody um so but since

i'm developing this course for you i

have to show it i can't just go and

censor it but don't worry about it by

the time you're seeing this um video by

the time you're seeing this course i've

already deleted this project from

firebase so there's not going to be any

so that project isn't going to exist

even if you know the api key on app id

so don't worry about that but if you are

developing your own application just

kind of be careful who you share your

api key and app id with all right

that was a lot of information a lot a

and i'm gonna actually tick here

that we've talked about that

and yeah that's that's all working as it

so i'm also gonna go here in the

captions and i can see that i have some

information here about enabling

multi-decks and multi-dex was something

that we've already enabled in the

previous chapter which was chapter 10

now everything should be working as it

did before to be honest with you so if

you in your visual studio code or

android studio if you're developing

under your flutter app with android

go and select your device to run on now

in the previous chapter you saw that for

the entirety of this chat in this course

i'm gonna use an android phone to

develop uh our application so you may

choose to use an io simulator an android

emulator or an android phone or tablet

or ios phone or tablet so but i'm gonna

use a real android phone and as you saw

we have the ability to bring up scr cpy

to mirror the android screen so i'm

going to bring it right here

change the size of visual studio codes

window a little bit so you can see the

android um telephone right there as well

just to make sure that the project runs

after all of this work that we've done

so that we haven't broken anything

sorry run it without debugging and this

is this is why you will see this is the

result of all the work that we've done

it sounds funny to say it because we did

a lot of work with the firebase project

but there is nothing that you can see on

the screen and that's that's the reality

of doing software development you may be

putting a lot of work sometimes in doing

something and this result isn't

immediately visible all right

so but what you have done in this

chapter was that you actually set up

your back end with just a few commands

you installed two clis the flutter fire

cli and the firebase cli you logged in

with firebase cli and then you set up

your backend with the flutter fire cli

now just to make sure everything is set

up properly also you can bring up your

web browser i'm gonna bring it up here

and i'm gonna say console.firebase

our notes app here you can see my node

and you can click on it and you can see

how it is set up for you you can see

there is an android app setup and an ios

you didn't have to really do anything

now there's lots of things you can do

with firebase which we're going to

actually play with throughout this

course but not right now just make sure

firebase project is created for you by

logging into console.firebase.google.com

all right and we've talked about this

now running the application on an

that was already set up so we don't have

now that you've seen that you've set up

your backend you're ready to go and uh

so i can say congratulations so that's

the android setup is already done so i

can see that that is set up we don't

have to talk about that either

what we do need to talk about is what

in the next chapter we are for the first

time in this course we are going to talk

the uh footer code actual thoughts or

code we're going to start writing a

simple registration screen so using this

right now hypothetical users are going

look at the screen and say okay i don't

have an account with this application

i'm going to register myself so

be able to they will be able to enter

their email address a password of their

uh choosing press some sort of a button

and we will then talk with firebase and

say here's a new user register that

person okay so that's all for the next

chapter which is chapter 12. so grab a

cup of coffee cup of tea whatever you

and i'll see you in the next chapter

hello and welcome to chapter number 12

in this chapter and which i'm very

excited about we're going to talk about

a basic register screen well up until

this point we've been really configuring

our i mean if we go chronologically

we've had the introduction we've gone

through so many chapters to talk about

dart and its basics and even some more

advanced topics such as generics

and then as soon as we did that then we

started learning about setting up our

iphone and android application also

sorry the iphone and android application

together with certificates profiles and

got scr cpy working so there's been a

lot of information up on those till this

point so many hours of information that

and i strongly suggest that you actually

do that because i've explained

extent extensive detail that i feel like

explaining all those things again and

again will be a waste of time both for

we are going to use all that information

that we've learned from the previous

chapters and start actually creating a

registration screen a simple

registration screen in our floater

application source code that talks with

firebase and firebase we set up in the

previous chapter if i'm not mistaken so

have a look at that chapter if you

haven't set up your firebase app

or at least i mean we haven't really set

well yeah actually set up yeah we could

say set up um but we haven't really

configured in such great details it's

just like we've set it up so

have a look at that chapter please if

before you continue with this chapter so

i'm gonna go to my captions here and

just ensure that i can show you the

now what we need to do in this chapter

is to start working on our registration

screen and what i'm going to do here is

bring up a caption for you so that you

know what we're going to do

the first thing you need to do is to

on the screen so i'm i'm going to do

that and then i'm going to bring my

android phone mirrored on the screen

and then i'll see if i can bring my face

to the right so you can see a little bit

and what we need to do here now is to go

in this main dart file and remove

everything that is a comment now

if you're coming from like a design

background or a product owner or um like

wherever whatever background that is not

software development related if you're

coming from those backgrounds then you

may not know what a comment is however

i'll tell you now a comment is a piece

of information piece of text that is

written inside a source file such as

this main dart file that doesn't

translate to an actual code so it's

usually for other developers or whoever

is looking at the code so that they

understand the code a little bit better

comments in dart can be created in

different ways however the most

i mean the most usual way of doing it is

double forward slashes as you can see

here and a space and then some text all

i'm going to need you now to go into

your main dart file and we're going to

remove all these comments right now

because they are basically creating a

lot of noise for us right now okay

so let's go ahead and remove all those

gray lines or whatever color they're

displayed on your screen they may be

i have tokyo knight as i mentioned

in visual studio code so comments are

gonna remove all that comment there okay

and i don't know yeah and it seems also

so yeah i think now we've removed all

the comments so if i do command s that

and i'm actually going to talk about

what the hot reload is but if you've

done this then you're good to go i'm

going to take that in my notes so we've

now the next topic to talk about here is

hot reload versus hot restart now

these two are so important for you to

understand that i think you should like

get this before you continue with the

rest of the course and i'm gonna do my

best to explain what hot reload and

if you're for instance coming from a

design background where you have for

stuff you're you're putting some vectors

on the screen you're dragging images and

i can go in your figma design and

literally observe you as you're doing

that so i'm actually looking at your

changes you don't have to press any

publish button nothing like that even if

you're in your drafts i can still follow

you and watch you as you're designing

now that future is very very much

the cost of doing that the same thing

that figma does is quite heavy because

as i'm changing my code i actually i'm

not going to be able to see my changes

unless i tell flutter that okay i've

made some changes show me them on the

that is hot reload okay for instance if

i go in here and i say flutter demo home

page and remove the demo home page from

press command s that's going to save my

file which in turn is going to do a hot

you can see this title now was changed

so it's set it says not flutter demo i'm

going to change it back command s hot

reload and it's going to say home page

now you can also avoid for instance

doing command s and just go in here in

your visual studio code or android

studio and just say hot reload so i can

see now that didn't actually do it that

was great because i can see a little

like blob here you see the circle on

this file this in visual studio code is

an indicator of a file that has not been

so if i save it and it itself is going

to do a hot reload so i don't have to

actually manually press the hot reload

button so save and then you can see the

changes immediately applied there

however some changes to your code are

going to be so big that footwear is not

able to resolve the delta from the

previous state of the application to the

new states and we will come to those

changes very difficult to explain them

right now but just know that hot reload

usually works in 99 something percent

like i'm making up statistics here in

most cases hot reload works in that it

can show you your latest changes however

sometimes your changes may be so drastic

calculation of the delta from the

previous previous state to the next to

the new state may be so big that flutter

isn't able to do that so then you will

have to do hot reload and then hot

here sorry hot restart you will have to

do a hot restart sorry about that

so there's more differences between them

like internally about the state

like the state of your application and

keeps your state and the other one loses

your state so i'm not going to talk

about that right now because we haven't

even talked about states in flutter so i

don't think it makes so much sense to

talk about that right now just know that

in most cases hot reload displays your

latest changes and that and it's

sufficient if you just do a command s

but hot restart it will basically kind

of like rebuild your application

so i think i think to be honest with you

have a look a little bit about at

restructuring the code that is created

um i mean we don't really know how these

um you don't even know like in the

caption i say material app inside run

what does this mean well you don't know

i'm not going to like confuse us right

now with too much detail but what you'll

need to know right now is that

let's go in here and i'm gonna bring the

what i'm gonna do in here in this build

and command s and then you'll see that

printed to the screen so every time i'm

this entire application is being built

again and there is a little bit of like

as you can see here material application

kind of like a scaffolding entire frame

of your application including the bar on

top including this white view here and

including that badge up there on the top

it's like you are pretty much building

things that you don't need to build

every time you save this file so it's a

little bit of like a a problem of um

performance whether you want to do that

or not but in this in this uh course i'm

just i'm gonna give you some advice on

how to make your application also run a

little bit faster so to do that what we

need to do is just to tell flutter that

hey look we don't want to build the

or the app structure every time we're

pressing command s to how to hot reload

challenge here now is to if i get rid of

what we need to do now is you can see

in the main function which is the root

function that flutter calls when it

actually runs your application it says

okay i'm running an app called my app

and if you look at my app the only thing

it does it actually creates a material

what you need to do now is to grab this

material app so i'm just going to say

or control x i think on windows and

grab that and instead of this const my

and then kill your my app boom like that

and just to make sure everything is

working correctly i'm just going to do a

and you can see everything is working as

it should so what we did here really was

actually let's see my homepage yeah

what we have now is just the main

function and something called my

homepage stateful widget all right so

get your code also to this state

i'm gonna take in my notes that i've

so the next thing we need to talk about

is stateless versus stateful

i mean for me it feels like for me to be

able to explain this i need to first

explain what a state is uh let's say in

and then i go and i say oh i want to

change the title of this little label

yeah let's convert this to double quotes

because we're putting a single code in

i'm gonna say you've pushed the button

this many times and i'm gonna say

command s or control s in windows and

hot reload yeah command s okay

and you can see is that you've pushed

the button this many times but it kept

so if it rebuilt this application or

or this thing that you can see on the

screen how did it keep keep the state

hot reload is able to sometimes as i

mentioned before keep your state and

state is just data data usually

mutated and created either by the

application or the user or both and in

this case this is a state that the user

is controlling so by pressing the button

he or she is increasing this number now

a state full widget it can keep that

it's an integer and it keeps hold of

and upon this number being changed it

can kind of redraw itself so

something that is on the screen usually

something that you can visibly see

such as this screen the white screen you

upon who's changing it can redraw itself

had we had the same widget as you can

see in my home page and it was stateless

widget which is available as well

it wouldn't necessarily be able to

redraw itself or contain any mutable

data i mean even stateless widgets

for those who are a bit more familiar

with flutter you'll have like value not

notifier and builders so even stateless

widgets can be redrawn depending on what

mutable variables so that is kind of

difference between stateful and

stateless so you can see here this is a

variable that is not read-only otherwise

it would be final so if i make this

final you can see it says oh you can't

reassign this value to something else so

just know that if you see state full

widget then it is a widget that contains

as the user interacts with the widget or

as time goes by or as the widget sees

fit however stateless widget is a widget

who has who doesn't contain any mutable

pieces of information and doesn't manage

any mutable pieces of information

that's a lot of just just there's a lot

of talk i know if you're not comfortable

with like if you if you haven't done

software development before you may not

this may not make any sense to you and i

promise you as we go on and of course

you're gonna learn more about it so

don't worry about it if you didn't get

you can see now let's see um

let's talk a little bit about i'm gonna

okay so i can see in my notes that i had

that as part of as part of uh

what i was going to explain here i was

i had planned i can see my notes i had

planned in one of the previous captions

as part of this caption i was actually

supposed to come completely kill this my

and i was supposed to actually create a

widget just called home page so let's do

that let's just go back into that

caption so kill this my home page

go in here and change this to home page

so what we need to do now is to create a

very simple home page okay so i'm gonna

remove this title from here as well and

you can see now we have an error telling

us that okay i don't know what home page

is now what we need to do is to create a

uh actually let me see if i plan to

create a stateless yeah stateless widget

a great shortcut that you need to know

in visual studio code and i think it may

be available in android studio as well

is if you want to create a stateless

and you can see it tells you that okay

you want to create a stateless widget

okay there it is then you give it the

name of home page okay so now you have a

home page great and i'm going to do a

command s and now you can see this is

one of the times that flutter was like

i don't understand what you're trying to

do you change some stuff in this main

function and i can't do hot reload so

you have to do hot restart so now the

screen is kind of gonna be black

now we have what i had planned in the

course initially for for this chapter so

great let's go now to the next point

so you can see the screen is black here

and that's because of this container

there is a little container there or

something on the screen that you can't

really see because it's just black so

you could go in here and say there is a

color and you can say colors red i just

and you can see now the screen is red so

just know that there is something on the

screen but you just can't see it because

the way to get your application to a

point that is actually like presentable

to a user you usually have to create

something called a scaffold now scaffold

as it as its name indicates it's kind of

just like the basic building structures

of an application that kind of makes it

presentable to a user to an average user

even though if you're creating like a

graphically intensive application this

black background may be completely okay

but in most applications when you run

then you'll get like a bar on top that

tells you like the name of the screen

that you're on kind of like the title of

a web page and you'll also get some like

a status bar on top where as you can see

here the status bar is kind of like

black with all white icons on top and it

will give you like a wide screen where

you can interact with your content

so we don't have that and in order to

create that you have to create something

go to your container here and say

now i'm gonna press command s and you'll

see all this on then we get this little

white screen here and then there's a

little tint on our status bar as well so

it makes it a little bit more

what we need to do now i'll basically

see if i've planned to add some bar

title in here which i haven't so let's

do that right now so for our scaffold

we're also going to add an is something

so go to your scaffold and say app bar

and then say i create a new instance of

and in here there's a property called

title and as the title say text

and for the text i'm going to get rid of

all this documentation there's excessive

amount of documentation here which kind

for instance and make it a constant

so you see after you've done that

your screen has a beautiful blue bar

here with the title of your uh

application or the title of your home

and there is a white canvas here for the

rest of your content to be displayed so

now there are a few things in here which

i could jump over but i kind of feel

like they're so important to explain

that i'm going to do that right now so

in flutter every time you have for

instance here there is a text you see

sorry there is an app bar an app bar if

you go into the source code of an app

bar let's go a little bit higher you can

see it it says i'm a stateful widget all

right so app bar in itself is a widget

so what we're doing here is saying we

have something called a scaffold let's

go to scaffold it itself is a stateful

widget so we're saying the main widget

we're returning from our build function

as you can see it should return a widget

is a scaffold which is a stateful widget

in itself it has a property called app

bar an app bar it itself is a stateful

widget which in turn has a property

if you look at the documentation it says

let me also make the screen a little bit

like this so you see it better

now the title is a widget and we're

saying oh we're going to use a text

widget if you look at text what it is is

a stateless widget it means internally

it states or its state can change and it

it doesn't have any mutable variables

okay oh i didn't want to change that

if you see what we're doing here when in

flutter you're just creating widgets

everywhere in flutter almost everything

is a widget either stateful or stateless

and you try to you need to kind of try

to stick to stateless widgets as much as

you can all right we're going to talk

more about stateful and stateless so

now that we've added the scaffold and

i've explained a little bit about these

widgets that were we've created and

we've done a command as here just to

hot reload the application or this

uh what we need to do next is to create

let's go and create some sort of a login

and you can see here i've written the

caption button on home page in the

or more accurately it could actually be

so i'm going to change that i'm going to

and button on the homepage in the center

display the caption to you there

to and i'm gonna change my notes here

now your task is to create a button on

the screen how do you do that well

in scaffold you see the scaffold at the

moment it's the owner of that bar on top

white content here so what you need to

do is to go and look at a property

in itself if i move my mouse over it

says okay give me a widget you see

and of course i could say well i have no

widgets null is also acceptable but in

this case we're going to create a button

called text button so text button is a

widget if you go into source code you'll

text button button style button and that

is a state full widget all right so

you're basically saying that i'm

creating a button and i want to allow

the user to do something with it all

right so we need to do as you can see

there is a little bit of an error here

to say that says unpressed is a

parameter that you haven't provided to

me so we need to tell this button

when this button is pressed it needs to

do something and this is a requirement

for the text button class that it's

telling you well i'm a button

what do you want me to do when i'm

pressed if you don't press if you don't

provide unpressed parameter to me i

don't i'm not even a button i could just

be a label and that is what this error

is all about is saying that if you're

creating a button make sure that you

what happens when the user presses on so

and i'm just going to get visual studio

to complete this code for me you can see

it says okay an empty function

a function with empty list of parameters

the code in itself is empty at the

moment okay so go after the create

creation of that function and then you

see that there is another that you have

you see text button you would say you

would probably just assume that oh a

text button should have some sort of a

string parameter that says what is my

if we write child here the beauty of

child is a widget so text button doesn't

doesn't make any assumptions about what

content you want to display on that

what it does it says i need to display

some widget anything it could be an

image it could be an icon it could be

whatever it could be a list of things

which is not a good idea to do but you

go and create a child widget and now

you've learned about the text widget so

i'm just gonna say a constant text

widget and in here we're just going to

and you'll see now all of a sudden you

have a register button there

so another cool feature now i want to

show you in visual studio and i think

it's available also in android stu is

that you can go and wrap your widgets

with other widgets so instead of for

instance saying that i want the text

button to be in the center and then you

you know it also exists you could do

command dot or command dot on mac or

control dot in windows and linux and

visual studio code on the widget that

you want to wrap in some other widget

you will get this beautiful menu that

says you you know you can wrap it with

many different things so i'm just going

to pronounce a wrap with center so as

you can see center is a widget that has

a child property all center does is that

horizontally and vertically it's child

inside the available space of the center

the entire available space in this case

as you can see is this entire white

background so center has access to that

entire white background right now

because center is the root widget of our

body which is the only thing that our

scaffold is showing at the moment

center then is able to center align this

text button so let's command s and you

can see the register button is centered

horizontally and vertically in the

now that i've talked about that i'm

and what we're going to do here is very

we now need to handle when the text

that we're going register a user with

we talked about this when i talked about

like uh dart in the previous chapters we

asynchronous and i'm not gonna go into

registration i'm sorry i'm not going to

talk about that in details because we've

talked about that in details before so

if you need to know about that i think

synchronous and asynchronous were

probably explained in um i'll have a

they were explained in chapter number

seven so if you haven't watched chapter

number seven i strongly suggest that you

do that if you don't know what sync and

what we need to do now is to tell

registering a user with firebase is an

asynchronous task so it's not going to

complete immediately so what we need to

do now is to tell flutter that the

button press is an asynchronous task and

all you need to do here is just to put

the keyword async in there okay

what we need to do is to have a look at

this link that i've provided for you

um i'm going to close this safari window

other sign-in methods great you can see

enable various sign-in methods

is not only limited to like google

services you can as you can see it can

allow you to enable facebook signing for

twitter or phone number sign-in so there

are various methods available

for you to enable in your flutter

application and in this application

we're gonna use email and password sign

and there's like documentation about all

of those in this link that i've provided

i'm not gonna go through the entire

contents of this to be honest with you

because there are just so much

information and we're not interested in

all of these but still i believe if

you're interested in firebase and

firebase authentication which we are

going to use in this course it is great

if you could just have a look at this

link that i provided for you here

is also right i've written here that i

need to talk about a little bit about

anonymous users you see firebase when

you start your application and you kick

you basically start the whole process of

firebase you say firebase start

firebase is amazing in that on the

client side it by default creates

something called an anonymous user so if

you talk with firebase with your

thoughts or application and say who's

the current user even if you haven't

done anything with firebase before if

you haven't configured it or actually

which we have already done but if you

haven't called any firebase functions

before in your application you could

just say firebase who's the current user

and firebase will just tell you here's a

current user it's an anonymous user so

that user is pretty much never going to

be empty it's never going to be null or

nil or whatever you like to call it so

or if you're python developer you just

call it none so that user is almost

so just know that firebase has a concept

i'm just going to take that in my notes

so what we need to do in the next step

i'm going to bring the caption up so we

have to kind of like speed things up a

little bit here because there's so much

um what we need to do here now is just

create two text fields now one for the

email and the other one for the password

and we are going to then put our button

next to those two text fields so text

field one email text field 2 password

and then the register button as the

third component now if you have

components like this that you want to

stack vertically one on top of each

other and one after each other then you

need to use a which is called column all

so what i'm going to do here is go here

to the center and kind of like remove

that i'm just going to say command dot

in mac or control dot in windows on

linux and just say remove this widget

okay i don't want to center anymore

command s results register buttons on

top left and what i'm going to do is i'm

going to command up again and say wrap

with column okay now if you command s

you'll not see anything directly on the

but what was created for you is a column

widget with children property which is a

list of widgets that it can display so

the first thing we're gonna do is to

so let me have a look here and just make

i'm just going to say a text field

save you'll see two text fields display

there so i can actually go in there and

like that so now we've created two text

i'm going to note that here a ticket in

my notes so we've talked about it now

grab the text that is displayed in this

take these text fields and when you

press the register button pass that to

firebase okay now you see i'm telling

you that when you press the button you

need to grab the text inside these text

fields but inside this function of

onpress you have no access to these text

fields okay so you kind of need to pass

information from this text field and

this text field to a text button and the

way to do that is is using something

a text or a text editing controller a

text editing controller is kind of like

a proxy object that you pass

to your text field and the text field it

writes its current text all the time to

that text editing controller and in your

text button here then you can say

controller text okay so you can then so

it's kind of like if your text field is

sitting here and your text button is

sitting here then you'll have something

here in the middle that is your proxy

the text editing controller that is

grabbing me for latest information from

the text field and then your the text

button can read that information okay so

just know that a text editing controller

now that we need to manage some state we

need to manage this proxy object then we

need to convert our home page to a

stateful widget okay so go in here to

your home page command dot and say

convert to stateful widgets so all of a

sudden stateful widget all right

um now what we need to do is to go and

controllers so i'm going to go in here

what do we call them do i have any

specific desire here let me see my notes

so there's no desire really for the

naming so let's just say late final text

controller and let's call it here email

and the other one i'm just gonna

now in the previous chapters we haven't

talked about late what late is this

keyword in dark that tells your program

that although this print although this

variable has no value right now but i

promise to assign a value to it before

it is used so it's kind of like a it's a

late literally means that i'm not ready

right now i will do it later i'm not

ready to assign a value to this so

what we need to do now is to

is to create these values now

you need to also know something about

stateful widgets now that our homepage

state is a stateful widget it will have

functions one is called init state i

believe and the other one called is

disposed now init state is a function

that will be called by flutter

automatically when it creates your home

page so it says okay now you have the

ability to create all your variables or

now whenever this homepage then dies and

goes out of the memory or it's trying to

go out the memory it will also get a

you've said that in the contract i've

written that i'm going to provide a

value for these emails email and

password text editing controllers and

the best way to do that is to go into

assign those to proper values so i'm

email is text editing controller like

and i'm gonna do the same thing for the

now you also need to understand that you

after you've created these two you also

need to dispose of them all right so

go in and overwrite your dispose

and then say email dispose and password

so a lot of developers forget to do this

especially like newcomers so don't make

that mistake so you created the text

editing controllers and you're also in

charge of disposing them okay

okay uh so we've done that already

after you've created your text editing

controllers you need to go to your text

those controllers to your text field so

in here there's a parameter called

controller and just say email

and for your text field on the second

one which is for your password say

it's password so what is happening now

is you hooked this proxy object that sat

this one which is your email or password

text editing controller to your text

field that is sitting here okay you

still haven't hooked it to your text

button which is sitting here so this

link is kind of broken and we're gonna

okay take it in the notes that we've

so what we need to do now at the moment

if i press command s you will see no

visible changes on the screen however

there's a little bit of a problem with

our text fields as you can see they

don't have any hint they don't tell the

user what they expect the user to

what we need to do now is to go and add

something to these text fields called a

a hint is a piece of information

and usually kind of like very subtle

color that tells the user about the

information that this text field expects

and that hint will automatically be

removed as soon as the user types at

least one character on that text field

okay so let's go to the first text field

and i believe it's an input decoration

and then say input decoration okay

and for the hint there's so much

information on the screen we can't see

and there is a hint text as you can see

hints text and it expects a string so in

here say please enter or just say enter

and you can see it's suggesting this to

be a constant so i'm going to make it a

and a little bit of a comma there as

well and you can see now it says enter

and copy and paste this decoration as

well and put it in the next text field

so say that enter your password

so let's enter your email here enter

let me also make sure that that is

correct there and take it in the box so

then if you start typing in those fields

you can see that the hints disappears as

soon as you type something and if you

remove that character then the hint also

disappears and the same thing for the

work done here and we need to get

through the authentication so when you

press this text button here where we

need to do authentication and that means

we're just going to register for now

so what you need to do is you need to

firebase so firebase was our dependency

and using the import statement you can

actually grab the content that it was

created for firebase and bring it into

so as you can see here we're gonna bring

now command s you don't see any

difference on the screen because an

import statement doesn't really change

the state of your application as such

i'm going to take it here as well that

so what we need to do now is to upon

pressing this button where we're going

username and password from these text

username or sorry email and i'm going to

i'm going to say final password

we're going to our email and password

controllers and grabbing their text

which is the latest text that the user

entered in those fields okay

after we've done that now you can go and

and then you will say create user with

email and password you can see this is a

that allows you to register or create a

user as its name indicates uh with

um i'm gonna do that so as you can see

here as well this thing returns a future

so this is this is not nothing that you

can just like call and say hey do this

without actually awaiting on it

otherwise it will just say here i am a

future i'm something that i will

calculate something in the future and

by not putting a weight before that call

you will only get the instance of future

you will not actually get the work that

it's doing you will get like a wrapper

around the work saying that this is the

kind of work i'm gonna do but if you

have weight on it it will actually

if that makes any sense so i've

explained the weight in that chapter i

think also chapter seven or whatever it

was when we talked about more advanced

topics in dart so please have a look at

um after doing that you will see that

the return of this is actually future of

a user credential so what i'm going to

do is i'm going to say final user

and then i'm going to print it user

and just hot restart here just in case

because we didn't import so what i'm

going to do in enter email here i'm

going to say pixelityab.gmail.com

and for the password i'm just going to

so let's bring our console up so we can

see what our application prints to the

and i'm just going to say register which

we're going to get an error for right

and you can see here it says no firebase

app default has been created called

this is i mean this is really good that

we're getting this because i actually

have planned for us to fix that

um but before we go ahead and do that

um i should probably explain what this

is why this is happening you see

firebase there was there was if you

remember when we configured it there was

a file created here for us called

and it has a lot of code in it and then

there's like a configuration here uh

that here you see android and for ios as

well now what firebase is complaining

about is saying that you've created this

configuration but you've never actually

poor firebase so what we need to do now

before we actually do the configuration

something that you can immediately see

on the screen which is which is

you see foo bar bas is your password it

shouldn't be visible to the user so when

you're typing it it should be a password

field and at the same time this field

here you see is is an email field but

where is the add sign at sign isn't

immediately visible here so you need to

tell these text fields to be configured

in a specific way so that they're

actually suitable for email and password

so i'm going to get rid of this bar on

the right oh sorry on the left

and what we need to do is to bring up

for the next thing for the next topic to

first what we're going to do is to make

what you need to do here in your

decoration of the password field go in

here and say obscure um actually it's

not in the decorations right here

it has true and if you press s on that

you'll see that your text is now obscure

false and then you will also do

false these are three important

provide here now you see enable

suggestions is usually like as you're

typing in a text field depending on your

it will provide you suggestions like

in a password field you don't want to do

that you don't want to have any

suggestions so that's for enabled

suggestions also autocorrect is when you

try to type something and you know you

all probably know what autocorrect is so

i'm not going to explain it so you're

disabling autocorrect based on your

password password field which makes

let's go and bring these two properties

also to our email field which is

and what we're also going to do is to

tell it that it is an email it needs an

email keyboard so let's go in here and

or keyboard i think type and it's called

there's the email address so

now if i then go here you can see

there's an ad sign so i can um oh sorry

you can't see it so i'm going to do

this so you can actually see the that

sign so you can see their keyboard here

and then there's an ad sign right there

that's for that and then suggestions are

also disabled so as i type there's no

suggestions really for my um text

because you don't want suggestions on

email fields emails are usually like

um or not usually but sometimes so you

don't want any suggestions there okay

we've done that i wanna take all of

these items as done in in my notes

now the next thing we need to do

initialization of our firebase app so

we're gonna do it naively right now so

because you see we still have this error

pixelity a b gmail.com and i say

i say register we will still get this

error that says no if no firebase app is

so what we need to do is to actually

sorry initialize firebase before we do

firebase instance create user with email

what we need to do then is to go here

auth instance or initialize app

i've actually forgotten the syntax for

let's see if we actually can learn

how to do that by going to our

initialize you can see it should be done

and what we need to do then is to import

firebase options as it's as it's showing

here firebase options and then await

firebase.initialize app with this okay

so let's let's kind of grab that code

and then go into our main guard file and

import firebase options so i'm going to

this code that was provided there for us

so i'm gonna remove the comments

command s and i can still see that

firebase isn't imported so we're going

to import it by doing import library

package firebase core firebase core here

what i did here is that i basically took

advantage something that's built into

visual studio code in order for me to

get the import statement automatically

so i'm going to do command dot on it and

import this dart file so i'm just gonna

take advantage of that why not

and you can see that it is imported here

now that we've done that um i'm gonna

press command s my state is preserved in

the uh in my phone here and let me bring

the logs here clean them and then i'm

gonna press the register button

uh here and we got an error here and it

says device unlock initializing all

firebase apis and firebase preparing to

create blah blah and let's actually see

it is on handle exception request

unreachable host and that is probably

because i actually don't have proper

so i'm gonna go here and i'm gonna go to

actually great that you're seeing these

errors because these things do happen so

so make sure that it's gonna connect to

and it connected i'm gonna go back to

clear the logs oh my god there are so

many things displayed there

so then what i'm gonna do is i'm gonna

repeat the same thing i'm gonna say

next state that i have prepared that it

says you can see in the errors it says

what is happening here i'm not taking my

notes that we've talked about the other

what is happening here is that

we haven't actually told firebase

that we are going to take advantage of

email and password signing combination

as i told you before there are various

way for various ways for a firebase to

allow us to register a user uh apple

login um you can do email and password

combination you can do facebook you can

maybe twitter as well yeah i think

twitter was there as well so you need to

allow this combination all right

now i've explained that let's bring up

safari or your favorite browser maybe

chrome and let's go to uh console

firebase google.com i'm going to bring

my browser on the screen so you can also

and i'm going to then find our

application which was called

uh my notes flutter project okay so go

consolefirebase.google.com and find your

project that you created in the previous

then go to authentication as i as i show

authentication actually get started

uh what we need is this email and

password combination so go email and

password combination and just allow it

and that's it that's all you have to do

grab this screen just kind of bring it

monitor so you don't see it clean the

so you can see now all of a sudden you

got user credentials back from firebase

register your application like register

a real user with firebase like that is

actually magical so i'm gonna

click on my notes that i've talked about

however you see this this is a little

bit problematic in that by pressing the

button but we're actually initializing

an application and then we're doing the

create user with email and password what

would happen if you had two or three

buttons on the screen all needing

firebase you can't do firebase

initialize app in every single one of

them so the solution to this is kind of

like initializing your firebase

start and start with everything else in

your in your on your screen and on your

there is good documentation of how to do

that and i've actually linked to that so

so what we need to do is take advantage

of something called widgets flutter

what happens to be honest with you here

is that firebase it needs some

kick start its process before everything

else is rendered on the screen and in

order for that to happen it needs to it

needs to have some sort of that like the

core flutter engine to be in place

and so that it can make its call to the

core slaughter engine and say that i'm

done with my work so in order to do that

then you need something called um

the um caption for that and i can show

you that i'm this is this is the

documentation that i'm showing you as of

in our in your void function here

um before we actually you see

maybe i'm jumping over a little bit but

what we're trying to do is to try to fix

this issue here that we're awaiting on

initialize app on firebase okay so we

don't want to do this on the press of a

button we actually want to do it

somewhere else and in order to be able

to do that somewhere else we have to

first take care of this widget binding

okay so in your main function in here

widgets flutter binding dot ensure

okay and if you want to know more about

that i strongly suggest that you read

this documentation that i've provided

um now that you've done that do a hot

okay so you're gonna lose your state

here after the hot restart and that's

i'm gonna take that in my notes that

app is a future you see it's a future of

firebase app now what you need to do is

kind of like you want to tell flutter to

not build this column before it has

the way to do that is using flutter's

future builder widget future builder it

it performs the future and once this

future has succeeded or it has failed

doing its work it will give you a call

back and in that callback it asks you to

actually produce a widget you want to

display to the user depending on the

of that futures result so it basically

instead of you having to do this

initialization of firebase every time a

user presses the button you say i'm not

going to do anything until that is done

once that is done or if it errors out

let me know then i will give you a

widget to display to the user depending

is gonna go to this body which is a

column right now command dot and then

let's see stream builder we have but we

don't have future builder so i'm just

gonna say command dot wrap with

and i'm gonna say future builder okay so

i'm gonna build a future as you can see

okay builder is required so let's put a

builder parameter here and if you're

like me and you forget these syntaxes

you can just control space in visual

studio code on mac or command space in

linux and windows to get help

and then you'll just use this syntax

here you see this until the end of the

then you remove your child bring that

entire thing and put a return here and

now your future builder um it doesn't

have an actual future to come to perform

say that we've talked about the future

and what we need to do now is to grab

this future from here you see

await firebase initialize app and grab

that future without the weight remove

and put it in the future builders future

you can see nothing has really happened

you didn't have any difference you don't

notice any difference basically

so if everything really worked as it

then what we need to do then is to

um if everything is working as expected

then we should be able to register users

so what i'm going to do here is i'm

going to provide the exact same user

already registered and then say register

and you'll see now we get an error

let's see if i can show you there and it

says the error is firebase auth email

already in use the email or the email

address is already in use by another

and that is this part which i'm gonna

bring the caption up for you

the next topic that i want to talk about

before we close off and round off this

we told future builder to perform a

the future was firebase initialize app

now if you look at the builder what

we're returning from it right now is a

column but we're completely ignoring the

parameters that are coming in here

the second parameter that gets passed

your builder is something called a

snapshot of data type async snapshot as

an async snapshot of an object is the

state of that object right now okay

so and that object itself is actually

the result of your future in this case

it didn't understand that this snapshot

is an async snapshot of your firebase

app but that's okay we don't actually

need the firebase app in the snapshot

however one thing that you do need in

this snapshot is its state you see a

future has a start point it has a line

where it processes its information and

it has an end point it either ends

successfully or it fails now the

snapshot is your way of getting the

results of your future whether it

has it started is it processing is it

done or did it fail so what we need to

do in here as we're waiting for firebase

initialize app to do its work we're

gonna basically say uh we're loading

just tell the user loading and as soon

as the snapshot is done then we're gonna

so let's do that let's go in here and

connection state all right and then get

help from visual studio code to complete

this so i'm going to say add missing

case clauses and you can see there are

done waiting active and done

waiting let's let's just say everything

else except for done we're gonna return

text that just says loading so

let's say in here we remove all of these

in the done statement we say return this

right and then we don't need the break

because we said return and then we're

default is a special case which is not

actually inside that enumeration but is

a case that says everything else that i

haven't handled and in this case we just

loading something like this as a

sorry hot restart and the two hours

video this is happening so fast that

we're not actually seeing the loading

but at least we have handled the case

that if for instance a user's connection

is too slow or their device is too slow

when the future has finished they will

see this column i'm gonna actually fold

and if this feature hasn't finished yet

it's not done then they will see this

text offloading all right and by the way

this is how you can actually fold and

unfold things in visual studio code so

fold like this unfold all right it's a

great way of seeing more of your code so

wow a lot of information this this video

took an hour kind of like as i expected

so we now have a basic firebase setup

we've done our initialization of the

application of our firebase we talked

about a lot of widgets actually we

column we text talked about text future

god app bar so many things so

this is a lot of content and if you

didn't get all of it that's okay we're

gonna talk more about these in the

but i strongly suggest that i mean if

you're watching this course and if

if you're an advanced developer and

you're watching that's completely fine

but if you're if you're develop if

you're not a developer or if you're a

junior developer or someone who

doesn't have so much experience with

flutter development and you're really

trying to learn everything i'm saying

here please don't just watch this video

go and do this yourself go and write

this code pause the video as i'm talking

i know i'll talk a little bit fast but

that's just to save a little bit of time

pause the video write the code as i

write it test it as i test it and see

the results for yourself because that's

how you will learn not just by watching

great we've talked a lot about

widgets and firebase configuration

and in the next chapter we're going to

talk about login screen and also email

verification and also clean up our

registration screen so without further

ado let's just prepare yourself for the

next chapter and i'll see you there

hello and welcome to chapter 13 of this

in this chapter we're going to talk

about the login view in chapter

sorry about that we talked about the

we actually talked about quite a lot of

things which after after that i i

thought maybe we need to kind of like go

through them one more time just

every now and then talk about those

those little widgets that we talked

about like a future builder center

column text button and we talked also

text field text editing controller so

there were lots of components that we

talked about but we got pretty much like

a simple registration flow working it

wasn't really a flow actually it was

just a simple registration screen

i'm saying that it wasn't a flow because

it was just a simple screen that didn't

lean anywhere that's usually what is

called the flow if you have a screen

now in this chapter we're going to talk

about login the login view and we're

also going to divide the logic that

we've created in our current home page

and put it into a registration view so

we're by the end of this chapter we're

gonna have two views one is for the

registration the other one is for

um we have those logic i mean the

registration logic in place now we have

to work on login but we also work a

little bit on cleaning up the code

usually this i mean as you get more and

more comfortable with software

development you'll know that

you will have like these flows of ideas

and then you'll start coding and write

your code and then you test it and then

after a while you realize oh this got a

little bit messy i have to refactor the

code so that's what refactoring kind of

means like you take what is already

there and you kind of make it better

make it cleaner more presentable so

that's what we're also going to do in

so the first thing we need to do is to

create a stateful register view widget

so as you can see here this will be used

the base of our register view

let me go and bring some stuff that

we're going to need in this chapter the

i bring it to the screen so you'll see

and scr cpy we set it up in one of the

previous chapters so you should be

comfortable with that already

i'm going to go to go to our app here

which is the register view that we

created gonna bring my face to the right

so we'll see a bit more of the content

and then i'm also going to bring up

visual studio code which is appearing on

another screen right now but i'll bring

it up here so you'll see as well

i'm going to increase the size a little

so this is where we lift things um

and do the screen like this so this is

where we live things we have a home page

which at the moment is the register view

okay but we need to create a register

view like not just a home page it's

and since we need a stateful widget

we're going to use a shortcut in visual

studio code to create a stateful widget

for us and that is with s t f as in

state full so if you want to create a

stateless widget you'd say stl okay

and in here we're going to call it what

should we say register view like that

this will be as i've mentioned here this

this will be the base of our

registration view all the code for

appear here i'm sorry that i'm looking

going through my notes i have very

detailed notes here and just making sure

that you get all the information that i

plan for you to get so if you see me

looking here it's just because i'm

looking at the notes to ensure that

um so now that we've created register

view at the moment it doesn't have

anything so it's just a container and

the default color for containers and

let's go to our register view here

so let's go to our main function here

and as you can see at the moment we're

returning home page as the home and what

we're going to do here is just to say

instead of that return register view

and that is it's very possible we will

get a problem here and you can see

nothing is changing because i'm changing

something inside the main and that isn't

affected really by a hot reload

so we have to hot restart so i'm gonna

and you can see now the screen is black

so what we'll have to do here now is to

rename our home page to our login view

actually so we have a new registration

view which we're going to write the code

for or actually place the code from the

previous home page into register view

and we also need the home page to be

renamed so it's very some i mean there's

lots of renaming putting things here and

there but we're just playing with some

the next thing you need to do is to go

to your home page which is here

and rename it one way to do that visual

studio code is to right click on it and

just say rename symbol or i believe it's

or actually for me it's f2 if two does

the renaming but on a macbook pro for

instance you don't you can't just press

f2 because f2 has another function

so what you'll need to do is to press

function keyboard keep key on your

keyboard and then press f2 that will

bring up the rename dialog or you could

just right click here and just say

rename symbol which does the same thing

so rename your home page to login view

all right so we have login view here now

um i'm gonna take it that we've done the

right now all we've been doing here is

just to like write our code write

everything in main dart but this is this

is not a not the right way of doing

things especially as your projects get

bigger you need to make sure that you're

you're taking the responsibility to also

make sure that your code is readable and

the structure of your project is

understandable by others who may also be

working on the same project now chances

are that if you're watching this course

that you will be the only person working

on the source code so you won't have

anybody else looking at your code

that you may be the only person looking

at the code and working with it you

still will need to from time and time

come back to the project fix some stuff

add some stuff remove some stuff so

even if you're the only person working

with it you will need a clean

source code to look at so if you come

back to the source code after a month

and you start to add more and more stuff

to this main dart file after a while it

will just get out of control so

you'll need to also do refactoring on

your code just to ensure that it is in a

what we're going to do is to bring up

as you can see we're inside lib and then

there's a file called main dart

to move our login view into its own file

and you can see here i've written that

we're going to move it into lib views

login view this file doesn't exist at

the moment so you'll need to create it

what you'll do here i mean in visual

studio code there's a great trick that

you can do that it can create a file on

folders as well so instead of going here

and say new folder to create this views

folder and then inside there i create a

login view what you'll need to do just

and then type the entire path in there

views and then slash login view dot dart

and this will create the views folder

so what i'll need to do here is to

take our login views code as you can see

as we had here class login view and then

bring all that code into this new login

view file that we just created okay so

i'm gonna get this out of the way

all right and that's okay we're getting

a lot of errors here and the reason

behind that is i mean we haven't talked

about import statements so much before

a way for you as a programmer to bring

whether it is the flutter team at google

or whether it is a third party

where those pieces of code are and at

i mean if you're not coming from a

software engineering background you're

the closest analogy that i can find is

as if for instance in figma you've

you're trying to create an instance of a

design that you've already created but

figment doesn't know where that instance

is so you'll say oh here's a copy of the

and then figma is like oh where can i

find that button you haven't even

created it so then you need to first go

create that button or drag it in from

another project and put it in your

page and then you can create an instance

if you're not into design and

figma you may not understand what i just

what i'm trying to do is just to be as

inclusive as possible in this course to

make sure anybody who's following this

try to at least understand bits and

going back to import what we need to do

now is to tell flutter where those

pieces of highlighted code are and one

thing to do in visual studio code which

can help you greatly if you're trying to

writing things by hand is just to do

command on mac or control on linux and

windows hold down command or control

depending on your operating system and

then you will see suggestions here as

where those components those missing

components may be placed and what you'll

need to do here is just to import

package flutter material because that's

where these components that we're using

i managed to click the wrong wrong

option there so material boom

all right i think now almost everything

has disappeared all almost every error

has disappeared except for these

and also here we need to import minors

so i think everything basically is

disappeared there's also firebase auth

alright so we're good to go now on this

this login views code really is not

login view i mean if you remember the

code that we've written in the previous

this login view at the moment it says

log view but all it does is register do

you remember that we have the text field

and even the button that says register

what we need to do now is to

drag the code as you can see here from

we need to kind of bring it into the

register view okay and our register view

at the moment is here you see

so let's go and try to do that a little

bit with care okay so grab all this code

that is here in the login view here

and also grab your email and password

so i'm gonna go then in here in the

then paste those right before the build

function so there we go okay

go back to login view dart and you can

see that there is a build function here

i'm going to literally just grab that

entire build function including the

as i can see here the build function

ends right there and i'm gonna cut that

also okay and i'm gonna go here and

replace this override on the um

on the what is it called register view

and paste that one from before here okay

so what all we did here is we made sure

it is indeed the register view and the

login view is empty at the moment so

what you'll need to do you see there's

an error here that says that okay you

have a stateful widget for login but it

doesn't have any build function

so you'll now need to create that build

function and of course you could do it

write all that code by hand of course in

the beginning you may say that oh well i

just want to learn the best way to learn

is to type and i completely understand

that but there are some things like

there are limits i also believe like

once you've done it once or twice you'll

kind of get bored of doing that or

you'll get tired of doing that so i

actually suggest that for these

functions that you're overriding the

best way is actually get your editor

text editor or ide to complete these

things for you so i'm going to go on

this error and just say command dot on

mac and control dot on linux and windows

and say create one missing override okay

and in here we just say return

so that's our login view and you can see

that is right here and then we also have

in our main dart file here i can see

that there is a register and let's just

hot restart okay so we have a register

our login view is completely empty so

what we need to do basically is kind of

it's kind of work on our login view

because this is this is like the goal of

we need to have a login view and up

until this point what we've been doing

is kind of like create a register view

with all the code in it a separate login

previously created registry so

i mean this is all a lot of talk just to

say that we have a registered view

but we don't have a login view and we

need to work on login views so

wow i mean you don't actually have to

remember you can look at it here the

register view has two fields enter your

email here and for your password here

this is this their register v and login

are very similar to each other what

register view does differently is that

it creates this it basically does a call

create user with email and password

but if you think about it everything

so you need to create you need to make

sure in both of them that firebase is

you will have two text fields email

password and you will have a button one

for register and for one for login

what we could do to be honest with you

is to now go and copy this code that we

okay that happens i actually forgot that

so let's go and copy this code again

literally get grab everything from there

and put it in our login view like that

and change this register button to log

so now we have two copies of the same

view basically once it's registered the

other one says log in all right

and what we could do is now go to our

and instead of returning the register

view we could just return the login view

because we want to work on the login

view now okay we have a user registered

and now we need to work on login and as

if you follow the previous chapter

you'll you'll know that we actually did

register a a valid user with firebase

what you could do is to go to your

as we could do now just an ad hoc i

ensure that you're logged in with your

then i'm going to go to this uh project

that we created mynotes flutter project

authentication and you can actually then

using the flutter application that

you're actually working on so when you

call this function in your in your

register view this function

firebase os instance create user with

email and password that user was indeed

created in the firebase console so here

you have a user you could also disable

this user and do other things but we're

just going to leave it like that for now

so what you need to do now is instead of

register view tell your home page to

render the login view and you could just

type a login view like that you will get

an error of course because login view

isn't in scope but i believe visual

studio code could actually help with

that because you see we haven't imported

this main dart file doesn't know what

exactly the same thing happened here do

you remember if we didn't have these

imports we got lots of errors saying

that they i don't know where this class

is so the same thing is happening in

this main dart file all right so i

believe in visual studio code now i'm

kind of improvising but i think if you

set login view and just press enter boom

it does an import automatically for you

and let's see where it is here you see

but if you're not comfortable doing that

by hand and do the same thing i showed

you before just command dot on mac or

controlled up in windows and linux and

say import okay so it's going to import

now we have the login view and if i

press command s or actually we have to

you see now there is a login button

so what we'll need to do is as you can

see in the caption now that we're

working on logging the login view go to

and go here where the button is pressed

what we'll need to do here is to

call the a new function on our firebase

auth instance instead of create user

with email and password we're going to

but sign in with email and password and

you can see the function signature is

very similar to create user with email

and password in that it takes two

parameters namely email and password

both of type string and then what it

does return in fact is user credential

and do you remember create user with

email and password also return user

it's very simple to switch between login

and register in that in that sense so

grab the sign in with email and password

that's the only thing we're interested

in and just paste it here instead of

scrcpy crashed and i have no idea why

that's okay that wasn't planned what we

could do is to go to our and i can see

you see it got an aborted so what we

could do is to go to our terminal and

and i'm going to bring it to the screen

and also if you're if you noticed here

we have a login button but the title

here still says register so let's go and

fix that let's go into the app bar and

and actually problem is i can also see

as scrcpy crash also the running of this

process this application on that android

phone also crashed so there is i mean

the flutter instance of this project

isn't really running at the moment so

what i'll have to do is to go to main

dart and say run without debugging so

and it's now launching doing a gradle

build gradle remember from the previous

and if it's using xcode it is for ios

it's doing the greater build so if

everything goes according to the plan

title up there and while this is doing

its work i'm going to go to my notes and

that i've talked about the things that i

about all right it's installing our

application i'm gonna remove the widget

inspector and now you can see we have a

that is working as expected all right so

as you can see here after the logging

call here sign in with email and

enter some information of a user that

doesn't exist okay so i'm just going to

and i'm going to say foo bar path

and i'm then going to bring up the

console here as you'll see the debug

and i'm going to actually remove

or do something like this so you can see

the debug console a little bit better in

its entirety and i'm going to press the

the next thing that we need to handle as

i'll perhaps increase the size even more

that doesn't exist meaning that we

haven't registered that user then we got

an error here that says firebase off

user not found and that that makes sense

actually completely because

registration for this user okay

what we could hear what we could do here

here and i'm gonna bring things back up

here we're recalling this function uh

let me decrease the size because it's

signing with email and password

a thing called an exception and i don't

think we talked about exceptions to be

honest with you while i was i was

teaching you about dart if you know

about exceptions you could just skip

through kind of skim through this little

bit of the video but if you're if you're

not a software development developer

from before or software engineer then

you may not know what an exception is an

things go wrong and you haven't kind of

thought about those things from the

beginning so as you can as you

for instance if you're if you're working

if you're a software if you're a

haven't done software development before

you may have also used other pieces of

software and sometimes software crashes

just like scr cpy just crashed a few

an exception or an error that the

software developers who created scrcpy

hadn't counted with so they hadn't

an error might occur in this scenario

not having handled that the application

crashes it means that an exception

happens and error happens that the

developers of that program hadn't

and this is an exception that you're

seeing here in your flutter application

so firebase is saying that you're trying

to log in with a user that doesn't exist

so what do you want to do with it i

can't continue after this i don't know

the way to handle exceptions in

flutter or in dart actually is using a

try catch block so i'm going to bring it

here put the entire code for your user

credential creation in the try statement

as you can see here and then go in here

and then i'm just gonna say something

all right so you can see here now we

have a try block as indicated here with

this line it's all the way from on top

to here and then we have a catch block

the way try catch works is that it as

its name indicates it tries to do the

work that you're saying it needs to be

done in the trial block should anything

bad happen it will go to various catch

statements that you can't then place

as you saw in the logs this error

let's see if we can find it here

it was of type firebase auth uh let me

see on handle exception but we didn't

actually get its type unfortunately so

print something bad happen and then

so i'm just going to say clear the logs

and then i'm going to press the login

sorry here and you can see now it says

something bad happened firebase auth

user not found and then some information

we could actually say print e

run time type and doing that will

actually give you information about

which class of exception this is because

as you're working with flutter and as

you're working with software generally

you're creating software you're writing

code different types of exceptions

happen and these exceptions have their

own identity every exception has its own

identity it's the series of classes or

different places that it may come from

anything can become an error even a text

can become an error or enum can become

when you come to this catch block as

i'll move my mouse over it you can see

that here it says i don't even know what

but you are actually in the in your

cache block you're mostly interested in

exceptions that might occur from

since we don't really know what this

and we're gonna have a look at what type

is this a little bit better arrangement

perhaps so you can see what happens yeah

perhaps then what i'm going to do

and go here press the login button and

you'll see that the type of that

exception is firebase auth exception all

so what we need to do now is to go to

firebase auth exceptions not just any

exception as we're doing here

because we're catching any exception so

what we want to do is to catch firebase

off exceptions in our cache block all

right and a way to do that is i'm going

and i'm going to do like we were doing

before get rid of the consoles to see

so what you could do you can have

specialized cache blocks in dart and

that means that you are not catching

everything but you tell dark that look

in this particular catch block i'm

interested only in exceptions of this

as you might have guessed that already a

try block can be accompanied by more

this cache block that you can see here

is called catch all it catches every

exception that might occur in the

running of the code inside the try block

if you're interested in specific

exceptions in this case firebase auth

exception i believe oh i've cleared it

but i think it was firebase off

exception i'm going to run it again

go to the login button and you can see

it says firebase off exception so we're

interested specifically in that so let's

go and say tell dart that we're

interested in that i'm just i'm going to

so this is the format of catching

specific exceptions you prefix your

catch statement with the keyword on and

then you write the type the runtime type

or the class name of the type of

exception that you're interested in

so in this case we said on firebase off

the exception catchy and we're gonna

actually i don't even have to cut and

what you'll need to do in here just say

save this before i before i tell you

what i was going to say after uc

let's test this let's say login and

you'll see that the code is used or not

now that we told dark that we're

specializing in catching exceptions of

firebase auth exception then this e is

not an object anymore really let's see

if we can get some help now it says okay

if i can catch exceptions of firebase

auth exception then i know that the

error that i can pass to you is of that

now that you catching firebase

authexception you can go to this code

and you see there are different

properties that you can read from

message code email credential et cetera

so we're now interested in the code

as the caption right here shows at the

bottom of the screen you'll see that we

need to handle e-code equal to user not

found all right so let's say if e code

user not found like that else e code oh

sorry actually we're not going to do it

outside kind of like running ahead of

e-code user not found then we're just

saying print user not found okay i'm

going to clear the logs here go back to

see our cpy here and i'm just gonna say

login and you'll see all it does it says

so that's that we haven't really i mean

the caption at the bottom left of the

screen says handle but depending on your

expect handle to do different things for

a software for a seasoned software

engineer handle may actually mean that

well do something about it okay tell him

tell the user like oh i couldn't log in

whatever reason just show something to

the user and we could do that but at the

moment we don't have the capacity to do

that we don't really know how to handle

what we need to do then is to simply say

print so we just print it to the screen

so this is our handling for now okay

it's very simple all it does is just

ensures that no exception is thrown to

the user's face or that the application

okay that was a lot of information um

now as the caption here shows in the

login view we also need to handle wrong

and i mean as you can see here the e

code is a string so anything here could

happen that could be defined by string

one of those errors actually is wrong

password so let's test that

in here let's say else if if the code is

not user not found just print

the errors code to the screen okay

and i'm going to then go here and then

actually change this email to an

existing email which was the one that i

and password i believe was foobar or

and i'm going to say login and you can

see here it says now something else

that could that could kind of mean that

well yeah actually that isn't my

password this foo bar was in my password

i don't even remember what it was maybe

but that is great it says something else

happen an e code and that's exactly what

and that is exactly what we need to

handle here um wrong password so in your

then we're going to say print

so that's there clear the logs i'm going

to say log in and you'll see the message

we've done quite a lot of work now in

the login view but we haven't really put

much energy into the register view you

see they're very similar in that they do

almost the same api calls with the email

and password ones that sign in the other

however in if if we go to our main dart

file you'll see in here in our register

view we're just calling the api and kind

of like hoping for the best there's no

try catch statement here okay so what we

could do is have a look at how we did it

for login we put the api call inside the

try block you see what we need to do is

to go to main dart and for our register

here register view state do the same

thing let's put this in a try block here

and then just say catch or say on

this is i mean i'm not going to explain

this again because it's exactly what we

i believe firebase authexception didn't

really exist in this in this dart file

before but that is what visual studio

code helped me with as i typed it and

pressed enter for auto completion

then it must have been imported

or it was probably part of firebase auth

dart i believe actually so if i command

it goes to firebase auth so that's why i

it probably didn't have to import

anything because it was already imported

as a part of firebase auth okay

oh wow that was a lot of information

now that we're working on the register

dar main function here and since we're

only seeing the login view let's switch

and command s but this is not going to

change anything as you remember hot

reload doesn't have an effect of any

changes that you it doesn't have an

effect on anything that you're changing

the main function remember that you have

so hot restart now we're in the register

and we need to now handle wrong password

no that's not the login sorry about that

as you're working with uh firebase zoom

you will notice that it has its own set

of security rules you also can override

these security rules later for your

server if you want to for instance you

can expect or you can say all my users

have to have passwords that are 18 um

characters long and a mixture of digits

and alpha numerical values etcetera

there are some default security rules

for credentials that every user needs to

abide by so let's actually have a look

do a print here and i'm going to say

and as you'll see in the caption as you

are seeing in the caption there is an e

code of equal to weak password that

needs to be handled so i'm going to go

here try to register user with my

personal email and the password of a b

c all right then i'm going to bring up

the console clear the console a little

i'm going to do this so you'll see it a

then i'm gonna try to register with a

password of abc press register

here you see the code was weak password

and as you'll expect yeah weak password

that is too weak a password to even be

so what we need to do here is to handle

error basically i'm gonna take in my

notes that i've talked about some other

all right so we'll handle weak password

and let's just say print week password

um so that's that's that for now okay

and i'm going to just bring up the um

and press the register button one more

now you'll see the information let me

bring it so you can actually see it

yeah you can actually see it great you

can see weak password being printed here

now let's go let me bring the let make

the screen a little bit bigger

the next thing we have to handle

is um in this register view as you can

you can also get an error called email

already in use so if you go to the else

statement here again and print

if i try to register with the same email

this user already exists and if even if

i have quite a good password for this

user so i'm going to say fubar bass

so we know that the error is not going

to be the password like it's actually a

better than fubar baz at least and that

or abc so i'm just going to say register

do we not get any value here or did i

even press the register button

oh i hadn't saved the file oops so yeah

i haven't saved my changes i'm gonna say

oh now it says email already in use and

that is exactly i mean that is pretty

much what we have to handle right

because we're printing e so

um i didn't have to say oh no surprises

so let's handle email already and use so

i'm going to copy this email already and

use string just exactly as it's

and i'm going to go to else and say

that string and then say uh email is

clear the logs press the register button

again you can see now it says email is

let me also have a little bit of a look

i can also i mean to be honest with you

in the notes i don't see anywhere

that we're really trying to handle

uh these errors like actually doing

something about them all right

to really like show a message or

and i'm kind of wondering that right now

like whether that's a good idea or a bad

idea for this chapter and perhaps just

doing a print will suffice to be honest

not entirely sure about that so

um let's leave it at that for now okay

i'm also gonna go here and make sure

that i'm not yeah i'm in do not disturb

so let's leave it leave it at that email

already use perfect okay let's leave it

now the next thing that we have to

it could also write a situation where

the user tries to enter an invalid email

all right so let's put an else statement

let's go and remove this add sign so it

becomes an invalid email and try to

press the register button okay now you

can see uh you can't actually see now

you can see at the bottom in the logs it

says invalid email and that is the code

for that error so let's handle invalid

so i'm going to go here and say else if

e code we call to invalid email then

we're going to say print invalid email

entered all right and save it

tap the register button and now you'll

see invalid email entered okay

error handling and as we're going on i

mean to be honest with you i still have

a little bit of time to figure out

whether we're really going to handle

these things by and by that i mean like

if we need to display some some error to

the user okay and we may need to do that

but it is a little bit complicated like

depending on how we want to handle it do

we want to show like a message to the

user do you want to show a toast to the

or do we want to like display another

screen to the user and that's kind of

like unclear even to me right now so

maybe we'll iron these things out then

in in the upcoming chapters as well

carry on with the upcoming chapters

is actually to make sure that we are

logged in to the application you see

we've worked on the register view we've

we're trying like so many different

combinations here to register new user

login so i personally don't know at the

this application firebase instance

actually has a logged in user and if

you're familiar with like python django

or flask or if you're doing nodejs or

whatever development like backend

you can be a logged in user but still

so if you send a login login user to a

login view doesn't mean that the user

instead it means well that user is

logged in but may want to log in as a

different user so that is the case in

our application as well we have a

register screen a login view but i

personally don't know what the state of

the application at the moment is are we

logged in or are we not logged in

because we're kind of like playing with

different views here okay so that's very

next chapter i can see in chapter 14 we

we're working on separating the app

initialization from the login and

register screens because you can see at

the moment we have this future builder

initializing firebase and it is doing

lots of work comes with snapshots stay

done blah blah and we're doing the exact

same thing in two views login view and

what we need to do is kind of like

and ensure that we display the correct

view depending on yeah what the state of

the application is and before we can

then continue or start that chapter we

kind of need to make sure that the user

the current user is logged in all right

main dart here and login logged in views

already displayed so i don't really you

don't need to worry about this part

what you need to do now is to make sure

that instead of register view we're

and remember now we're saving something

changing something in the main

function so hot reload isn't going to

work so you need to do hot restart

so we'll get to that login view

and let's then enter valid details here

so i'm going to say pixelityab.gmail.com

and i think the password was fubar best

i'm going to press the login button

all right and there we got the

wow that was a lot of information and i

so what we need to work on now i'm going

to take some stuff in my notes

as i mentioned we need to for the next

chapter i mean we're kind of done with

this chapter to be honest we've talked a

lot about like exception handling

separated the login view from the

register view but our register view is

still in the main dart we're gonna we're

but what you need to know to do before

you continue with the next chapter and

just ensure that you're displaying the

login view to the user and that you're

actually logging logging in with a valid

username and password this ensures that

the firebase instance that is running in

this application right now is going to

cache that information locally on ios is

going to cache that information in a

secure storage called keychain and on

android i think it's called shared

preferences or something like that

so that information is going to be

securely stored now on that telephone

which for me is an android telephone

when i restart the application whenever

telephone restart the telephone the os

come back up that information is already

saved on that telephone so my user is

so just ensure that before you continue

with the next chapter that you've

registered the user first and that

you've logged in with that user from

your application so that information is

cached inside the application all right

we're going to separate the app

initialization from the login and the

register screens there are only a few

so i don't think that chapter is going

so grab a cup of tea coffee whatever you

want chocolate or whatever it is and

i will see you in the next chapter

hello and welcome to chapter number 14

as you saw in the previous chapter we

worked on the login view now we have a

login view and a register view in place

and what you also saw is that we did

error handling for various scenarios

uh email address already registered

incorrect password or wrong password i

now we have two views in place

um we have but we have two main issues

registration or the register view that

and the other issue is as the caption

here displays is that the widgets are

if you remember from the code

there was this firebase initialization

invocation that we had to do and since

the login view and the register view are

very similar to each other they're both

what we're going to do in this chapter

make them one that's that's the first

first thing we need to do so we just

have one initialization that's going to

and what we're also going to do is to

bring the register view in its own file

so this this chapter is going to be a

quick one unlike the other chapters and

i think that's kind of refreshing to be

honest with you otherwise all chapters

start with the first thing we have to do

basically to move the register view into

i'm going to see if i can bring up

and i'm going to bring up scrcpy

is my android phone running our flutter

so let's do as the caption says here i'm

going to make the screen a little bit

then go to your project uh or explorer

here visual studio core if you're using

android studio you can go go to the

navigator there as well there's a

similar one in android studio or if

you're using sublime that is exactly the

same thing here on the left hand side

you can see the project structure

then go to lib and then views as we have

the login view there let's create a view

called register view so right click here

and say new file and i'm going to say

okay so then we have to as the question

says go back to our main dart file and

grab this register view from here

group all the register view including

cut it in mac you do it with command x

and in windows and linux i think you do

um i cut that and i'm gonna then bring

as you saw in the previous chapter doing

these things usually cause a lot of

for your editor because i mean it's not

a headache for you because we can easily

fix it for us it's not a problem but

it's just the editor that doesn't

understand where all these classes are

located at so i i've explained this

the exact previous chapter before this

so i'm not going to explain it again so

let's say command dot in visual studio

code and then say import material to fix

all the stateful widget problems and all

the things that all the classes are

stored in material dart here in the

then we have other problems such as

command dot import firebase core to fix

that command dot import firebase options

it's that problem and we will also have

to import firebase off i believe and

that is also fixed all right so now we

have a register view here perfect

if you see here in our main dart now

there are lots of things that are

imported which aren't which aren't

so let's remove those you can see these

you may say okay well how do i find all

these problems like there's lots of

issues here but had i not come back to

the main dart file i wouldn't have seen

them and the way to fix that is to

problems view here and you'll see that

there are lots of problems stated that

you can go go and fix those you see

print statements are here and then

unused imports which you can which you

that's how you can use the problems

i'm going to do that by hand now remove

this and remove this so we have a clean

void main function here all right i'm

gonna do a hot restart just to make sure

everything's working as expected

then we have the login view here okay

so the next thing we need to do now is

as the notes i'm actually going to go to

my notes and make sure that i have

talked about the previous point

so the next thing we need to do is to

create a dedicated home page that does

the app initialization and depending on

whether the user is logged in or logged

out or if the user is verified or not

then it's going to display the correct

widget on the screen okay so

just to explain that a little bit more

is that i mean you i can say that

you see in your main function here that

when your application run you it runs

you're telling it to go to login view

why are we saying go to login view

why are we saying go to register view we

have no logic at the moment that says

are you logged in then show the login

view or if you're not like me and show

that's what we're going to do with our

home page okay so imagine the home page

kind of being the manager of the

different routes that your application

can manage so saying that oh if this

condition then do this if that condition

display the other screen so

we need a home page and conveniently

named is home page i mean lots of other

people may try to call it something else

but for now we're going to go with

homepage because it's just so easy to

a stateless widget stl and we're going

to call it home page okay and i'm gonna

press escape after that so now we have a

stateless widget called home page in our

what we need to do then after doing that

we need to go in our main dart file and

instead of saying login view let's just

say home page okay and if i press

command is remember this is not going to

take any effect immediately because hot

reload doesn't take into consideration

it changes the main function here so you

have to do a hot restart so you'll see

basically have some scaffold in our

homepage because we don't want to

display just an empty screen to the user

let's go in here for our container

instead say we return a scaffold

talked about scaffold in previous

chapters so i'm not going to explain

and let's go and create an app bar with

which we've also talked about

title accounts text and say home page

well command s in mac or control s in

linux and windows to save this file and

what do we need in the home page we said

that the home page needs to initialize

firebase it needs to first do that so

that we can get rid of this code in both

register view you see this code future

builder firebase initialize app and then

connection state done blah blah and also

we have the exact same code in our login

there's a lot of code to write in every

view that we're gonna develop though

this application isn't gonna have so

many views maybe six seven views but

still we don't wanna do initialize app

in every view and do a future builder

it's just a lot of code so that's what

so let's do that uh let's go and grab

let's grab this code with the future

builder pretty much maybe the entire

build function okay from our login view

so go to your login view grab the entire

build function until its end which is

here this parenthesis okay ending

close your login view close your

register view if you want to then go and

replace the entire override of widget

with that code that you just cut or

sorry copied from the login view paste

now we we don't want the home page to

have any logic that has anything to do

text fields this homepage is we're going

to use it for something a lot more noble

so you don't need all the text fields

all of these columns and uh your text

go to here where you're creating the

column in connection state done

and grab that code all the way from

return so if i fold it you'll see that

that is the entire return and i'm going

oops it didn't delete the entire code

okay so i'm going to do it by hand from

and instead of that column what we're

just like that so if firebase

initialization is done it's just gonna

say done and let's also change the text

here and just call it home all right

now that we've done that you can see we

still have some problems with firebase

not being imported because i deleted

imports previously so i'm gonna fix that

now command dot on firebase and say

import that and command dot on default

firebase options or control dot

depending on whether on your linux

whether if you're on linux or a mac or

windows import firebase options

all right so now you'll see we have a

homepage that just displays the word

once the connection state of our future

which is initialized app of firebase is

done is also displayed hot done

i'm gonna take that in my notes that

the next thing we need to do in this

to make sure that the user is not null

and that also the user is verified so

under some rare circumstances with

firebase such as when you haven't

initialized your firebase application

using initialize app the user that is

code or in the instance of firebits

running inside your application may

actually be null and we've talked about

null in uh previous chapters where we

talked about dart and it's basics so you

can go back to those chapters and watch

those so i'm not going to explain what

but just quickly null is simply said the

absence of a value in this case absence

what we need to do in our application is

the user the current user in the

um non-null meaning that it should be

present and also that the user's email

is it important for a user's email to be

i mean also before i say why is it

important for a user's email to be

verified maybe let's talk first about

what an email verification is and

that whether you've already seen it or

not so in a lot of services online if

for instance you go to a website

even if it's a shopping website or

amazon or whatever ebay if you say okay

i want to register a new user and you

say okay here's my email address here's

you will be logged into the website

they'll say okay if this email doesn't

i'm gonna allow you to register this but

then you wouldn't really be able to do

so much with the website you can search

stuff but you probably won't be able to

verified your email and that means that

as soon as you register for amazon for

instance then it will send you an email

to the email that that you chose upon

registration and there will usually be a

link in that email and say thank you for

registering a user at amazon or ebay

click on this link to verify your email

you've probably seen emails like that so

you could just go to your inbox and

search for verify and you'll probably

find lots of emails that ask you verify

your account with the service so um

now let's now that we talked about what

email verification is let's talk about

why it's important well let's say that

i'm a user and i want to use this

application that we're developing so i

want to score some notes in it

then i'll go and and register myself

under an email that i don't own

all right so let's say then i register

your email address with a password of my

choosing since you haven't registered

your email address yet with the service

icon and ahead of you and register your

email address with the service and now

remember i'm not logging into your email

i'm logging into this application with

now i've taken that email so if you then

who's the rightful owner of your email

address comes to this application and

say oh i'm a foobarbaz gmail.com and i

want to register an account with this

application and it says oops that email

address was already taken so you'd be

like how is that taken that's my email

that is the importance of email

verification what we need to do in our

application is to make sure that

whenever someone comes and registers a

user using the email address and a

password of their choosing then we're

gonna send a real email using firebase

to that email address and say

hey you just registered a user here make

sure that you click on this link that

says verify blah blah to actually verify

your user with our application or with

our file with our applications firebase

instance that sits on firebase cloud all

so what we need to do now is to go in

here in the connection state done you

let's then check the current user okay

let's see if this current user actually

is logged into the application so let's

firebase app i believe it's called

all right let's see if we can actually

google that together okay so this is

right base flutter get current user

we're probably going to end up on some

and we'll have a look at how we can

actually retrieve the current user as

you can see the response here is from a

dissu kurt jr i apologize if i'm

butching this name but you can see that

it's provided here for you that it says

and using that instance then you can get

the current user so let's do the same

thing here let's say firebase off

i'm gonna get rid of this screen on the

left which which is our project browser

and i'm gonna print this statement right

here before we return the done text okay

so i'll bring up the debug console clear

the debug console and i'm going to say

and since we've made a lot of changes

here you see we created a home page lots

of stuff in here so what we need to do

is just do a hot restart basically

flutter in this case wasn't able to

what we've changed in our home page so

there were so many changes that it just

couldn't handle so a hot restart is the

now you can see here as we printed the

i'm going to do this so you can see more

the output i'm going to bring it up a

little bit i'm going to increase the

size quite dramatically so you can see

i'm going to highlight the parts that

were actually printed so this is what

firebase or this is what the print

statement printed out for us and this is

user credentials that were created by

if you remember from the previous

chapter i said that make sure before you

come to this chapter that you have a

login user and this is the reason i

wanted us to i wanted the firebase

instance in our application to already

know that you're logged in so that when

we print your current user credentials

then as you can see it says here's the

and then there's a property called email

verified false and it says are you an

false and if you remember from one of

the earlier chapters when i talked about

an anonymous user is a user who hasn't

really logged into the application yet

firebase is intelligent enough to

understand that any user who comes to

your application who hasn't logged in

information isn't saved in keychain or

shared preferences on android then that

user is anonymous anonymous by default

um last action from the previous chapter

and you didn't log into the application

then you will actually be anonymous here

but since we've already done that we've

logged into the application then you'll

see our credentials being printed to the

now this is the part that i was

interested in which is email verified

so what we're going to do here is to say

take the user so we're saying a final

user is firebase off instance current

user i'm going to decrease the size a

and i'm gonna make the screen a little

bit bigger so you can see it better

and let's go then create an if statement

and let's say that we're gonna say what

what have i planned for it let's just

verified email verified then we're going

we're going to say print you need

you see here because i'm so glad that

actually we're seeing this error you can

how can i scroll here it says the

property email verify can't be

unconditionally accessed because the

receiver can be null try making the

access condition using question mark dot

or adding a null check to the target so

what this is saying is if you go to this

user move your mouse over it uh if i can

here you'll see that it says user is an

optional user so what firebase has done

this current user property that you can

see here is an optional user meaning

that well if something goes wrong and

firebase can't actually calculate your

for instance if you disable anonymous

users which you can actually do

then firebase will be said it will be

the user is absent i don't know who this

that is firebase api telling your

application that if you're using my api

then you need to handle this case you

can't just ask me if the email is

verified because the user may actually

be null the user may be absent so

there was a great suggestion here you

saw here that says you can conditionally

access that property using the question

syntax so let's do that question mark

done but as you do that you see you'll

you're asking me to compare an optional

an actual boolean because remember your

if conditions need to resolve in into a

um so in this case what you can do is

to either create something called for

instance if an intermediate variable you

and you'll say that is equal to user

optional access to email verified field

or false you see this is the question

mark question mark which we've already

talked about when we talked about dark

what you said here is take the left hand

side of this operator of question mark

question mark which is a null aware

operator you say if the left hand side

exists take it otherwise take the value

on the right okay so now if you move

your mouse over email verify you'll see

that it's a boolean all right

perfect so you could either do that or

get rid of this intermediate variable

that you created here and literally just

put the exact same code in your if

statement and that will work exactly as

it did up there so let's just go ahead

with that one less line of code

if the user's email verified or false is

which means that if the user's email

verification could be read as true or

false and if you can't use false if the

equation then in itself is true then the

otherwise the user isn't verified so

let's bring up our console i'm going to

change the screen layout a little bit so

and you can see here it says you need to

verify your email i actually clean the

screen a little bit and command s again

so you'll see a little bit less

information on screen and you can see

our print statement which was here got

printed saying that yeah you haven't

verified your email and you need to do

okay a lot of information but maybe less

than the other chapters and to be honest

with you this is all we have to talk

about in this chapter i just wanted to

or and show you that um or actually

explain first what email verification is

why is it important and that we're we

are going to use email verification in

our in our application as you'll soon

and how can you actually read that

property from a firebase user

that was all for this chapter now the

next chapter is going to be a little bit

different you may actually expect a

continuation of this chapter you would

think that we're going to jump right

into email verification but i have

intentionally actually put a little bit

flow because this is something you'll

have to do as a software developer

sometimes in that if you see something

kind of correct something isn't working

right then you'll need to address it as

soon as possible and this is something

we're going to address in the next

chapter the problem here that you may

may if you're a seasoned software

developer or may not have thought about

we are just writing code on our computer

this code could be easily deleted by a

malicious program a virus or if

something happens to our computer all

this could just go away and you'll lose

everything that you've written so if

you're not coming from a software

engineering background then you may not

i'm not going to scare you to be honest

with you this is not something scary but

what we need to do is just to make sure

that we have a backup of our code and

just that's just common sense like even

if you're a designer even if you're a

music producer even if you're a soft if

or product manager you probably know

that whatever you're working on needs to

be saved somewhere safely so if you have

a video file you're not just going to

put it on your computer you're probably

going to make a backup of it if you're

working with figma that that file is

already shared in the cloud is sorry not

shared it's already stored in the cloud

it's very rarely that you will work on

pieces of um documents that are not

securely stored in some sort of cloud

and even if you're working for instance

with a document then nowadays there's

also shared like um sorry there are

solutions for storing your documents

almost always when you're working on a

user generated document or a source code

in this case you'll need to make sure

that it's securely stored in the cloud

and that's what we're going to do in the

next chapter so we're going to talk

about git and github we're going to set

or pgp keys how do you want to say it

and we're actually going to dive a

little bit deep into git and what it

actually means and why it is why is it

good why do software developers talk a

lot about git and as you might know

not might you already know this course

but i couldn't help put this chapter in

because i believe if you're not a

software developer if you're coming from

then it is my duty kind of to tell you

about git and github and why is it

important how to use it how i like to do

very simple tasks with getting github so

so let's then prepare ourselves for the

next chapter which is going to be a

little bit less coding it's not really

we're not at all almost not at all going

to be working on the source code we're

mainly going to work with git and github

with that said i will wrap up this

chapter and i'll see you in the next one

hello and welcome to chapter 15 of this

in previous chapters we talked a lot

about setting up our project so we've so

far been working a lot with setting up

the project and the basics we also

created our login and registered views

in our flutter application as i was

developing this course myself i got to

the point that there was a lot of code

being written by me and then i needed to

in a in a place where i can always go

back to even if i lose this information

on my computer that i can go back to

that place and then retrieve that code

if you're a software developer if you're

if you're a seasoned software developer

from before and you know what git and

github are and you're comfortable using

them and you know how to set up for

instance your secure keys with gpg

then you can safely jump over this

chapter but if you're a designer product

owner product manager whoever who

doesn't know what git and github are or

maybe need some help setting those

then this is a good chapter for you

uh otherwise you can just skim quickly

let's talk quickly about what git and

github are and why we need them um as i

mentioned when you're working with your

code for instance as i was while

developing this course then you're

writing a lot of code which

is i mean intrinsically valuable because

your time was translated into those

pieces of code as you were writing the

code you spent some time and energy and

effort and wrote the code so it is quite

an important piece of information for

you just to lose and depending on the

type of project you're working on for

instance this project it has taken me

quite a lot of time to even develop the

idea of the project and put it together

so while i was while i was putting

together the idea of the course and

written writing all the bits and pieces

that i have to explain in every video i

made quite a lot of backups of that of

those ideas because had i not done that

and had i just put everything in just

one piece of paper or something or just

even one digital document on my computer

had i lost a document then well yeah

i would have lost it and i would have

had to begin from the absolute beginning

and this is the same thing for your code

so you need to use two services called

in in a safe place so that you can

so let's talk quickly about what is git

so what you need to know about gitz is

piece of software on your computer

various changes that you make to a code

base such as our project at different

times keeping track of the date those

changes were made the person who made

the changes and the changes themselves

and also it will be able to provide you

the difference between your recent

provided in the or what was already

committed into this git repository

well what a git repository really is is

is an empty bucket initially where there

is nothing in there and as you interact

with your source code then you'd be like

okay now i want to turn this source code

that i've written into a bucket so then

there's a bucket created around your

source code called a git repository

which keeps track of all the changes

that you're that you're making or

anybody else that works on the same

source code is making to the code and it

will allow you to save snapshots of

at specific times of your choosing

if you're a designer of your and you're

figma for instance figma already

automatically saves your work at the

times that it sees fit so you never have

to press really a save button and also

and it keeps track it has a version

history so you can literally go to figma

and say okay i've done my work i want to

actually commit my changes in the

version history and i want to give it a

most designers don't do that and they

legislate must save their work

automatically and by that figma just

says here's the timeline of your changes

at this time you did this at this time

even if you're a designer you're

implicitly using something called a

version control and which in it in that

but when you're coming to the software

development world we're working with

your flutter application there is no

figma there and you're working with raw

code so you're going into visual studio

code or sublime or whatever text editor

that you're using android studio

then there is no service sitting there

and saying oh you made some changes let

me let me help you save it in some sort

the system that allows you to do that on

your computer is called git so git is a

software that allows you to keep track

of changes that you're making to source

so i can see here that before we

continue we're gonna actually talk a

what i'm gonna do here i'm gonna add lib

a little bit here and improvise

and i'm gonna go here and make the

screen a little bit bigger i'm gonna

bring up terminal and you don't see it

on that screen because it opened on

let me just increase the size and bring

it up here so you also see it

so i'm gonna go here to my development

and i'm going to go to my projects and

make a folder i'm going to say git

should i call it git or just let's

actually create a folder called

let's go into testing then it is an

empty folder as you can see for now

and what we're going to do is we're

going to tell git now which is a

software installed on my computer um to

tell it that okay all of a sudden i want

to turn this empty directory here into

something called a repository remember

it's going to be a bucket then that

keeps track of changes in the current

directory now before we continue maybe

maybe you also need to actually install

git on your computer if you're not

coming from a software development

background you probably don't even have

git installed on your computer so i'm

a browser window here and say install

if i google install git you will see

that there there's like information

how you can install git on your computer

are on a macintosh and you have already

installed xcode xcode comes pre pre like

pre-packaged with gits already

if you're on windows i believe that you

actually have to i have a windows

machine right here next to me which i

use daily i believe for windows you'll

have to install git personally like

manual so let's say install git

uh get download package get a time get

oops my ipad for some reason got

disconnected here so i'm going to have

let's see now install git on linux

i believe there is a good package

actually for getting it on windows let

me go back here installer on windows you

just go to i'm going to increase the

screen size a little bit as well so you

can see it a little bit better

here it says go to https get scm com

download win so i'm going to go here

and it's going to start downloading so

i'm just going to say cancel because

right now i'm in a macintosh so here is

where you can download git and install

if you are on a windows machine and you

have the linux subsystem which i do on

my windows machine then you may actually

want to download git using see sudo apt

it is possible that the linux subsystem

on windows already comes shipped with

git so you don't have to do anything i

wouldn't be surprised if git was one of

the absolute core components that was

so that's for a macintosh and also if

you're on a macintosh and you don't have

then you may need to also download git

separately so let's go back here and see

uh if you say mac os here it says there

are several ways to install get on mac

users probably install the xcode command

line tools which we've already done so

if you don't have it in slavery it will

so otherwise you can go in here get

semcom download mac and then you can do

so if that is what you want to do then

you first have to actually install

go into this link and say homebrew

install basically just do as it says

here you see there's the command

and if you're on linux then a sudo apt

install git i think maybe you don't even

need to have sudo if you're installing

for the current user so just apt

app is it get or install i forgot but

yeah i mean i'm assuming you're kind of

like on a debian based distribution as

well but otherwise there's information

here how you can install it otherwise so

that was a lot of information and before

we continue i'm just going to try to

make sure that i'm connected back to my

to my laptop to my ipad here because on

my ipad i keep hold of all the

information that i have to provide to

you in some sort of like a chronological

order so it is very important for me to

actually get my notes up there so i'm

going to try to connect to my ipad and

now that you've i'm assuming that you've

installed git i'm assuming that that is

then it's going to tell me in this case

that user being get that's where get it

installed if you're on windows to be

honest with you i don't know the command

on windows to know whether it come like

git is installed but on windows all you

have to do is just to type git and if if

it throws an error it says git isn't

available either you haven't installed

git and if you have installed git maybe

git isn't in the current path so you'll

have to go and adjust your environment

variables in order to get git and

is lots of information on the internet

so we're not going to focus right now on

how to install git exactly because

that's going to be like its own course

but if you follow the instructions that

were provided on the website that i just

showed you should be able to get far

i'm assuming now git is is installed on

our computer and you can see here we're

in a folder called testing so if i say

where that testing is you can see that

is is right here now what we want to do

is to say testing for instance is the

project that we're gonna place all our

code in okay so there's gonna be

information that we're gonna write here

in this um in this folder there's gonna

be some dart files there's gonna be some

png and jpeg files there's gonna be our

application icon all that stuff

and we want to store this safely

the first thing you may want to do is to

to basically tell git that this current

directory in itself is a git's

repository so the bucket remember the

bucket is going to wrap itself around

if i get the contents of this directory

at the moment you can see that it's

completely empty but if you want to

create a git bucket or a git repository

around this directory all you have to

say is just to say git init dots

you'll see here now it says that

initialize amt git repository in this

so now if i get the contents of this

folder you'll see that there is a new

directory called dot git and dot git

directory is where git basically keeps

track of its internal like the changes

save when you save it who is it that

saved the work etc so now that you've

done that now you've created a git

repository basically around this empty

directory you can issue various diff git

this will give you the current status on

directory and you can see here as soon

as we created a git repository with git

in it all of a sudden my terminal

changed my prompt here and said that all

of a sudden testing is not just testing

anymore but it's actually a git

directory and we're on a branch called

i don't want to talk about branches

right now but just know that there are

yeah let's just not talk about branches

right now because i'm planning to do

so but what we are going to talk about

is this little message here that says no

in git whenever you're working um git

automatically you need to tell git to

save your work and those points where

you save your work there are call

commits it commits as its name indicates

is you committing your work you say i

committed to this and i want to save it

and that's i mean it could be called

read as kind of more like a verb like oh

am i gonna save it now or what is it but

if i say here's my commit then

it could be a little bit easier to infer

that oh it's a piece of information that

you've saved and you've committed to so

i think maybe that's the reason it's

called the committee i'm not sure

those commits are points of time where a

person that has access to this

repository saved their work okay so just

remember that that is a commit and if we

see here the status says no commits yet

because there was literally nothing that

you told get to save now what we're

going to do is to open up visual studio

code so i'm going to bring up you just

to studio code here and you can see it's

and i'm gonna create a file here and

info.txt so just text file okay

so here's an empty file and i'm just

gonna type hello in here increase the

size a little bit as well so you can see

now if i say git status here you can see

all of a sudden it doesn't say no

commits yet it it well basically it says

dad but it also says on track files and

it puts the info text right here now

let me then explain what attract file

and on track file is a track file is a

file that you've told git about before

so it it's tracking the changes being

on track file is a file that you have

not told yet before about so it says oh

here's a file you're doing something

with it but i'm not gonna even look at

it i'm not gonna keep track of it

because you don't you didn't tell me to

i mean yeah a file basically can be in

three states in git right now you've

learned two of them either tracked or on

track but it could also be in another

state that i will show you soon

now you can see there's a message here

that it says let me bring actually the

terminal a little bit up here so you can

see the terminal in its entirety it says

use git add and then the name of the

file in order to include what will be

committed so let's do that i'm just

going to say git add info txt

and now i'm going to say git status and

all of a sudden you'll see that get

understood that here's a new file you're

committing committing this file

called info text but you can see

that it still says you haven't committed

anything but it says changes to be

committed and all of a sudden this file

remember i said a file can be in three

states on tracked which means git

doesn't know about it tracked which

means it does know about it or it could

so if you see here this file is green

and it says changes to be committed so

you have made changes to a file

and you've told git that you want to

commit it but you haven't committed it

now you may be asking okay why would i

have files that aren't going to be

committed in some projects if you have

some information for instance if you're

working with 10 other developers

tests and you're writing some code in

the in the directory where your source

code is placed at but you don't you're

not really ready with that file yet you

don't want to commit it into a branch

where everyone else sees then you could

say oh i'm not going to commit this it

is not staged file i'm not even ready

for staging it and putting it into the

commit so in that case you're not going

to add it to the staging area okay so

now that you've you've done that you

just said git add you can commit it and

a commit literally means that you're

going to save this work in git okay

and the way to do that is using git

and then you will provide a message

using dash m here and then quotation

marks okay so here you will write a

message that will be appended to your

so what we're going to do here says

add new info txt file for fun okay and

then i'm just going to press enter

and see here it says one file change and

one insertions and it will say that yeah

it has created this file okay so i'm

gonna clear my uh terminal now and we're

all of a sudden that message that about

no commits yet disappeared and all this

is is that is that you're on a branch

called main and there's nothing to

what do you do then if you want to see

the commit that you just made like if

you want to see okay what are all the

comments that were made then in that

all the all the commits that were made

and who they were made by and you will

also be able to see the date that were

made and the commit message do you

remember we said git commit dash m so

that was the message provided in the get

command and then saved in the repository

that is the message and that's the email

of the person who basically did that

now i jumped over a little bit here and

and to be honest with you that was

i didn't really think about that some

people if you're installing git

then you're not going to have all this

information already set up like who you

and there's information about how you

configured it and how you tell get who

and what your name is etc and that is

using a command called git config

but you could actually read about read

about that online so just say git config

and then you will get a lot of

information about how to do that so but

just know that git is such a big world

that if i want to explain everything

about git we could have a course that is

30 hours just talking about git so

just know that there's constraints for

on me to explain like the absolute

basics of get to you in order for us to

be able to use git in this course for

this particular use case so i'm gonna

just focus on those things okay so

um now that you know how to commit i

place to start learning more about git

and the thing you may want to know so

which we're not going to use in our in

is branch using git and why you'll need

is a piece of software that allows

groups of people work on the same piece

of code without losing their changes now

if you're for instance from a design

background if you're working with figma

if i go into the design file that you

you've shared with me as an observer i

cannot make any changes so i can only

observe you and i can just like export

assets uh or even if you're using um a

it's the same thing you can so someone

some designer sitting with sketch for

instance and then they're exporting the

work into zeppelin and then you as an

you're exporting that information from

but you can't make any changes to the

source however with git when you share

your information for like your git

repository with someone else they can

also make commits to it as you'll see

soon we're going to use github for that

make sure that every person is

identified correctly and then they have

that they have configured get in the

i mean we're talking about branches so

don't want to affect what you are doing

in this main branch so just imagine and

train line like your train is going

and maybe some some places your friends

want to visit a town in the city that

you hadn't planned so they get off the

train they go on another train line and

at the end you will meet so at that

point you can see that they branched out

into their own branch and that is like

the concept of branches in git as well

so sometimes when you're working with

other developers they may want to branch

out into their own branches on the same

source code do some experiments and once

they figure out what they actually

wanted to do maybe they will save their

own work into that branch and then they

will bring it back to your branch at the

end you will meet at the train station

and then they bring the results with

them and then you merge together so

there's a lot of information about

branches how they work in kit but just

branches are kind of like train lines

and right now you're on the main train

going from your city to the destination

um but again there's time constraints on

this course i can't explain everything

about git but if you're interested

there's lots of great content available

on youtube that you can watch and i'm

pretty sure that there's lots and lots

of tutorials online as well that you can

wow that was a lot of information okay

let's now talk about what github is

github is simply said a cloud service

for storing your git repositories so

right now this git repository is sitting

on my computer so even if if it is i'm

committing my work i'm saving my work

no uh traceability from the outside

world so no one else is allowed to see

this code right now it's sitting right

on my computer and for that if i want to

share this code with other people and

potentially allow them not to read only

but also to be able to commit and

collaborate with me in the source code

then i would be able to share that on a

cloud service such as github

has the word git in its name but it's

not the same thing as git so git is a

software that actually manages all your

commands and etc but github is the cloud

service that holds on these repositories

if you don't have a github account i'm

going to help you do that right now

let me close actually no i'm not going

to close i'm going to minimize this

yeah let's close this one i don't think

so i'm gonna bring up a window here

what we need here is that for you to

create a github account and to do that

this website that i will provide for you

right there github.com sign up okay

so i'm gonna if i bring up um

a browsing window here and say sign up

you will see that yeah it won't know

that i'm signed in already with my other

account and it will ask me to start

so this is like the main window for the

sign up of github and this they've done

it a little bit comically it kind of

like a star wars kind of theme i don't

know what you want to call it but

here you will go through a few steps in

order to create a github account okay

i'm not going to do that simply because

but in your case we'll just need to go

through this provide your email choose a

good secure password for your email for

your github account and then at the end

you will have a simple github account

we've talked about already setting up

git in the terminal so i'm not gonna

talk about that i'm just gonna maybe

um a little bit up all right

now after you've set up github on your

uh basically after you set up a github

you will need to set up something called

this is a little bit technical but

and it is nothing that you can jump over

it's not like you can actually commit

your work without setting up ssh keys on

your computer you can always go to

github and actually commit your work

right on github itself like you can

text right in the github interface like

then they will do all of that work for

you because they will commit it from

kind of like their key their own ssh

keys i believe but if you on your

computer want to be able to commit your

hard disk or your ssc or whatever into

github you will need something called

yeah cryptographically i don't know

yeah cryptographically signed

these are cryptographically signed

just kind of like private keys that we

worked with when we worked with keychain

in one of the previous chapters

they allow you to identify yourself as a

uh i apologize again for the hiccup of

cryptographically it's just because i'm

not a native english speaker so you

should be expecting these hiccups

an ssh key is a piece of key that is a

signature that you as a developer or a

committer of code create on your

and whenever you make a commit and you

person xyz and you're trying to push

your changes into this repository i'm

just gonna make sure you have access to

so you need your ssh key set up

what we need to do is to go to github

and i'm going to bring up a web browser

for you to understand how to set up your

ssh keys so let's say github sets up ssh

and you can see adding a new ssh key to

your github account so there is a very

very comprehensive guide here on how to

set up your ssh keys so you can see that

generating a new ssh key and adding it

to the ssh agent so this is where you

so after searching for github as a setup

ssh keys make sure that you at the end

go to this link generating a new ssh key

and adding it to the ssh ssh agent

read through this there is very

comprehensive guide there are only a few

commands that you have to issue in the

do them precisely as as it is specified

so after you've done that then what

to add that ssh key i believe into your

github account you see as the link

provides here adding a new ssh key to

you can see here then it says okay do

this command and then go to your github

account settings and then go to search

and gpg keys and then say new ssh key

and then add that information in here

and that's it then you have your ssh key

all set up and done so these are the two

things you'll need to do create an ssh

key and then upload the public key into

and again because of constraints on this

like line by line to i'm just providing

you the information that you need to

know and i kind of expect you to do

these things on your own okay

we also need to talk about um

and let's actually i think gpg was new

so is a piece of software that you

download on your computer you can see is

a free software replacement for

semantics pgp cryptographic software

uh it is compliant with rfc blah blah

all you need to know about gpg and how

we're going to use it in this course is

have your i mean we talked about ssh

keys where you have your ssh keys and

then you and i know this is a little bit

geeky but that's kind of like the nature

sign your commits with your ssh key with

your private key and then you push your

changes to github and github just

this commit is coming from someone who

has access to this repository

gpg keys and then you sign your commits

then that actually verifies that you are

who you say you are so a lot of software

developers are still continuing with ssh

keys and to be honest with you that's

well it it depends kind of on your

opinion but in my opinion is not good

enough because anybody getting a hold of

your ssh keys can literally just do

anything they want with your commits and

change anything they want but um

with the gpg keys you'll ensure that you

are who you are and anyone else even if

they have hold of like your ssh keys

their their commits won't be signed as

so let's now talk a little bit and we're

going to take some items here and just

make sure that we've talked about them

now we're going to talk about gpgm where

you actually need it so there's a little

i'm going to open that link here so we

can both see it and it says git is

still i this word is a little bit

different different for me to say

cryptographically secure but it's not

foolproof if you're taking work from

others on the internet and want to

verify that commits are actually from a

trusted source git has a few ways to

sign and verify work using gpg okay

so what you'll need to do is uh you need

to set up jpg basically on your computer

um if you just say gpg install mac or

gpg install windows or whatever then you

can come to for instance for i'm using

and for you can actually install gpg for

various operating systems for instance

windows or linux so just google gpg and

then your operating system is so for

gpg and download noon pg here and you

see so this is like the download tools

windows i believe let's see

and you can see here you could use

full featured windows version of you

all i'm trying to say is just to

download the piece of software called

gpg for your operating system so whether

gpg tools for mac os or if it's like for

canoe pc is part of debian okay so it's

already maybe built in so you don't have

your debian based linux operating

so after doing that then you will need

set up gpg for github and i'll provide a

link here for you that you can

read about says managing commit

and the link i'll open it here

so you can see how it looks like

generating a gpg key so you can first go

there and it will help you through the

various steps that you need to take in

order to create your gpg keys it's very

easy it's just a few lines of uh

code or a few lines of text that you

have to issue in your terminal in order

so after you've done that and

you need to make sure to go into this

section add a new gpg key we've done

and then you go here to your settings

you can see ssh and gpg keys and then

the same way you added your ssh keys

you'll need to add the gpg key in your

and after you've done that the

difference between sshk and a gpg key is

kind of like to you need to tell get

that you have a gpg key and then it

needs to sign your commits with your gpg

and that's where you go into this tell

get your assigning key and you need to

just follow these steps to tell get

git config global user signing key you

so just follow these steps to be honest

with you i don't think you need to

associate email with gpg really right

now but if you want to you can do that

so i'm kind of like assuming that you've

for your computer and that you've

created the ssh key you kind of know a

little bit about git you have a github

account now you have created your pgp

keys and then you have told git about

your pdp key so your signature comments

so the next thing we need to do is to

now can you see we've been working on

notes application my notes i think it

the project was called my notes here

if i say git status here you will see

that it says not a git repository and

that's kind of a little bit sad because

we've written quite a lot of code but we

haven't really backed it up in github

what we need to do now is to go and

create a github repository remember that

bucket we need to create one of those

so let's go i'm going to create a safari

firefox whatever you want to use and i'm

and i'm going to go into repositories

here as you can see and i'm going to say

and i'm going to give it the name my

notes all right i'm going to increase

the size of the window so you see it

better for the description i'm going to

say my notes flutter application

and you can see here that tells you it

asks you if you want to create a public

public repository or a private

repository and the difference here is

that if you create a public repository

the content that you're creating

if if you're if you're not 100 sure what

public means create a private repository

usually there's lots of information that

you may want to create like a private

information with some api keys

so you want to probably create a private

repository unless you know exactly what

you're doing or if you want to for

contribute to open source projects and

create an open source project from an

absolute beginning then you go and

create a public but you can always make

your private repository public later

and you can always make your public

repository private later but that

it's probably a good idea to create a pr

private in the beginning okay

then in here add a readme file a readme

file is pretty much just a file that

will be displayed to whoever goes to

your github repository and looks at just

the index file of the github repository

so you can place some information in

there but it's usually a good idea to do

that you don't have to but i suggest

that you actually do that and then say

and then say add git ignore and we

haven't talked about git ignore before

but what get ignore is that its name

indicates is a file that dictates to get

or on the computer of whoever has cloned

your repository about what files should

not be committed to your git repository

usually it's a good idea to have a get

ignore file and in here for the template

and in here you don't have to choose

license right now because you're

probably not going to share this code

with anybody as it is right now but you

can always add a license later okay

i created a private repository some name

uh which is my notes sorry yeah um

i actually feel no for the name of the

repository i'm going to change it just

to lower in case i have no space it's

and then i'm going to say create

so as you've done that now you will see

that you have a repository here

i mean there's nothing really in it okay

what we need to do now is to you see we

our code here and then we have a

repository how do we put this code in

there you may think okay i'm going to

upload all the files by hand or like go

you could kind of actually do that but

and so what you need to do is just tell

git now all of a sudden that hey

folder here is indeed a git repository

remember from what i said before so you

i'm going to bring up the caption so you

know what i'm talking about git init and

then you say good and it dot okay all of

a sudden this became a repository so if

let me see if i can actually change the

arrangement on the screen so you'll see

and perhaps i could even do something

is that a better idea than just doing

no probably not so this is better

uh okay this is a little bit better so

you see now it says now that you're a

git repository i can see you have a lot

of files that you haven't really

committed and what we could do then we

add all these files and folders to my

git repository and then i'm going to say

with the m as a message my initial

see now if i say git status it says

i want to kind of push these changes i

want to send these changes together but

how do i do that because if i say git

see it says oh i don't know where to

what you need to do now is to go to your

github repository and then go to code

and then grab this guy from here

and then copy this and then go in here

and do what it says here git remote ad

so i'm going to say git remote add

origin it's the name of our remote for

instance and now i'm going to add that

it says okay now that you've done that

you still need to tell me that this main

branch which is on your local computer

is actually mapping to the main branch

on github which is right here

so you see here's the main branch and

we're also on the main branch so

you don't have to do this complicated

code you could actually say git push you

origin head which to me is a little bit

and that will do the same thing for you

updates were rejected because the remote

contains work that you do not have

locally this is usually because it's

actually great that we got this

i had a plan for this to happen but what

is happening here is that you see if i

i can click on this initial commit here

you will see that when i created the

repository and we chose all those you

and the git ignore file these are files

that are literally created on github

using github by github and placed inside

this repository so that is a commit you

that commit is sitting there in that

bucket over here so there's a commit in

its own bucket okay now we have our own

computer here with its own bucket

and its own commit but all of a sudden

we're telling this using that git add

what we're doing is that we're we're

making a connection between this local

repository and the server repository and

saying that any changes have happened

here we want to push them over here and

these changes are rejected because it

says oh you're you have changes here

and commits and you're putting them in

your changes your repository here didn't

contain the changes that were already

there so it's saying that there's a

conflict i don't know what you're trying

to do are you trying to like replace the

contents that were over there with your

and to be honest with you that could

you see what we did here we have a git

ignore file here that was created for us

by github and also we have our readme

file which we probably actually don't

need to be honest with you maybe we

don't need that and also they get

ignored but if you looked at the changes

that were committed committing here if i

you will see there already is a file

which was created by flutter when we

created our project flutter already

and with ignore to see its contents and

you'll see there's lots of stuff that

fluffer has already created for us that

says these things need to be ignored so

what i'm trying to say is that all these

things that exist over here we don't

need them really so what you could do is

and i believe that force pushes a bit

so i'm going to clear that now and i'm

going to go to my notes repository and

and oh we already had a readme file as

well so flutter has created a readme

file that's that's amazing i didn't know

this so i learned something that's

all right there we go so now we have our

i'm gonna just take some items here that

so that is already done as well pushing

so now you have your changes over there

now what we need to talk about is also

in this course i'm going to use a

a tag is just as its name indicates it

so as you're as you become better and

better at software development you'll

understand that some places sometimes

during your journey as a software

developer the code that you wrote means

a special thing to you for instance you

after a whole weekend of work i could

finally deliver like the verification

screen to my users and that in itself in

its essence essence has a special

importance is it has a special meaning

and you may want to tag it and by

tagging it it means that i'm just going

to give a special name to this so in the

future if i want to go back to that

point in time i don't go i don't have to

go into my be it log and look at all my

commits and see which one was that

special commit but i also want to like

give it a special name okay and that

name is a an annotated tag or a tag that

has a message applied to it all right

that is in its essence what tagging is

so you're giving a name to your um

so what we need to do now here is to tag

our work as step one we've done a lot of

steps up to this point but none of them

like important that we actually have to

commit yet but i think this is important

enough now we have a registry screen and

a login screen so that we can tag it so

the way to create it to create an

annotated tag and git you will literally

let's go in here and say git tag and

give it the name of step one

all right now you can see if i want to

push these tags to the back end sorry to

github because those tags don't exist

what we could do is to say git push tags

dash tags and this pushes all those tags

which is github in that case

and to be honest with you i don't really

know here one tag i can see all of a

tags and step one is created there okay

so what we could do also is that's after

we have our gpg keys all set up we also

can confirm that our work is truly

and if i go to my notes here and then

let's see if you can see that

somewhere here can we see all our

oh it's not showing me that information

yeah but anyways you could you could

have a look at whether your commits are

signed by a little badge which i can't

see right now so maybe there's actually

something wrong with my pgp key so if

you've done all the pgp installation

correctly on our computer then you

should see all your commits being signed

and actually displayed here but with

some sort of a badge but i can't

unfortunately see that maybe github has

changed that interface so that we can't

see our verified and badge for our jpg

all right we talked a lot about

um so i think that's actually quite

enough for this chapter and git we've

talked almost 15 minutes about get to be

honest with you and that's sufficient

now that we've got get set up what we're

going to use it for in the upcoming

chapters is whenever we do something

significant that needs to be saved we

are going to commit that change and also

tag it and send both our commits and our

to github so that is stored securely in

some sort of a cloud storage basically

that's how we're going to use git and

and i thought of it as so important for

every software developer to know that i

thought if anybody is watching this

course who is not a software engineer in

then you definitely need to know about

git and github before you can continue

so what we're going to do in the next

chapter then is to talk about email

verification we've done login register

screen is very simple but we haven't

done the email verification yet and

that's exactly what we're going to do in

the next chapter so i'll see you there

hello and welcome to chapter 16 of the

in the previous chapters we've talked

about the login and registration page

and also we took a little detour to talk

so now you should have all those things

set up so you should also have some sort

of an emulator simulator or real device

setup so we're testing our application

right from visual studio code or android

studio or sublime whatever text everyone

um in this chapter we're going to as the

caption says here we're going to talk

one of the previous chapters why we need

but the main reason for that is as you

can see in the caption here says people

can sign up with emails they don't own

and that is a little bit of a problem

is a problem is that you might

get into a situation actually i can see

here my wi-fi is kind of tripping

okay it's connected now sorry about that

what could happen is if a user comes in

to the application and starts your

flutter application on their phone or

tablet and then they sign up with an

email that they don't own and then i as

the rightful owner of that email address

come to and download the same

application and try to register my email

and the applications as well this email

um so we have a problem here so what we

need to make sure is that the p people

who register in an email can also verify

that they own that email address okay

so let's take care of that in this

gonna bring up visual studio code or you

editor of your choice where you're um

the editor that you're comfortable with

and i'm just gonna take in my notes that

so what we're gonna do here as the first

step is to go to our main dart file here

right after home page and create a state

i'm going to do that right now so

then we're going to call let me see

and in here uh what we're gonna do

is just to return a simple scaffold so

i'm just gonna say return scaffold for

now we're gonna get a cons error here so

um that's for our stateful widget

then what we're gonna do is um

we are as you can see here as soon as we

see that um the email isn't verified

here we just say you are sorry that it

is verified we say you are a verified

user and if you're not verified we just

say you need to verify your email first

but in both cases what we're doing is

that we're just returning a text widget

that says done and it's displayed here

in here we're going to say return this

otherwise what we need to do is to

display this verify email view okay

the way we need to do this right now and

we're actually going to fix this quite a

lot as we go on but right now i just

want to show you how to push a view into

the screen now pushing is a concept that

like a widespread existence after ios

and android became popular in the early

and pushing is where you have a screen

and you're seeing that screen and then

you press a button or something and

another screen just kind of pushes

itself on top of the existing screen

so what we need to do now is to

if we see that well you haven't

verified your email you want to push

this verify email view and a way to do

is with something called a navigator and

remember this is a little bit

problematic the thing that we're gonna

do right now is actually gonna cause an

error and i will explain all this but

for now let's just go go ahead and do

this so we will fix things as we go on

right here that where we say you need to

verify your email first and we can

actually see that in the console um

here um oh you can't see it because it's

the caption but you can see now it says

you need to verify your email first

verify email view onto the screen what

i'm going to do i'm going to get rid of

what should i do here should i go back

to the same layout so you can see yeah

that's probably better so go in here and

then you say your build context and then

now push is the function that you're

you can see here it acts it says okay

and then you say material routes here

okay and then there's a builder function

like this i will explain all of this

soon to you and then in here say verify

there's something wrong with all this

let's see builder and then we're doing

that and then one parenthesis i think is

and it needs to be ruined and what is

the actual error that's being displayed

the return time future dynamic isn't a

and uh what we need to do is just to do

and yeah that's fine so let's bring this

return done back to where it was and

then we remove this print statement from

here as well and this print statement

from there and make this cons and i'm

gonna explain all of this so don't worry

what is happening here is as you can see

sorry about that my throat isn't really

you see in our future builder here

we are expected in the builder function

which we are right now in here you see

we're always expected to return a widget

so that's what the future builder does

that performs a feature and once that

future is done or it errors out or

then it calls this builder function and

in the builder function it is expected

to return that builder function itself

is expected to return a widget

something to display on the screen okay

now your job as a developer who's using

the future builder is to actually return

a widget in this builder function and

that's why we're doing here what we're

doing here we're saying if the

connection state if the future is done

otherwise return this text so we have

fulfilled the contractual um

builder expects a widget we return a

widget however we're trying to be clever

here in saying that okay we do return

done but also we're performing an action

which is navigator of this context which

is our build context and we haven't

talked about build context so much

before but you can actually see

i mean the documentation isn't so clear

maybe it says this class presents a set

of methods that can be used from build

but anyways what a build context is is

kind of like a packaged bit of

information that you can you can use in

order to pass data from one widget to

the other and it is very useful for for

instance if you're using block and we

haven't talked about block yet but just

know the build context is kind of like a

bit of information about the context

so in here what we're saying we're

saying create a navigator of this

context and navigator is just a class

for you okay and then when you tell

navigator to push something it says okay

what do you want me to push on the

screen then we say create a material

and you can see that material page route

has an argument called builder which

in itself expects a widget okay so you

in this build function but all we're

doing here to be honest with you it's

just saying that push a widget on the

screen that's all so this is like the

format that you need to learn about okay

navigator of the context push material

page route builder context and then you

all right that was a lot of information

i mean this looks kind of okay at the

however there is a problem with it and

if you're not careful you can miss that

problem and i really always like to

debug console so that i'm aware of all

problems that might happen and the

problem that you can see on the screen

on handle exception package flutter

widgets navigator dart failed assertion

there is actually a github issue for

that i can see i've actually linked it

there as well but we're going to come to

that but just be aware that what we are

doing here is not really good

it's not a good idea to push something

inside a future builder but we're going

to do it anyways just so we can fix it

later so that you know at least this

issue exists and at the same time we

achieve what we're trying to do here

which is displaying a new widget

once a condition is met in this case the

user's email is not verified okay

what we need to do now is fix this up

i'm gonna just take some items in my

it it's it's a completely wide scaffold

it doesn't even have an app bar there's

nothing in there so what we can do is

just to first of all go and create an

app bar here so we say app bar

we've done this before so you should

know already the syntax and then the

title is just gonna say verify

and i can see appbar title is text i

don't even know what i've done wrong

here to be honest with the constraint

isn't the cons instructor it just means

that well okay i have to remove this

and i have to make this text const

i'm i'm like moving past these things

but you may be a little bit confused if

you're not if you haven't done this

before you may be confused what i'm

doing here let's maybe i should explain

actually this what is happening here you

before we started using the app bar in

scaffold everything was completely fine

dart was completely okay and i said okay

i'm gonna accept this as it is what

we're telling dart here is that we're

creating a scaffold and it is a constant

scaffold it means it is we're not

actually doing any special configuration

that makes this not a constant okay but

that's so let's actually go here i'm

going to hold down command on my

macintosh you can hold down control your

linux machine or windows and click on

and you can see that the initializer

that i'm calling here or the constructor

that i'm calling here is marked as const

but as soon as we put app bar in here

and i'm going to click on the same thing

if we can find that initializer

scaffold app bar this app bar i can't

really seem to find that particular

essentially here is saying that

what you're trying to do here which is

creating an app bar with a text inside

here a text widget and an app bar makes

this scaffold widget not a constant

the first thing you need to do is say

okay i understand that that's not a

constant anymore remove this constant on

scaffold but then you get an error here

well a problem telling that okay you've

removed the comms from scaffold but

still you could make your code better by

making your text a constant because this

text scene text widget seems to be a

constant all right so i'm going to make

so i'm going to press command s here

is not true and i'm going to hot restart

verify email okay and i can see we have

again we have a problem with hot reload

because as soon as we do hot reload then

we get this error but this error is

simply because of something weird that

we're doing in here so if you get error

just do hot restart and you should be

good to go until we fix this problem

all right so as you can see in the

caption of this chapter what we need to

do here is to display a column text and

a text button to send the verification

email so let's go to the body of our

scaffold so i'm just going to say body

children and inside the children

let's just go and say we have a text and

and that's that and then what we're

gonna do in here we're gonna place a

and perhaps what could be better

if i scroll this a little bit up so you

can see the code in its entirety

then the text button if you remember

from the previous chapters it has two

very important and required parameters

analysis tools or flutters analysis

the child parameter of those widgets or

those functions that do accept the child

is preferred to always be the last

parameter so go ahead and create the

unpressed first and then go ahead ahead

and create the child so in the child

and make this text content so dark is

happy about that and make this constant

and don't forget the comma here then hot

reload so we can see the results

okay so now we have some text in there

and then we have a button here that says

okay i'm going to take it in my notes

that i've talked about that so we don't

now what we need to do here is upon

we actually need to send an email

verification to the current user okay so

what we need is the current user so that

login view and register view we have you

see login views or credentials firebase

um let's see actually we got the user

right here firebase initialize app and

then we were like fire yeah that's how

you get your current user firebase auth

instance current user okay so i'm going

to copy that information from our

home page okay and bring it into your

verify email view state in the button

now what we need to do is as the caption

says here we need to await on the user

send email verification so say await

user send email verification okay so now

you can see this is a function

and it says it can't be unconditionally

invoked and that is because user can be

and it is an optional user so as you've

understood from the previous chapters

access this function now be a little bit

careful here because this function is a

future you see it's a future void so as

you know calling a function that returns

a future void does not invoke the future

except it only tells the function to

return the future okay so if you

actually want the future to be executed

you need to wait on it so if you then

you'll see we get an error telling that

yeah you can't do asynchronous call

scope that you're at and that is simply

because the unpressed function is not

marked as asynchronous okay so remember

um i'm gonna press command s here we get

the error i'm gonna do this hot restart

uh if i'm not mistaken i mean if i bring

a browser up let's see if i can bring a

browser window here and i'm going to say

and let's go to our mynotes flatter

project and let's go and have a look at

our authentication i can see that

pixelityab.gmail.com for you it's

probably gonna say something else

hopefully it's gonna say something else

so that you haven't registered with my

and what we need to do then is to simply

go here and press the send email

so nothing happened on the screen

i'm going to bring up the right caption

here so you know what we're talking

about now we want to kind of look at how

this email actually looks like

so let's see if i can bring up that

other emails and other users because

that's kind of like private information

all right so uh let's go ahead and see

i'm gonna then bring up this email on

the screen so you can see how it looks

that email address you can see here

that's my email address or this is the

user that is logged in into our

application then received an email from

firebase which is no reply at

mynotesflusterproject.firebaseapp.com

and it says okay you need to click on

this link in order to verify your user

i'm just going to take in my actions in

my notes here that i've talked about

and let's then click on this link to

verify our identity and here it says

your email has been verified you cannot

sign in with your new account great okay

so i'm going to close that taking in my

notes that i've talked about it

um and what we can do here then is just

refresh here and there's nothing really

different about this user as you can see

we're also looking at that user and you

can't really i mean at the moment i

can't personally see if this user is

maybe that's something that firebase is

going to provide in the future just like

a checkbox or something saying or like a

yeah just like a check icon saying

whether this user is verified or not but

you can't see that at the moment in

firebase console at least i can't

all right a lot of information now let's

talk about this error that we got on the

and i've provided a little link here

which i'm going to click on on a

separate screen and then bring it bring

it up here on the screen that you can

now if you remember where we pushed this

using navigator and then material page

and where is it material page right here

then we got this error on handle

exception okay and then there's an issue

github repository so as you know flutter

is an open source project and

is an organization here on github and

pretty much everything that they're

doing for flutter is under that

organization on github so as you can see

here it says how to call navigator push

in future builder error log and then

there's lots of great discussions about

what should be done and etc but

just know that for now what you need to

know is that you cannot do that without

having that error although although

on the screen but as you saw as soon as

hot reload and then you will have this

error also so there is an exception

after you've looked at that uh

github issue and you've gone through the

comments you'll understand that that's

not the way to do things in flutter at

and um i'm actually gonna take it in my

notes so if you see me looking here i'm

just making sure that i'm explaining

so what we need to do now is to go and

our verify email view is created so

you see here what we're doing is that

we're in our verify email view what

we're returning we're returning an

entire scaffold and that is why we're

trying to push this screen on our

current home home page because we're

saying that here's the home page and

then there this is the verify email view

and it has a scaffold just like the home

page does do you remember if you go up

to our homepage homepage also has a

scaffold and an app bar so what we're

pretty much saying right now is that

this is the home page and we kind of

need to move another page on top of it

which pretty much has the same structure

and that is causing the problem because

we're pushing something in future

builder and we're not allowed to do that

in order to fix this problem just for

we go and remove the scaffold and in our

build function all we're gonna do is

just to return the column okay so go on

and what we're gonna do is we're just

gonna say uh let's see if we have a

remove functionality here and we don't

i'm just going to grab this column

and i'm going to bring it a little bit

up so you can see i'm going to put a

hot hot reload so we don't see the ugly

and without the comma at the end grab

that column and in the build function

just return that okay instead of your

scaffold and a semicolon at the end all

so that's what we're gonna do now

for now we're just gonna return column

there and then what we need to do

let me see actually that's what we're

gonna do now or is it something that

we've now changed verify email view and

that returns a column now let's go in

here you see in here when we see that

the user isn't verified uh what we need

to do then is to say navigator instead

of navigator of we're gonna just return

our verify email view in here okay so

let me go in here and just say return

otherwise do that so i'm going to press

let's go and see what is happening here

if user instance current if user email

verified then return done otherwise

what's happening to be honest with you

previously where we were pushing an

entire screen on the current screen now

what we're doing is saying that here is

a screen already put this verify emails

that returns that is returned from the

build function right inside this current

screen's content okay so it's a little

bit of a difference instead of pushing a

whole new screen we're putting that new

screen's contents in our screen all

okay and now we have this and i see now

our app still thinks that we're not

verified but what we could do is just to

make sure you can see here that

um at least we're not getting that ugly

error anymore so if i do a hot restart

i can see this email verification and

that's a little bit strange to be honest

with you because we did verify our user

so what i'm going to do is just to

ensure that this this phone right now

and it does so that user should have

and i think we actually did click on the

verification email so let me go back

and what we could do is just to stop the

application from running and then press

run without debugging and just to ensure

that everything is set up correctly

so if everything is working fine then we

verify email view instead we should go

we should display the done text to the

let's just let's just ensure that that

is working as expected before we

i can still see this and we could simply

poor man debugging in here and just

prints the user email like that prints

user to the screen command s okay

and let's go in here i can see email

verified is still false is anonymous

last signing time so it still thinks

that i'm not verified so what i'm going

to do is i'm going to send an email

and i'm just going to go to my mail here

and let's just i'm going to bring up

and let me just ensure that

and it says your email has been verified

then let's close this and i'm gonna do a

and to be honest with you i can still

see now that we're not verified so

flutter email verified not working

let's see if there's something that

uh firebase auth current user and then

user null is email verified and i

believe that is what we're doing here it

this is not hopefully a future is

in here we're initializing the

application so that that should work

and then we're getting the user and then

email verified that should also work so

one thing to implement is email verified

and initiate function imperiality can be

ideal approach to easy for verification

with firebase well that's not really

and it could simply be that we need to

just try to log in with that user so

that it tries to contact firebase again

what i'm gonna do here is to as we have

planned here let's go and change both

the login view and the register view as

well so that they don't return

an entire scaffold but instead we're

gonna make sure that they only return

okay as you can see i put in the caption

here that they shouldn't for now return

so that's going to be done in the home

and i can see i have a little bit of

now return a scaffold that's the

job of home page so i just fixed our

little caption there as well let's go to

login view and i'm gonna go here

and let's go to your login view here you

can see we have firebase initialize app

future builder we have all that logic

also in both login view and registering

we shouldn't be doing that so i'm gonna

grab this return column all the way from

go to all the way where the return

grab that then i'm gonna pretty much

build function and instead return the

column okay so that's our login view

unused imports i'm going to remove them

for now as well do the same thing for

go to your build function in the

needs to be removed except for the

actual content which is the column

grab the column as you can see here

nuke the entire build function

and just return your call all right

fix this email verification issue

perhaps what we need to do here

turn just comment out all the codes so

when the initialization of firebase is

done just return your login view so

okay as a constant so i'm just gonna

press command s and then we come here

and i'm going to enter pixelityab

and if you remember from login view if

we had this beautiful little thing that

printed the user credentials to the

that is saved already and i've saved

so let's go and enter that information

pixel tab at gmail.com and then through

and let me bring up the debug console

and kind of change the screen layout so

so you see it a little bit better as

well i'm going to clear the console

and i'm going to press the login button

here now we have the user credential you

can see it's printed to the screen

and now email verified is set to true so

when there's email verification sent

as you as a user i mean there's

something for me to learn as well so

i'm actually grateful that i'm learning

one once what happened here is that we

verified an email and that email

we clicked on the link but firebase

doesn't immediately understand that

as a user have verified your email now

so what you need to do you need to ask

the user to log in and upon that point

it seems like firebase is actually

refreshing that data locally as well as

contacting firebase backend and getting

the latest information from there so

just because your user has verified

their information doesn't mean that the

application is immediately going to

understand that so you need to ask the

so i can see here now we were supposed

i'm going to take some items in my notes

just to make sure that i've talked about

and we're returning the login view right

from our home page so this is something

you'll need to do also before we

all right that was a lot of information

what we've done pretty much is just to

create the uh verify uh email view or

what we call it is it called verify

verify email view we ensure that it can

send an email we clicked on the link in

the email and made sure that the user is

verified and that's and that all has

but we still have a lot to work on and

as you can see it right now i'm going

into the code and manually like

returning the screens that i personally

want to see or it's important for you to

see for instance the login view but

if you display login view how is the

user able to go from the login view to

register if they don't have an account

that they can log in with so that's what

we're gonna do in the next chapter we're

gonna create links between our screens

so that a user can go from one screen to

so yeah great job that's it for this

chapter and i'll see you in the next one

hello and welcome to chapter 17 of the

in the previous chapters we've been

working quite a lot with some of the

basics of flutter for instance stateful

stateless widgets we've been looking at

a column we've been looking at text

button and many other widgets and kind

our screens presentable to the user and

at the same time we've been working on

the functionality of the applications

such as logging in registering verifying

and um we're gonna break it down by

first starting to work on the link

between the login and the register view

at the moment we i mean i'm going to

the way we left it in the previous

as you can see here in the main function

home page widget and also let me change

let me change the structure on the

uh of the different views on the screen

so you can see a little bit better so if

i do a hot restart here you can see that

um when the connection state is done

when the firebase application is

initialized i'm displaying the or we're

displaying the login view here without

basically having the option to go to any

other screen from here so if i want to

send the user to the register view then

i have to change this code right here

that's why we need a link between these

two views i'm sorry i'm looking at this

screen just because i need to actually

ensure that i tick the items that i've

already explained so um we need to make

sure that when a user is on the login

screen even if that's the first screen

that we always display to the user which

but if even if it was we need to be able

to let the user to go from the login

screen to the registry and also from

registry view back to the login screen

so that's what we're gonna do in this

is to go to our login view and add a

the registry so i'm going to open up

i'm going to bring it here make the

screen a little bit smaller here

so let's go to our login view which i

can see is actually modified um yeah

and what we need here you can see we

have a text button and that is for our

and as you can see the cache has added

text but it's allowing you to send us a

registry view so right after this text

button let's create a new text button

and i'm going to bring it a little bit

higher so you can see i'm going to say

text button remember uh child parameter

always has to be at the la at the

it should be the last parameter so i'm

going to say unpressed ask visual studio

code to complete it for me and then i'm

going to say child the text is going to

and we say register here something like

and i'm gonna save this and you can see

now that we have a little button here

that says not registered yet register

okay so that part is done but the button

at the moment the way it is right now

but before we can do that we need to

you see in the previous exercise or in

and then we created a material page

that may have all been kind of like

alien to you and you didn't really know

what was happening and that's okay you

will get to know it more and more as we

go through the various chapters in this

in this course but what we need to do

here is to first talk about what a route

is and what a name route is and i've

actually put a link to a documentation

that we can go i'm going to bring up my

web browser and i'm going to create a

new window and i'm going to say flutter

which is going to end up in the exact

same link that you can see there

and it says here in the navig in the

navigate to a new screenplay recipe

however if you need to navigate to the

same screen actually it wasn't such a

great description to be honest i was

kind of expecting a little bit of better

description but maybe i can do that

myself instead of you having to look at

this and i can see to be honest with you

webpage is a part of a cookbook which

like linked together so in order for you

to understand this page you actually

have to go to this link and read that

and then this would be the continuation

i just put the link here just so you

but i'm gonna explain that myself here

now if we go back to um where we had the

uh where did we have the name route when

we pushed it it was quite a bit before

so this is something called an anonymous

route so sorry about that i said name

route but this is an anonymous route so

a route is as its name indicates in

flutter is it's a journey that has a

start and an end so it starts from a

view and it ends in a view okay that's a

however there are two types of routes

and you can create in flutter either you

do your routes either you go to a new

screen to your destination from the

current screen without providing any

sort of information about what this

route actually means to your application

so it's an anonymous route you're doing

it in line you're not telling flutter

so as the user presses the button or

for instance in this case as the user

ends up in the home page and the future

builder initializes firebase upon the

connections they've done meaning that

the initialization of firebase is

the verify email view on the screen and

fixed it by doing all this code

so that was an anonymous route you're

doing it in place as the done connection

state happens then we were pushing a new

but a named route is the exact same

thing that we write like we were doing

before but you tell flutter about that

route before so that when your

application is created and initialized

and the flutter engine starts it knows

that there is a route with the name xyz

for instance or fubar bass whatever you

screen okay so that is the difference

between an anonymous route and a name

route in that as its name indicates a

is a route that has a name so you tell

flutter that associate this particular

name as a type of string to this route

in my notes that we've talked about that

is to define two routes for our

application one called slash login slash

and the other one is called slash

so let me just go and ensure that i'm

bringing those routes correctly so

what i'm going to do here and you need

to do as well is to go to your main

and at the moment we have a title for a

material app and a theme data and then a

but what you also have is a parameter

called routes okay so let's go and say

we want to create these routes

and you can see here it says routes its

value is a map of string and a builder

function for the values of those

uh string keys so it's a little bit

strange it's a map whose keys are

values are functions that take in a

build context sorry about that and

return a widget so it's a little bit of

it's like maybe a paradigm shift in your

head but these things do exist and i've

already i've also created my own classes

that kind of expect this kind of

so let's go into routes and say okay now

as you know as you know this is how we

create a map map is a is a list of key

or map entries as they're called in

and then what we need to do here is i'm

sorry but i'll just move some code

around i have three screens here so i

kind of have to manage those screens at

the same time i'm explaining things so

what we're gonna do here is to define

two routes slash login all right and

remember the value of this of the value

of every key inside this routes needs to

be a function you see it's a function

that returns a widget and it takes a

build context inside so in here what

we're going to do is say we have a

and we return actually sorry login slash

we return the login view all right so we

say have a route called slash login

slash and when that route is used it

an instance of the login view now we

need to do the exact same thing but for

register so i'm going to copy this

and here just going to say register and

instead return the register view which

we haven't imported into our main dart

file and you can remedy that by pressing

command dot on mac or control dot on

windows and linux and then say import

okay that's that and i'm gonna have a

look at my notes a little bit

what we need to do now um i've already

explained that okay in log area all

right so what we need to do now is to go

from login to the register view

and as you can see i've explained it

here in the caption that this will

actually cause an error but we will fix

this error as we go forward okay

in this uh register view here sorry in

in our login view so let's go to the

login view we have this button right

here and what we need to do is just to

ensure that by pressing that we can go

i think i brought up the caption

and you can see that we need to use

navigator of context push named and

and this this is kind of a peculiar call

because what it essentially does is as

you can see right now on the screen we

we basically the way we've created

things at the moment is that we have the

and then depending on the state of

actually no not depending on anything

we're literally just hard coding login

view to be returned inside this okay so

we have the home widget and then inside

this home widget we're inserting the

contents of login view so login view and

home page are kind of like displayed on

this home page has the scaffold whereas

login view doesn't have any scaffold and

it's just a column at the moment if you

remember we can go back to login view so

you can see that it's just a column okay

so that's the structure currently by

doing this command that i'm providing

you here navigator of context push name

what is going to happen is that as its

before it pushes this new route

is what we're basically saying here is

that by pressing the not registered yet

button and register here we're going to

nuke this screen remove it completely

from the screen and replace it by this

new widget that we're returning okay so

let's go to our login view in this

button here into the login view and

sorry in the not registered yet button

and remove until here push and remove

until push named and remove until

and in here now we need to display our

register route and we refer to that

let's go and fix that now so we say here

put false there as it is and you can see

you can get documentation about this and

there's a predicate here that returns

returns true or false and it says push

the route with the given name onto the

navigator and then remove all the

previous routes until the predicate

and at the moment we're just saying

return false meaning return remove

everything from the route and just go to

the register view so just leave this as

and this is actually going to cause

a problem and you will see that soon i'm

going to hot restart just in case and we

and i'm going to press the not

registered button here and boom and you

that's actually great that we're getting

this error this is exactly what i what

what is happening here is that we're

removing everything that's on the screen

pushing around to the screen that has no

scaffold so this is the problem that you

can see on the screen that yeah i can't

just display a column on the screen

without anything around it so we need

and that is what this caption also is

saying at the bottom left of the screen

i'll check some items in my um

so as the next thing what we need to do

now is to go to our register view

which is what we're pushing here and

make sure that our register view now has

all of a sudden a scaffold all right so

lib here and register view i'm gonna

remove this project explorer here at the

moment we're returning a column what i'm

gonna do is gonna command click on mac

or control click on linux and windows

widget and then call this widget

and for the app bar create a new app bar

and for its title say text and this is

the register view or just say register

with constants okay we're just gonna

leave it like that i'm just gonna double

check in my notes to make sure that's

what i had intended for the register

view to actually be called yes i can see

that it was called register as well

we have that now and you can see

now we're in the register view and there

is no error i'm gonna do a hot restart

and we go here again and now i'm gonna

press the not registered yet button and

you can see we are going to the register

so now we have a good connection between

the login view to the register view

but there is no connection backwards

there's no connection from the register

view to the login view and that's

exactly what we're going to do now

i'm going to take some items in my notes

in the login view that i'm going to hot

restart so you just uh remember you can

be reminded of what we did we had a

login view as our login button and we

added a new item to go from login to

register but also we want to make sure

that if you are already registered and

you ended up on the screen then you can

go back to the login view okay so let's

do something similar here in our

at the end of the register button here

let's create a new one and we say text

and uh on crest gonna get help from

visual studio code to create that

function signature and then i'm going to

log in here like this okay as a constant

and i comma here so we get the

formatting in place and now you can see

the register view also has a button that

says if you're already registered then

log in here and the login view has

not registered yet register here so

now we have to program this and as you

saw in the login view we had this

functionality navigator of push name

blah blah let's copy that functionality

from the login view and bring it into

under already registered button there

and instead of going to registered main

route we're going to go to the login

hot hot uh hot reload you don't have to

i'm gonna press this button

and actually this is really great and

so i've talked about that i'm going to

just take some items um in the

in my notes to make sure that i've

covered all the grounds that i prepared

covering basically so you can see this

is the exact same error that we had in

or in the previous situation that our uh

register view didn't have a scaffold

because we went from login view and to

register view and then register we

didn't have scaffolds so we created a

if you remember okay but if you go to

the login view you can see the login

view still returns a column and the way

i mean the reason this has been working

so far is that because our home page had

a scaffold do you remember here homepage

had a scaffold and the contents of login

so far just been injected into the body

of our home page and that's the reason

if you hot restart your application you

come to this beautiful home screen it

says home and then you have the login

if you remember from the previous

chapter we removed the scaffold from

their login and their register and now

we're putting them back but i kind of

want you to understand the reasoning

behind why i'm doing things i don't want

you to think that everything is perfect

from the beginning because for me at

least when things are done perfectly in

the beginning i always question like

what if this thing wasn't there and i'm

just trying to make sure that we remedy

these things so you go through the

entire journey you see what's wrong and

how we can fix it instead of just

me presenting to you the exact right way

let's go to our login view and make sure

we do the same thing that we did with

so let's go in here and add a scaffold

so i'm going to write i'm going to click

on it sorry i'm going to command

and we're going to press command and dot

on it on mac or control dot on linux and

windows and you say wrap with widget and

just say your widget is called scaffold

scaffold unfortunately doesn't have a

child parameter so it has a body

so change that parameter to body

and let's create an app bar for it then

and it has a title and we say const text

and in here we just say login

as you can see i mean we've now added

the scaffold and as the top as the

caption here is telling you it says

about login view is being embedded into

so now what we need to do is to go to

section which is we need to remove now

the scaffold from our main dart or from

right now home page is our login view is

being embedded into home page but that

we can't have login view with its own

scaffold being embedded inside a home

page that already has a scaffold so

uh what we need to do is to remove the

scaffold from our homepage uh let's see

if we can do that and it doesn't seem

like it's working so i'm gonna go

say that i'm gonna grab the future

builder okay and this is what you need

grab the entire future builder and

instead of returning the scaffold just

return your future builder just like i'm

there's a lot of information and also

verify email view also has a scaffold

because this is what we need right now

we need all our views to have a scaffold

embed our verify email views columns as

wrap with widget and let's say scaffold

scaffold remember there is a body and

then we say app bar is an app bar a

text and we say verify email something

good now if i command s in order to save

all these changes we're gonna get an

which we didn't and that's also okay

it's probably because we actually fixed

home page so it doesn't have a scaffold

that's why we're not getting the error

that is really good i've also explained

so let's just make sure that the

connection is working between these two

login view is there you can see there is

no home page any anymore displayed here

if you remember from before this

refactoring then when we sh when we

showed the login view then there was the

home pages app bar displayed on the

screen but home page right now is just a

future builder that returns other things

such as a text of loading or the login

and also here i noticed that instead of

logging loading what we could do is to

display a circular progress indicator

this is a great widget if you're if

you're just doing some sort of a loading

that may not immediately have an end so

what circular progress indicator does it

just shows like a loading indicator we

could actually comment all of this code

out and just return the circular

progress indicator and comment the

switch out as well and then press

command s so you actually see how it

looks like it's ginormous at the moment

because there's no scaffold around it

but if you had scaffold everything put

in place then you would see the circle

progress indicator actually displayed

command s so we see the log loadings

sorry the login screen or the login view

and the connection between those screens

well the next thing we need to do is to

at the moment you see we have our login

view and the register view so they're in

their own files but in the main guard

file we've kind of forgotten or maybe

not forgotten we just haven't had the

time to do that we have the verify email

view still rightly like it's just

displayed or it's coded in the main dart

file so what we need to do is just to

create an an own file for it and we call

it verify email view okay so go to views

here and right click on it new file and

and grab the code from verify email view

or cut it basically and just place it

and make sure all the imports are in

place i've already explained in previous

chapters how we need to fix imports

so i'm not going to go into so much

detail about how imports work and how we

should do that because i think if you've

already gone through the chapters

chronologically then this is like

obvious for you how to fix it so it kind

of feels like if i try to over explain

all these things over and over again the

people who are watching this course

chronologically from the beginning and

they're kind of gonna get bored so in

the interest of not boring actual people

who are watching things i'm not gonna

over explain so there we go that is

fixed and also let's make sure that we

import firebase off as well so that

we do a hot restart as well just make

sure everything is working as expected

so what we need to do now also in

following through with the plan of

being a good software developer

what we talked about not in the previous

chapter but i think it was in chapter

let's see it was in chapter 15 i believe

where we talked about git and github now

we've done a lot of code things are

working great let's commit our code okay

so as we had if i bring up the terminal

here i'm going to do this so you see a

little bit better i'm going to bring up

and let's go to our terminal here i can

see scrcpy is running in this terminal

so i'm going to create a new terminal

and i'm going to just say be it log and

you can see we had the initial commit

and that was step one all right so

because we tagged it as a step one you

see here so what we do let's just get

git status and we see that we've done a

lot of work i'm gonna get add all the

files to the staging area remember from

and then let me also make this a little

bit bigger so you can see it better

okay then i'm gonna commit and i'm gonna

say git commit step two like this

and also actually before we do that i

believe we've missed a few things

then i just look a little bit in my

notes just to make sure that i'm not

missing things before we continue

yeah so what we need to actually there's

one thing we missed here at the moment

what we're doing is saying that okay

just go to the login view but one thing

that we've missed is to ensure that we

go to the correct correct view okay so

we say we first get the current user so

and we put an else statement here as

if the user is not null then we

and we just say print email is verified

email is verified something like this

let's go back to the print so

before we actually do all this maybe i

should explain why we're doing this so

at the moment or before we started with

whenever the application was running we

were just going directly to the login

screen but what we need to do now is to

now that we have three screens we have

the login view register view and also

is that what we call it verify email

we need to make sure that we're actually

accommodating these various conditions

into returning the the correct widget so

here we're saying that if the user's

and we can actually return maybe even a

and we'll return something so yeah let's

do that so we will return text

if the email is verified we just say

that your email is verified but the user

doesn't see that if the email is not

verified we will we will basically

that's us basically saying that yeah you

if the user is null then we send you to

the login view so let's go in here in

the ill statement we say return login

that should do it to be honest with you

return cons return log so we can remove

upon firebase initialization being done

check for the current user if there is a

user we're gonna check if the email is

verified if email is verified right now

we're just going to say print email is

verified and since we're not returning

anything in here the code is going to

fall through to line 48 here which in

turn then returns just a text done okay

so if you have a logged in user sorry if

logging into the application and the

email is verified all the user is going

to see is just a text done all right

but if you have a user in the

application whose email is not verified

that user is going to see the verify

if you don't have a user with firebase

so that user is not logged in then we're

going to display the login view all

a lot of information i understand this

may be a little bit frustrating so

so now i'm going to hot restart and what

you can see here is just a very ugly

text done displayed on the screen this

means the current user in the

application is logged in and the email

it is very ugly i understand but you

need to also understand the reason why

this is ugly at the moment and that is

what happens if you do not tell flutter

how things need to be rendered and

since our home page has a future builder

and nothing else surrounding it there is

no scaffold there's nothing it's just a

text widget that's flutter telling you

okay i don't even know how to render

things anymore i don't know what theme

you're using i don't know the font size

i don't know the default font color so

that's what happens if you don't

surround your widgets with a scaffold or

material widget that knows how to render

wow a lot of information again um but i

hope you're sticking with me here

now that we've done that we can go and

commit so let's have it look at our logs

and look at the status i'm gonna change

the structure or the layout of the

and now now we see that after we did git

add we've also changed the main dart

file with these changes so i'm gonna get

at that as well all those changes and

i'm gonna say git commit step two okay

so now that's gonna be committed and

we're also going to push the commit

and additionally we need to tag it okay

because if you remember if you look at

the first commit that we did here it was

now we've committed step two but we

haven't tagged it so let's go tag it

and then you need to push your tags with

tags and that creates the step two tag

i understand that was a lot of

information but i hope you could stick

with me and go through all these steps

so that we are ready basically for the

all right and also before continuing

with the next chapter just ensure that

you're logged in because in the next

chapter we're actually going to work on

i can see also i've planned a lot of

information in that chapter for you so

there's lots and lots and lots of things

so it's a very exciting chapter actually

the next chapter and but before you

continue with that just ensure that you

go to the login screen and ensure that

you log in with the user and you just

see this ugly done button here okay

as i mentioned in the next chapter we're

going to talk about displaying a simple

interface to the users who are logged in

and also allow those logged in users to

get some coffee tea if you want to or

whatever refreshments you want and i'll

hello and welcome to chapter 18 of this

in previous chapters we've talked a lot

and and we've also talked about

we now have pretty much like our login

well i don't want to say we've got them

we have a basic login and a basic

if you remember from the previous

chapter we kind of left the application

if the application detected that you

you were a logged in user and that you

had a verified email address then we

dirty done text on the screen and i can

bring bring the screen up on my android

and you see we kind of left it in this

and i'll bring the code up as well so

reminded of what we were doing so we

left the application in this state that

if the user wasn't null meaning that the

his or her email address was actually

verified we simply did a print statement

we left it like that meaning that

let me actually bring up the right

since the builder function of the future

builder requires that you return a

widget by moving your mouse over you can

actually see that it says required

widget you need to return a widget from

since it requires that what we did is

just we put a like a return cons text at

the end of all our if statements so if

none of these were present there we're

and since that was there and in this

user email verified we're not returning

then the code falls through to this line

meaning that if you're a logged in user

and you're verified then we're returning

so we need to kind of um now start

because you see okay before i say that

are have handled the email verification

view so if you're if you're a logged in

user but your email isn't verified we

displayed it verify email and if you're

registered meaning that like you don't

have a user then we show the login view

since we've got those down what we need

to do now is to work on the actual main

ui of our application because what you

can see here that says done this should

be the main ui of our application so

users who are logged in and their emails

are ready are verified should see the

in this chapter we're actually going to

work on the main ui of our application

and then allow the user to log out from

our application as well so i'm just

looking at my notes to ensure i'm

telling you all the stuff that i plan to

so without further ado maybe we could

actually get started with that so let's

main dart file here and create a new

i'm going to bring it up here

going to create a new stateful widget

and this notes you just imagine that it

it is the main ui of the application for

logged in okay so as i mentioned before

stf to create a stateful widget and then

let's see it doesn't even really have a

scaffold or anything so maybe that's

what we need to do i'm just gonna

so let's go create a scaffold and an app

we go in here into where we're returning

a container at the moment we just say we

and for our scaffold we want an app bar

and the app bar should just be an app

what should we call it i don't think

i've got notes for that to be honest

with you let's just call it your notes

i'm gonna actually go and have a look at

where i was actually preparing this

course for you and i can see i've

written main ui so let's just do that

let's just say main ui in here okay so

body is empty at the moment so there is

nobody and if you remember from previous

chapters when you return a scaffold and

an app bar all it does is that it

creates kind of like depending on your

theme but usually with the light theme

it creates a a bluish status bar and an

app bar with white text for the app bars

and the rest of the content of the

screen is just going to be white so it's

kind of like an empty container kind of

future builder here in our home page

we're going to remove that and now we're

going to get an error saying that well

the case should not complete normally

try adding break or return and that's

basically it's complaining in this

line of code here for me in line 41 it

may be another line of code for you

so it's saying that well one of the

cases of your your like the entire block

of code that you're placing in here it

doesn't always end with a return and

that's exactly right because in the case

of user being email verified we're not

returning a widget and what we're going

to do in here we're just going to say

all right um and i'm going to press

command s there and now we did a hot uh

reload and you can see the main ui of

and in my notes i can see here that

we're going to go and place a little

we're good to go for the body let's just

so now we can see the hello world

i can see i have a lot of notes to be

honest with you with this chapter so i'm

really making sure that i'm looking at

my notes while i'm giving you the

content to ensure that you're getting

all the information that i plan for you

to get so i apologize if i'm looking a

yeah it's just to deliver the best

okay so we've done that hello world

what we need to talk about is um

the app bar class and i've provided a

open on my screen and then bring to this

screen so you can also see it

increase the size a little bit and

perhaps also do this layout so you can

see it's um the caption as well

you can see for appbar the documentation

just says a material design app bar an

app bar consists of a toolbar and

all you need to do really or all you

need to know about an app bar is

various widgets i mean pretty much

everything in flutter is a widget so an

and an app bar consists of various

the default app bar allows you to

display a title as you can see here in

the title by default has its own styling

it means that it has its own left and

bottom margins so by default it's like

displayed vertically in the middle of

your app bar as you can see in the main

material component pretty much

everything you display on the screen has

an app bar has its own theme and it has

so what we're going to do the where

we're going to use the app bar in the

is not only to display a title but it's

to the far right that the user can click

in in our case tap on because there'll

be indirect users are going to run our

application on mobile devices so they're

going to tap and if we allowed the

our application to be run on desktops

then they'd be able to click and maybe

even tap on if they're running for for

what is it called surface book or

this is what an app bar is as is like

the gist of it and there's information

here in the documentation you can see

here it says there's a leading space and

then there's or you can actually put a

widget in the leading and then there's a

title and then some other actions and

these are the things we're actually

going to use actions in this um

in this section in this chapter of our

flutter course so you can see here for

code on how to configure an app bar with

some button you can see you can press

the button and then you get a snack bar

okay so keep this in mind you can have a

look at the documentation i really

actually suggest that you do that

and you can you can spend some time

reading through the documentation but i

don't think you need to get absorbed in

the documentation so much but just have

a look at the various parts of an app

bar and try it for yourself okay

i can see that i've told you about the

and now what i think we need to do

um is to talk about uh this print

statement and why we were getting an

if if i if i put a print here and if i

information here saying avoid print

calls in production code okay

before we move past this because you've

probably seen this quite a lot in this

course that i've placed print statements

and then we can like for instance if i

bring up the debug console and just do

command s on my mac or control so linux

and windows in order to hot reload

let's see actually email verify heart

oops see i can see that it crashed

that's okay so i'm gonna go and bring up

and these things do happen and that's

completely fine so and i'm gonna need to

run the application again because i

actually lost my connection with that

device but while that is doing its job

i'm gonna tell you also about

print is usually called a poor man's

debugger in that um if you're not a

software developer you probably don't

know about even debugging what that

means but what debugging is is it

essentially is is where there is a

problem in your source code but you

don't know really where so you try to

step through various lines of code in

your application and refine what the

um a lot of a lot of times when people

don't really either they don't have the

time to debug or they believe that the

debugger is just too slow they start

putting print statements in their

um by putting print statements in their

application they can kind of track where

they where the application is going

through the various lines of code and if

for instance they put a print statement

in a place of code where they didn't

expect the application to end up and

then they'd be like oh okay i ended up

in this code block i shouldn't have so

let me just check why i ended up here so

it's kind of called a poor amount

debugging because print is a piece of

code that you actually place in your

code so sometimes print isn't the

in banking applications for instance you

should be extremely careful what you

print because these things get logged

and you you may think well okay they get

logged on that phone uh what is the

the problem with logging things even if

it's on the phone is that you you must

know that the operating systems android

and ios usually like the most popular

ones right now they keep track of your

lot so these logs are actually stored in

a place on the operating system so you

can actually read them back later so

there is a buffer so this information

that your application may be printing to

the console isn't completely private

except that it is stored on the phone

even if it's for a short while while it

gets replaced by a new buffer if your

phone ends up in the wrong hands someone

can actually get a hold of your lock so

imagine a banking application logs your

like a login information username

password all that detail and even if

it's only for that application you may

think but someone else it may actually

end up in the wrong hand so that's what

this information is telling you avoid

print calls in production code okay so

there is another way of doing this

instead of doing prints you can actually

in your in your code and we're gonna i

we're actually going to talk about in

i think we're gonna talk about logging

so let me have a look here in my

notes um yes we're actually going to

talk about logging instead of printing

just keep that in mind that there's a

better way of doing print statements if

if they're if that's what you want to do

if that's what you want to see

on the console so we're gonna fix that

soon and this is you see hello world

information that was printed by this

print statement okay so sorry about that

that was just a little detour but i i

thought it was necessary to tell you

especially if you haven't done software

okay we've done the return notes view in

the home page we shouldn't have any

print in the home page and you can see

this is our home page right now and we

don't have any print statements let me

so what i'm gonna now describe to you is

that we need a an enumeration that

items that the user can click on you see

and this app bar will in itself be able

display something called a pop-up all

right so i haven't shown you how this is

going to work by the end of this chapter

so it may be a little bit difficult to

understand but just imagine that we have

our ui here and what we need to achieve

in this chapter is to place a little

button here with like a dot dot either

horizontally or vertically i don't

really know what the icon is going to be

so some sort of a button here upon

the user will get a little fine nice

like a drop down and in this drop down

then you can place various items like

settings blah blah blah so imagine we

have a drop down by pressing that button

and upon pressing the log out button

then we're going to display a dialect to

the user saying are you sure you want to

log out from the application so

this works very nicely i mean when

before i say this works very nicely

maybe i should explain that by pressing

each one of these items in the pop-up

menu that we're going to display to the

user we are going to get a call back

from the system saying oh this item got

and you need to tell the system what

this item is you can either give it like

numerical value or a string or even

better better you can give it an

enumeration value if you remember from

chapters where we talked about dart

basics we talked about enumerations and

why they're important and and that they

make things very easy because when you

specifying your enumeration and put

you you let me actually change this to

also do not do so sorry about i just

and you give those innovation values to

your pop-up menu items by press but by

the user pressing on any of those items

you will then get that enumeration value

back so you can do a switch statement in

your a callback and say oh which item

got called was it this case of the

enumeration so instead of you doing like

integer comparisons or string

comparisons you can actually use

enumerations which make your life a lot

we are going to talk about that

soon as you can see an enumeration that

describes our pop-up and we're going to

now let's talk about pop-up menu button

and as you can see the caption says

they're usually used together and let's

go actually bring up safari here and i'm

going to say pop-up menu item flutter

and i'm going to bring up the document

so we can have a look at it together

as you can see it says an item in a

material design pop-up menu so this is

the actual menu item itself so if you

imagine we're displaying a drop down

menu every item in that pop-up menu item

is of type pop-up menu item all right

and you can see a pop-up menu item in

a i mean a pop-up menu item is a generic

in advanced um a dart chapter we also

talked about generics and what a generic

item in this case a pop-up menu item

is that it has a value of this type that

is off in this case a pop-up menu item

why farther is a pop-up menu item is of

type y farther now we don't really know

why farther is but it could just be an

enumeration okay and you can see here

after you've decided decided that a

carries a value of of this type then its

value should actually be specified and i

can see that there is a case called

in that animation that you've assigned

to your pop-up menu item okay

what is a pop-up menu button so let's

search here pop-up menu button okay

let's go into the documentation here and

you can see it says displays a menu when

pressed and calls unselected when the

menu is dismissed all right so

what you need to know is that the pop-up

button that we will place on kind of on

our app bar upon pres upon pressing

a menu and you can see here in the code

has an unselected callback and it has an

and items inside the pop-up menu item

sorry the items inside the pop-up menu

are of type pop-up menu item so

imagine then you have the pop-up menu

and then you will have its item builder

and each of which of these items are of

type pop-up menu item and that's exactly

okay i'm gonna close that window i don't

think we need the safari window here um

now i think i explained this part of the

caption a little bit just now about when

we talked about the pop-up menu item but

you can see here i've said pop-up menu

item has a value let's look at the code

for pop-up menu items so maybe we could

just actually right here pop-up menu

item in our code and i'm going to

command click on it and you can also see

that a pop-up menu item has this

property called value okay and as you

can see a pop-up menu item as i

mentioned before is a generic class that

carries a value of type t and type d

basically when you see t in generics it

just means something that you specified

so anything that's specified inside the

less than and greater than size is a

which then gets replaced at a compile

time with the type that you as a

um that's the code for the pop-up menu

item and you're more than welcome to

drill down more into into that code to

our enumeration that we've now talked

here right above the notes view

and let's then define an enumeration

called menu action and in there we're

gonna have a case called log out okay so

menu action we said we're gonna call it

and then we have a case called log out

in there so if i do command s to hover

reload then nothing happens and the dart

formatter i can actually see they form

so the next part that we need to take

is to actually display our pop-up menu

button you can see in notes app view

state app bar create a pop-up menu

in the app bar in order for us to be

able to display a little action there we

actually go to the app bar here

and you can see there is a property

called actions which is it says it's a

list of widgets all right so we're gonna

say we need actions there okay i'm also

just going to ensure that i have

everything here so i can see the code as

i can take in my notes that we've talked

all right and now we're gonna create the

pop-up menu button all right so

you see the action as we saw in the

source code on the website that i

displayed you and that i displayed to

you as the documentation inside the

actions of our app bar then we're going

to create items of type pop-up menu

button okay so let's go ahead and do

all right and then you can see it has an

i think it's actually an item builder

let's first actually take care of the

unselected so i'm going to put

unselected command space in visual

studio code on a mac and control space

in linux and windows in order to get

this dialog get some help from visual

studio code to complete this code for us

you see upon selected it's going to

return the value to us and we're telling

darth in here that our pop-up menu

button actually manages values of type

menu action all right which is what we

and you can see we're getting an error

saying that the named parameter item

builder is required okay and we'll

get help from visual studio code with

the same command that i mentioned to you

and in here then we're going to create a

constant of a pop-up menu item

and we're going to say that this menu

values of type menu action as well okay

and we're going to say according to the

documentation remember every pop-up menu

item has a value so a value associated

with it which then in turn gets passed

when this pop-up menu item is tapped

okay so then we're going to say in this

case it has the value of menu actions

and this child is just going to be

okay and as a const as well actually the

entire thing is a cons so we don't have

so we just uh let me have a look item

menu actions constant body might return

okay i see because the item builder if

if i move the mouse over item blue you

can actually see that it needs a list of

and you can see pop-up menu item if you

go to this code is actually of type

pop-up menu entry so the problem we're

seeing here is that it says you aren't

returning a list but you're just

returning an item so we're going to say

can we actually make that entire list

const so yeah that works as well okay

i'm gonna do command s and what you'll

uh we've actually added log out

so and you'll see here now by pressing

this then we'll get a beautiful pop-up

and there is a log out item in it all

that logout text there is the child of

don't worry i mean don't get confused

with the child and the value what you

need to know is that the child is what

the user sees and the value is what you

when the user then taps on that item

your unselected is going to get called

and then we'll get that value so just to

test that let's go back to our print

and i'm going to bring up the console

here going to clear it and i'm gonna

change the ui layout a little bit so you

see it better i'm gonna do command s and

then i'm gonna tap on this log out

you'll see now our unselected got called

which was what you associated with your

got printed here and got sent sent to

okay so we've done that part we've

handled it with double quotes we haven't

really handled but we're just printing

go through some of the things that i

we can see that the print statement is

in the previous part of this chapter i

talked about why print usually isn't a

there is a better way of doing print and

pre-packed with a package called

and you can easily import developer and

inside the developer tools for dart

there is a good function called log and

you can use log which is a more

trustworthy and more even configurable

version of print and i'm going to show

so in your import statements let me

increase the size of the screen a little

say import dart from dart import

now i haven't talked so much about

import statements before but import is

actually configurable as well so in here

for instance if you look at the code

inside import this dart developer

there's a lot of stuff that you might

not need in your application okay so by

um a package or a library in your

program you're pretty much importing

everything that that package also

imports so in this case extension

these things will then be available in

your workspace just by you pressing for

instance for me is control space on my

macintosh so all these symbols will then

be available right here so there's tons

and tons of things that are available

right now in your application without

you having to do anything just because

you imported quite a lot of things now

by importing the dart developer

package in this case also you're making

all those symbols available kind of like

globally inside this file at least and

some developers don't like that some

developers kind of like to limit the

and only have the symbols available that

and because of this there is a good

functionality for import and dart where

and by doing a show you are telling dart

you only want to import a specific part

of this package so the specific part

that you're interested in is a function

after doing this you can basically go to

your application and then say log

now a lot of developers also don't like

this because they think oh log where did

um if you want to be more specific where

functions come from especially if

they're not your own functions or maybe

even if you have few log functions maybe

you even have a log function in in this

code right here like if you say void log

i mean it's there are so many logs

available now i don't even know which

dart allows you to do is to give an

alias to your import so for instance if

you want to use the log function that is

provided in this developer package for

you you can actually give an alias to

this entire package in this source file

which is the main dart file so you can

i'm going to say dev tools okay so what

happens here is that the log function

now is not available as it was before

except you have to say devtools log and

then you'll see that there's a log

function and that's the only function

available inside devtools now because it

if you hadn't done the show here

then devtools will have everything that

dev tools or the developer package in

or import it into your workspace okay so

do the code then as this import devtools

show log and the reason i'm explaining

all of these is because i think these

are so important to understand

as soon as possible and now that i'm

explaining these things in such detail

i'm not going to explain them anywhere

else in inside this chapter so i don't

want to have like half explained

that we actually need to fully

understand and explain half of it now

and then half of it later because then

chain the information to get the entire

picture so that's why i'm explaining

things sometimes in such great detail

okay now that we've done as devtools

show log let's go to this print

in our notes in the unselected and then

and you can see now that it's

complaining to us because it says the

devtools log it doesn't allow us to

print a value and if you have a look at

the log fi and log function signature it

expects a message of type string but our

a menu action is an enumeration but you

can always say to string on an

enumeration value in order to make it a

um so what we're going to do then is to

click on this log out and now you see a

log item being printed to the screen and

it's a little bit more distinct as well

you can see now now that we're not using

print using log make sure that your log

items are a little bit more

distinguished inside the debug console

let's go now to the next item

so what we're gonna do here now we have

button here so i'm going to tap on it it

what we need to do now is upon pressing

this item we are going to display a

now if you're a designer you may be

familiar with a dialogue and the

dialogue is basically like an alert

displayed on the screen depending on

what type of operating system you're

running on but both android and ios and

ipad os mac os windows everything they

way of handling dialogues and dialogues

are usually like a small little window

displayed usually in the center of the

main screen where that application is

configurable usually with a title with

the description text or even images and

usually with some action buttons which

are called cta or call to action

that is the exact same case here in

flutter so upon pressing this log out

button we're going to display a dialogue

to the user saying oh you want we see

that you want to log out are you sure

you want to log out and then like a

cancel or no button and a yes button

which is the call to action or cta okay

what we need to do now is to create that

function a function that can display an

to the user and you can see here that in

the caption i've mentioned write a login

function to display a dialog

signature is kind of like it returns a

feature of boolean and if you think i

mean if you really think about it a

dialogue that asks the user to log out

either has a cancel or a null button or

either a cancel or no button and

a call to action which does the log out

so it either logs out or it doesn't

or basically it either confirms that you

need to be logged out or it says no you

shouldn't be like that so it's true

false okay so a boolean so boolean is

um and what we're going to do now is to

write a function that returns a future

of that boolean saying true you have to

be logged out or false not and we're

going to call it show logout dialog okay

so let's go at the bottom of this file

and as i've mentioned in the caching

we're going to call the show log out

dialog and we say build context because

we need actually context to display our

okay a lot of information now um i'm

gonna go actually a little bit back to

uh because i forgot to mention something

and the important thing to mention here

are two things called show dialogue and

alert dialogue now show dialog

actually let's go to alert dialog first

alert dialog we can see is a class is a

stateless widget which defines the the

dialog that gets displayed to the user

itself so it doesn't have any concept of

being displayed to the screen or

what happens when the dialogue is

created after that point it doesn't care

performs the action of creating an alert

that's for alert dialogue but

you need a way to display that alert

dialogue to the user and the way to do

i believe it's called show dialogue

you can see here show dialog is a

function that returns an optional future

or sorry a future of an optional value

there's a difference between an optional

future and a future of an optional value

so in this case it's a future that

always gets returned but it optionally

contains a value okay and you can see it

says okay give me a context and then you

have to provide a builder to me okay and

this builder should return a widget so

what we're gonna say is going to say

show the dialogue you can see here

and builder we're going to get help from

visual studio code to complete it all

and in here in our builder what we're

going to do is we're going to actually

let's go back to this caption so we know

what we're doing what what the actual

the builder you're responsibility is to

create an alert dialogue so let's say we

an alert dialog which is a widget as you

and it has a title you can see the title

actually right like here is a widget

for the title we're going to create a

the text i can see we set sign out here

so we're basically configuring the alert

or the content also is a widget and

we're going to say this is also a const

text and we're going to ask the user

are you sure you want to sign out okay

now that we've put the title and the

content in there we need to specify the

parameters call actions and you can see

the type of this actions is list of

widgets all right and this is like the

buttons that the user will see on this

what we're going to do is going to

create two text buttons so i'm going to

and don't worry about all these errors

and things that we're seeing here this

is because as i mentioned in one of the

previous chapters or one of the first

introduction chapters i think

is because we have an extension here

called error lens and aero lens is

extend expanding all these errors that

are happening as we type and it's

displaying it on the screen it looks

really scary it looks like we're doing

everything wrong but these these bro

these errors actually do make sense if

you look at it it says text button the

named parameter on press is required but

there's no corresponding blah blah so we

need to fix these things okay so let's

go to text button and say unpressed get

help from visual studio go to complete

it and then after that i'm pressing say

so this first button is actually gonna

so that's the first text button and copy

this text button now and paste it in

here and instead of cancel this time say

like that now you see there's a lot less

information displayed on the screen and

now we have an alert with two buttons

cancel log out but you can see upon

pressing those buttons we aren't doing

anything here okay and we need to fix

this actually so let's go ahead and

first say we are returning this show

dialog which returns the value of

boolean and now you see we get a general

error here saying that wait you said

you're returning a future of bull but

this show dialogue of bull is going to

return an optional so what what do you

mean so this is dark getting a little

quite correctly actually is saying that

you saying that you return a boolean but

we know that show a dialogue returns an

optional boolean so what do you want to

do about it and a way to fix this to be

append something called a then function

to the entire show dialogue saying that

if this show dialogue isn't able to

return a boolean then i'm going to

return false otherwise return the value

because i mean you may be now asking why

wouldn't the show dialogue return a

value it either has a cancel or a logout

button but remember on android for

instance you have these physical keys

i'm going to change the layout so you

see this button down here if i show a

dialogue on the screen android users can

always press this little button which

will then change to an arrow down that

they can press on it to dismiss the

dialogue so they they have the ability

to dismiss a dialogue without actually

answering a question that the dialogue

asks them and ios users can sometimes

also tap outside a dialogue in order to

cancel that dialogue so that is why show

dialogue says i may not be able to

the value that i promised kind of to

return should this or tap on any of my

buttons quite correctly okay so append a

then statement let me change the screen

so append event statement here which is

a function that gets called

should this future complete so if the

user dismisses this dialogue this future

is going to complete but it won't have a

value you see it is an optional bull in

that case so in here we say either you

if it's present or you return false

that's it okay now you see dart is quite

now what we need to also do is

the way we're gonna display this

this like pause everything you're doing

and display this dialogue modelly on the

and this dialog is going to grab focus

from everything else that's on the

screen so the user kind of has to go and

choose an item unless they want to

cancel that item by for instance

physical key on an android phone

when we display the dialog we're going

to use the build contents context and

and display the screen just like we

display like a named route so

the show dialogue function here inside

our text buttons on press it is our

responsibility as the alert dialogue to

and it's our responsibility to actually

pass a value to this show dialogue and

say hey this button was pressed and this

is the value that it returned

what you to do on these unpressed is to

context and then you'll say pop

provide your value the boolean value in

this case so upon cancelling we'll pop

and we copy this code and we go into the

on press of the second text button which

is log out and in this case we should we

say that you should basically return

that was a lot of code i understand that

let's just make sure formatting is

correct as well put commas here before

your parentheses end so the formatting

is a little bit nicer in that case

now as the caption says what we need to

the user tapping this log out button

here you see the value is a menu action

is going to um do a switch statement so

warning that we're getting here saying

the missing cause clause for log out

dart is already understanding that

there's a case statement and there's a

case in this menu action enumeration

that we're not handling and it's asking

us to do that so you could tap on this

here icon and say add missing case

clauses or you can say command dot on

mac or control dot on linux and windows

to bring up this menu also and i've also

understood from my conversations with

others on linkedin that this option is

and other editors because this is part

of the language front end actually so

it's not only a thing you can do in

visual studio code thankfully

go and add the missing case clauses

and in this case what we need to do now

is to display our alert so we're going

to say await should log out or something

should log out is equal to wait and now

we're going to call this function that

and now it's complaining saying that you

can't do wait because this function here

is unselected is not asynchronous so now

we're gonna make it asynchronous and

should log out to a string okay

so command s and let's go to our ui now

and i'm going because we're doing

devtools log i'm going to bring up the

debug console here clear it so you see

better and i'm going to press the log

out now you see our dialogue is

displayed to the user saying sign up are

you sure you want to sign up with our

buttons pressing the cancel button where

we're then going to come to the

unselected here and get the value of

false boof you see right there

pressing the same button again saying

log out and then log out here we're

going to get the value of true

wow that was also a lot of information

so i'm just going to go to my notes and

ensure that i've explained everything

now that we've displayed amnata we can

actually display a dialog to the user

get the true and false values back we

need to also ensure that we're actually

logging out from firebase as well so the

true or false isn't enough we need to

log out from firebase and the way to do

that as you can see in the code here in

the captions is firebase auth instance

what we need to do then is to call a

then we are going to do that because you

see this should log out says true if you

do have to log out and false if you

don't have to so we just made sure that

it's true okay so you can either say it

should log out or you can say if it

shouldn't log out then return

and then you do the actual log out after

this so it completely depends on your

style i'm just gonna do if should log

out because it makes more like

grammatical sense for me if i should log

out and do this then saying if i

shouldn't log out don't do this

it's a little bit of a preference but

you're free to to choose your own style

um instance as we can see here and then

and you can see that it returns a future

so let's call it and then we say wait

right and now that we've done that

uh after we sign the user out then

there's no point keeping the user in

this user interface because this user

interface is only for people who are

logged into the application and signing

out from firebase means that well you're

not logged out anymore okay or you're

not signed in anymore sorry you're not

logged in anymore signed in anymore

they could be used interchangeably sign

in or log in and log out and sign up

depends of the lingo that you prefer to

i also use these terms interchangeably

so if i say sometimes sign out or log

all right in this case after you sign up

we also want to send you to the login

screen because that's like the in in my

opinion at least it's the most common

thing to do if you sign out of an

application you then go back to the

otherwise if you for instance are

website and then there is like a

a forum website or something and

the user goes and logs out you may send

them them to not to the login page but

but you may actually send them to like a

read-only copy of all the forms

available in your in your website but

any content to display to a user who has

signed out the only thing we can display

to them is the login screen because we

don't have any other content to display

okay so upon signing out we're gonna

send you to the login screen so let's do

so we're gonna see navigator

as you can see in the caption of um

and we're saying push remove push name

and remove until and then we're going to

all right does this make sense

so let's then see if this works um

let's have a look at that uh let me also

go to my notes to ensure that i'm

great and let's just make sure that sign

out is working okay so log out we say no

just to test that that is working and

then log out and then we say log out

here and i can see i'm even using the

language like interchangeably here which

is not a good idea are you sure you want

to sign out and then a log out button

it's not perfect but it works

you're free to change this if you want

to and then if you say log out then we

should go back to the login screen

that is working but something isn't

working quite right and i'll tell you

soon but before we do that let's go to

go to here i have two terminals one for

scr cpy and the other terminal is for

doing commits messages i'm going to

bring up actually so you see it better

so what we need to do as we've done in

the previous chapter is now that we have

set up let's commit our work and we're

going to call this step three okay

so that's what we're going to do now we

are going to commit our work and we're

so let's say git status just to have a

look at what we've changed i can see

that there's only changes in the main

dark file and you can also say git if so

you can see what you've changed you see

all the green ones are new and all the

red ones are things that you've

basically removed or replaced with new

for instance this one was removed this

one was removed and this one was added

all right so quite a bit of information

here let's say it gets at all so we

add all those to the staging environment

in order to commit them and then i'm

going to say git commit with a message

and let's have a look at our logs i can

see initial commit which is step one and

then step two and then step three

and then you will push these changes or

push the commits to github all right

now i'm gonna clear that terminal here

and we also need to tag our code

remember commits are not the same thing

as tags so i'm going to say git tag step

so that pushed the tags as well great

wow that was a lot of work um

keep up with me in this chapter as we

went through all these different bits

and pieces that we had to put in place

for the log out to work but like at such

an integral part of our application that

i think it's worth spending some time

explaining how things are working also

talk about a little bit of like basics

the show dialogue and menu items pop-ups

etc etc so once we talk about them now

we don't have to talk more about them

remember i told you something isn't

and that's what we're going to fix in

the next chapter which is fixing the

login screen and i'll tell you what is

isn't working if you now go in here and

and put your password in you can see

pressing login doesn't do anything

it just logs into the application

because if you go to login view and we

have a look at the code that we wrote

let me get rid of the console here

button that was pressed upon pressing it

all we're doing is just we're doing a

print user credential and you can see

that if you go here oh i can see i

actually got wrong password so let me go

now we got the user credential here you

but still nothing worked even if you

provide the correct user credentials

it's not working as it should and by

that i mean it's not taking you to the

next step what should happen in the next

that is what we're gonna fix in the next

chapter we're gonna work on fixing the

login view so for this chapter all you

uh take care of our main user interface

done text widget that we were displaying

at the end of the previous chapter

and we have now a main ui with a

bar item on top right and pressing that

item in it upon pressing which then you

get a dialog and then if you cancel

you go back to the main ui and if you

say log out or sign out you go back to

the long view so there was a lot of work

that we did and congratulations for you

uh get ready then and whatever you want

to do get some refreshments and that we

will fix our login screen in the next

hello and welcome to chapter 19 of the

in the previous chapter we worked on log

and after we completed log out you saw

that we went to the login screen and um

that it wasn't really working as it

what it was doing is um that it was

logging you in with firebase and it was

printing the user credentials to

or the cons basically the console and we

but the login view wasn't actually going

so as you can see here it says the login

doesn't route properly it just stays

does nothing upon successful login and

that's exactly what we're going to

address in this chapter this chapter is

going to be quite a short one because

all we're basically doing is just doing

some cleanup and we're going to go from

the login screen to um the login view to

the note c and we're going to remove

print statements um and this is like

what what is gonna happen as you become

more and more of a software developer

and that sometimes you do the heavy

lifting as we did in the previous

chapter we took care of uh logout

and you learned a lot about new classes

like the buttons and the menus and

unpressed of those menu items and then

after you've done that you'll probably

spend some time to clean up the code and

this is one of those chapters that we're

so let's have a look at the first thing

that we need to remedy and that is our

let's have a look at the code i'm going

so i think we call it my nodes so here i

and i'm going to get rid of the debug

console right there and i'm going to

which i have somewhere around here

okay so you can see in login view we

have quite a lot of print statements at

the moment they just say print user not

found wrong password user credentials

and we also have a register view here

which has a few print statements so

let's go and remedy this and use log as

we talked about it before so let's say

view layout here so you see the code a

let's go and use log and if you don't

know the difference between log and

print nice drawing i strongly suggest

that you watch the previous chapters

where we talked about this and why it is

actually advised to use log instead of

and login itself isn't perfect it has

not problems maybe downsize or things

that you need to be aware of and i

highly suggest that you read the

documentations for log as well but um in

this case as you can see it's also

suggested by the analyzer not to use a

print so we're going to change that to

both in the login view and registry

we're going to change that to

using log so let's go ahead and say

import dart developer and as devtools

show log all right now i'm gonna copy

paste this in here as well and at the

same time i'm gonna clean up the code a

little bit in register view all right

okay we've done the import in login view

and register you want to save those and

now let's go to the login view and

remove all these print statements and

and we're just going to say user

credential to string okay remember print

you can see the function signatures is

object which is kind of peculiar that it

can print an optional object i mean

does it mean that i don't have to

actually pass a parameter no it has a

positional argument but that argument

value is null like this like an optional

and just pass that here so i animal

still work that's what it means so let's

have fun it can accept an optional

and remember every object has a function

called to string so this two string

functions actually coming from objects

so we can command click on it

and you'll see that uh let's see oh that

user credential but if we look at um

if we create for instance how do i

explain the tostring and where it comes

let's let's do it like this let's say we

optional object value and that is null

now i can say value to string you see

so these are the op these are the

functions and properties that any object

implicitly a subclass of object

including user credential meaning that

user credential has inherited the

function from the object class however

if you looked at the source code for

this particular two string you can see

it comes from package firebase off

firebase off the dart meaning that user

credential this class has overwritten

the functionality of tostring meaning

that it is returning its own string to

and that's this long string that we saw

we can't see it now but let me see if i

log in here so you see it poof

and you see this user credential that is

let me change the screen layout a little

this is being printed or this is being

the to string function on user

credential and you can see it looks like

this user credential and then additional

information and then prints the

additional information and that's

exactly what you can see here you see

additional user info and then there's

it should be somewhere around here

is anonymous is here credential that's

the key and then another one called user

it's somewhere in here i can't see it

really but it should be somewhere in

user password i mean to be honest if you

copied this like if i actually copied

this and brought it into its own file

it's a little bit strange that it's all

in one line but that's okay too i'm

going to search for user boom

and that is the user information you can

see user is user display name etc so

that's two string okay the reason i'm

explaining all of this is because you

need to know that print can print an

object but log can't log needs a string

so if you look at the function signature

it says give me a message of type string

um that's what we're doing here we're

saying devtools log and then user

we need to do the tostring okay

so go ahead copy this dev tools log and

let's change all these print statements

to say that that's what needs to be

change all of those in your login view

so that you don't have any more warnings

save your login view and then go to

register view and do the exact same

and for weak password do the same thing

email to the same thing and then invalid

email entered and we have no other print

statements and what you could do i mean

in my notes here i don't see

anywhere that i'd plan for that but i

we could just improvise a little bit and

what i really like to do when i'm doing

like cleanups like this in my source

code i like to go and make sure that

there's no print statement statement

anywhere else because it just feels like

when you're clean on cleaning up your

code especially if you're doing

something as simple as what we're doing

here it is worth spending maybe just a

few more seconds and making sure that

you're applying the same cleanup in the

entire source now sometimes your source

code may be so big and complicated that

you changing even a simple bit of code

may affect the source code in such a way

that you may not know if you're breaking

and for that we need tests unit tests

widget tests etc but if that is the case

you don't have to do that but in this

case since our application is so new

we've just created it there's not much

logic in it i think it's worth maybe

in visual studio on mac or ctrl shift f

it was just here to go on linux and

windows just to go go to this global

search and just search for print

and i can see here that we don't have

any print left in our source code so we

don't have to change anything else all

the prints seem to have been in the

login view and in the register view so

don't worry about that anymore okay

um so now what we need to do is to

yeah basically we need to now focus on

what we wanted to do in this chapter

that was a side kind of like a

side note there to clean up our print

statements what we need to do in this

chapter to make sure that we can go from

notes view i believe is what we created

and one of the previous chapters um

is it here in the main dart perhaps

so let's do that and you remember from

the previous chapters where we oh we

if you remember from one of the previous

chapters where we talked about named

routes and named routes as you can see

that are defined in the main function

now remember the main function

when you do a hot reload keep that in

mind so we're now going to modify our

routes and allow and create a new route

as you can see here it's called nodes

actually it should be node slash

so i'm going to hide this caption

and change it so that it is actually

um and i'm going to bring it up

correct route that we have to create

so let's go in here and create a new

push this route on the screen will get

on their screen okay so let's just say

as a string and notes slash as the

captions suggest and then you have to

provide remember the routes was a map

where the keys were strings and the

values had to be functions that accept

the build context and return a widget

it's a little bit of a string syntax but

you'll get used to so the value should

accept the build context as you can see

here and it should return a widget so in

this case we return the notes view okay

okay that part is done now so

what we need to do now is to ensure that

upon pressing the login view sorry upon

press upon pressing the login button

that we are doing a code similar to

what we did in um if you look here in

our login view when we went to register

do you remember this navigator of

context push name and remove until okay

we need to we need to do that and

when we did this initially when we

worked with push name and remove until i

don't think i actually explained

entirely what push named and remove

as its name suggests it pushes around on

the screen so it says that you have a

screen and you want to put something on

top of it okay so pushing is something

that is very popular in mobile

usually i mean after ios came um

it became very popular that you had a

screen you press the button and another

screen got pushed on top of that screen

so this has been available i mean in

many other places even web browsers are

not doing it these days and even nokia

phones in in the good old days were

doing the same thing but it wasn't as

popular back then and it wasn't like

coined as a term of pushing until ios

and android became more and more popular

pushing is the concept of having a

moving and pushing physically another

so that's what push means in push name

all right the named part of this

function means that you have a named

route so you have defined a route

somewhere such as your main screen here

and you are trying to push that using

its name so you're not just pushing a

new widget out of nowhere okay so that's

the part that says and remove until

if you have for instance one screen here

another one is pushed on top of it and

now you want to push another one on the

what the remove until says it says if

you want to push this one on the screen

i'm going to give you the chance to get

rid of the existing screen on the stack

so i remove these first and then i'll

push yours and this is kind of useful

for for instance if you're let's say you

and then you press the login button and

in the in our case when the user

credentials are correct if we then

if we then want to go to the notes view

we don't have to keep this logging view

on the screen so if this login view is

here what we could do is to push the

notes via on top of it some nodes view

is always sitting here but then you as a

programmer not the user as a programmer

login view is sitting behind this so

that's not so good because once you're

and you're on the notes view you don't

need this view anymore you don't need

the login view sitting there and

consuming memory so that's what remove

until does because it gives you the

opportunity it passes you see a route of

dynamic and it says let me know when you

move removing things from the screen

before i push yours and us returning

just remove everything don't care about

the routes that are on the screen at the

moment and don't care about the routes

that you're telling me about just remove

everything and go to this register view

all right that was a lot of information

now we need to do is to go to our login

view which we are right now and upon

getting our user credentials here what

we need to do is to send the user to the

so i'm just gonna check in my notes that

i've explained everything to you before

and yeah that seems to be the case so um

let's then go ahead and do that right

what we're going to do is going to get

rid of this dev tools log here okay

let's then go in here and say

of and remember we have a build context

and we're going to say push name and

uh like this and our new route name is

actually what's it called notes i think

we call it right in here yeah slash note

so put put that in there and in here you

this is one thing of also i haven't

mentioned in the previous chapters but

in dart it is very important that you

a comma and a comma you can see here

is placed usually between parameters but

also the last parameter is suggested to

have a comma because as you can see here

the dart formatter right now isn't

these two parameters into two separate

lines of code and that's what we usually

do in dart you can see here for instance

when we did a wait on firebase instance

sign in in the last parameter we had a

comma if i remove that the code will

actually be a little bit uglier in this

it looks like this but if you put a

comma at the end of your last parameter

dark is able to break your parameters

each parameter and its value in its own

line and that's like a usual convention

in dart so if you see something like

this that doesn't look quite right put a

comma at the end of the last parameter

and press command s for dark formatter

and at the moment we're not using

the user credentials um at all so what

we could do to be honest with you is to

get rid of that so all we'll do is we

say firebase instance sign in with email

and um that's it because this whole

thing is in a try block so if this thing

doesn't work properly then we'll come

well this is great actually now we're

um login view to the notes view but

you'll be a bit disappointed to see that

this isn't going to work as it should so

uh ui a little bit here and then press

and you'll see we get an error here that

says unfortunately on unknown route was

it's quite cute that they say

that's what this caption also tells you

you see i i talked about it a little bit

when we kind of started with this

chapter that we said that we're going to

name route in the main function

this is i told you that this isn't going

to really work so well the reason is

again the main function isn't going to

rebuild when you do hot reload so

in order for your changes in the main

function to take effect you need to do a

hot restart so what is happening here is

that you've defined everything correctly

everything is done right there's nothing

wrong in the code itself it's just the

way we are executing the code that is

wrong and now you have to do a hot

restart for flutter to be able to pick

up your changes in the main function as

well okay so hot reload is not going to

do it so you need to do a hot restart so

i'm going to do hot restart here

we come here and now you see we're in

we are actually logged in from the

and we come here now i'm going to enter

foo bar baths and please don't

use football bats as your password i'm

just doing it for the sake of simplicity

and now we say login and you see that by

doing login we come to the main ui of

the application so and as you saw

pushing in android using material design

pushing on ios let me let me demonstrate

it one more time for you so you'll have

good look at it in the login view enter

through barbados and then do log in and

before you do that just have just make

sure that you're focusing very well on

the screen i'm going to bring it up a

so you'll see better um look how this

main ui of the application won't

actually be pushed but it instead will

be kind of like moved from the bottom of

the screen to the top while that

previous screen gets faded away so

ios and android are going to work

differently differently but the

concept is the same so now that the main

ui is pushed to the screen where an

android is displayed on the screen the

login view has disappeared and been

removed from the view stack okay

so that's great that's all we have to do

in this chapter so i hope actually you

are happy with the results and that we

didn't have to do too much now what we

need to do also we need to make sure

that we do like we did in the other

chapters so let's go ahead and

let's go and commit and tag our changes

all right so we if you look at our tag

if you say git tag we have now step one

chapter in this chapter we're gonna

commit our message commit our changes

and tag it with the tag name of step

four so if you look at git log we did

step three in the previous chapter now

we're gonna do step four so let's say

all and you can see it was just a few

now let's um i'm not sorry i'm going to

i'm also going to say git commit

let's push our changes to uh github and

also let's get a push our tags

so if you say git tag now now we have

four tags and if we do its log

you'll see we have step two three and

four and the initial commit which is

step one all right well done that was

great and work for this chapter quite a

short chapter and sweet um and now we

need to get ready for the next chapter

as you can see in the caption here says

we need to clean up our routes since

and that means that you can see here

we've defined our routes login register

nodes but also in the login view we're

like redefining we're saying that

actually not redefining we're trying to

like go to the notes route but we're

typing the entire route name again and

this is usually in programming not a

good idea like if you have strings

flying all over the all over the place

like one is defined in the main dart the

other one is called in the login view

and this something similar is used for

instance in the register view as you can

usually this means that you need to um

bring these into one central place and

kind of reuse them and that is exactly

what we're gonna do in the next chapter

leave it like this and i'll see you in

hello and welcome to chapter 20 of this

in this chapter which is going to be a

very short one i think it's going to be

the shortest chapter of all the chapters

we've done so far we're going to do some

you can see that uh i mean i'll show you

what state we left our code in in the

this is what we've done so i'm gonna

you will see that um the state that we

left our project in was if we go to our

main dart we had some routes defined i'm

do it like this you'll see it better we

and one was called a login which the

register view actually uses to send the

if the user had already registered and

about that without showing it so let's

go here let's go here in the register

view so if the user ends up in the

their email and password setup then they

can click on this or tap on this button

that says already registered log in here

register view here navigator of push

name and then goes to the login route

which is defined in main art and kind of

the same thing happens in the login view

here so if the user doesn't have

if the user hasn't registered for our

service then they can actually tap on

not register yet register here button

and that's the register route and the

third route that we have is the notes

route which allows us to send the user

from the login screen to the main ui of

the application which we just call at

resides inside main dart and i'll just

have a look at my code here and just to

what i had intended yeah so we haven't

refactored notes view and we haven't yet

let's talk about hard coding now

if you're not a programmer like if you

don't have a software development

background you probably don't know what

i'll i'll kind of give you the um

i'll give you example maybe in different

be relevant for a programmer let's say

you're working in figma and you're

working with a design so you have a list

of items to display on the screen and

you create these list designs like you

have a little cell that should be

displayed inside a view then you go and

in 10 different places and then

you talk to the team about the design

that you've created and then they say oh

you'd be really great if this label was

a little bit bigger then what you'd have

to do is to go to every place that

cell and you have to change the label a

better way of doing that in figma if

you're a designer would be to create a

component and then create instances of

that design component in various pages

so you need to update something then you

need to just update it in one place

even if you're not coming from a design

background and you're working for

instance as a project this is a product

owner or a project manager you may be

excel sheets and you're creating maybe

graphs now if you create a graph from a

you probably want to reuse that graph in

other places so if someone says okay can

i get like all the graphs available in

the project then you don't go and create

the same graph over and over again you

kind of want to refer to the same sheet

google sheets or your excel sheets so

the concept is the same you don't want

to repeat yourself and that's what the

mistake that we've done at the moment in

our source code in that we have our

routes defined in one place however

where every word we're gonna use these

routes we're writing their names again

that most programmers do not like

when you become more of a seasoned like

a senior developer then you try to avoid

these things because if we now go to our

main dart file and change this login to

just slash login then we have to search

everywhere in our project for a name

route called slash login slash as it was

before and change that to this new form

that's hard coding and that is why

developers don't like it and i suggest

that you don't like it either

so uh what we're gonna do in this

chapter very quickly hopefully we can

uh be done with it soon we're gonna

create a new file in our project is the

first file of its kind that we're

creating where we're going to put our

constants okay so constants as you know

from where we talked about dart are

values that don't change during the

and they don't change during the runtime

either so these are our route names

because they're always constant they're

no one is going in there and changing

so let's go ahead and do that as a

caption says here let's go create a fox

under lib under folder called constants

and then routes and as i showed you

before you don't have to create the

intermediate directories in this case

constants before you create the route

start file what you'll need to do is

just right click on lib where you want

to create the constants and then the lib

sorry the constants folder and then um

route start file just right click here

say new file then say constants um if i

and that will create the constants

folder intermediate folder for you okay

what we need now is to define as the

caption says here we need to define

three routes one for the login route one

for register and the other one for the

notes route so let's just say

and we just say that's equal to login

slash i'm gonna copy paste this and i'm

just gonna in this second one just say

uh register route as the caption

suggests and then the notes route okay

and in here i'm going to say register

and in here you should say also notes

okay so now we've defined these three

but what we need to do now we've defined

them but this is not enough what we need

to do is to actually go and use them so

let's go back to our main dart file and

in here instead of using login we need

to use a login route right and you can

see now visual studio code smart enough

to understand that this is a symbol that

but this symbol right now isn't

available in the current context because

we haven't imported that constant

allow visual studio code to auto import

that you can see all of a sudden the

in my current context and if i go up

here then i should be able to see that

visual studio code has imported this

file for me but if you're if you're

working with veeam or if you're working

with android studio and you're not

uh to import you can always go to this

uh command dot or control dot depending

on your operating system and just say

editor isn't smart enough to do

importing in this way you can import it

yourself so you can just say

package then the name of the application

which is my notes and then you'd say

constants slash routes dot darts so

there you have three ways of solving the

same problem i usually do auto import so

i don't have to type all of that um and

i'm not gonna explain this more than in

the upcoming chapter so you have all the

tools necessary in order to be able to

fix a problem like this okay so in here

i'm going to use register route and

uh route start is now imported here

then i'm not going to have a problem and

i don't have to auto import anything

okay and for notes i'm going to say

oh that's great now we've defined them

in our main function however we still

have a few places where we're doing

routing and we're hard coding those

routes so let's fix first our notes view

which is the main ui of the application

so if i type here pixel tab gmail.com

and we're getting some oh foobar baz

in here when we do log out that's where

we sending the user to the login route

so let's change that as well to say

login route okay so that's one place

uh i'm gonna then say log out here poof

so that's fixed now the other place we

have to fix is in the login view as you

where we press the not register yet

register here button so let's go to the

i'm going to get rid of the explorer

in this button not registered yet let's

you see we're sending the user to the

register route so i'm going to send them

instead to register router and you can

see you should code smart enough again

to do auto import so i'm going to take

and also we have another route here

which sends you to notes where you

have successfully logged in so let's

and now the other place that we have to

fix is in register so go to your project

explorer and then go to register view

and have a look at where we're doing

if you now search for push name and

remove until and then show the results

if you click through them you shouldn't

have any routes that is hard coded okay

register route and the login route so

now we fix this and just remember

because we now have changed the main

function here and we have some routes

here do you have to do hot restart in

order to see your changes but

if everything's working according to the

plan and that we didn't like to make any

wrong choices in our rat names and that

we gave them the same name or anything

if everything is working like it did

before then you shouldn't see any

changes in here so if you enter your

information like you did before

and i say foobar about then i should be

and i should be able to go to register

it's working exactly as it did before

all right great stuff that was a quick

chapter as other chapters since now we

have made some changes and we've

actually made the code better and we've

tested to make sure everything works

fine it's time to commit our changes as

you can see the previous chapter we

committed our changes as step 4

and in this chapter we're gonna commit

our changes as step five and we're also

we're also going to tag it like we did

layout as well so you'll see the

terminal a little bit better i'm gonna

do it like this gonna make the terminal

bigger even so you see it even better

so let's go ahead and see what the

status is i can see there are lots of

changes as you can see here it says

you've made changes you modified these

existing files and now all of a sudden

there's a new folder as well so what i

like to do in these cases when there is

a new folder i like to do bits add all

because this adds all the files and

so you can take it at all and if you say

the new folder including its content is

now added to the staging environment or

okay now we've staged so now let's

commit and we say we said that we are

going to commit and tag as step five

so let's say step five um and then get

um step five as well get push your

and then give push the tags as well

all right so if i say you tag now we

and if i say gitland we have step five

four three two and then the initial

commit which is pretty much step one all

great stuff well done for going through

this chapter so fast as well together

with me and what we need to do now is to

get ready for the next chapter

and just to give you a little preview

what we're going to work on is to have a

look at our error handling in

specifically the login view so if i make

this a little bit smaller so it's more

digestible you can see at the moment our

error handling the reason i put

quotation marks around it is that it's

not so much of an error handling to be

honest with you what it is doing is just

says if an error of this type happens

then log this message to the console a

normal user sitting with their phone

they don't have access to logs they're

not going to see any logs so logs are

very very much useless for them and what

we're going to do in the next chapter is

actually display meaningful information

grab your refreshments if you want to

and i'll see you in the next chapter

hello and welcome to chapter 21 of this

in the previous chapter as you remember

we talked about cleaning up the routes

that we have in our main function and we

put them inside their own dart files so

that they are separate from um so we're

basically not hard coding hard coding

them in different places of the

we talked about what hard coding also is

if you're not coming from a software

development background and why it is

usually a good thing not to hard code

your strings and spread them around in

in this chapter we are going to focus on

error handling in our login view to

start with if you remember our login

actually i don't have to say if you

remember because i can bring up the code

so we can have a look at it together

i'm going to bring up scrcpy here as

the android phone working okay

so i'm going to also change a little bit

screen layout so if you remember uh we

have our login view right here probably

have to move some things around here so

it becomes a little bit better layout

let's go to login view and we have then

lock statements here should anything go

if we could sign in with an email and a

password then we were pushing the notes

but if there was a problem with our

firebase authentication and we got a

we are simply at the moment logging that

information to the debug console and

that is not good enough because should

any errors happen for instance if the

current user couldn't be found or that

uh your end user will not receive these

logs because they're not running this

application beside visual studio code or

except your actual users are going to be

running the application on a normal

telephone such as an android or an ios

so that's what we are going to do in

this chapter we're going to clean up the

logic for our error handling so um

so before you begin with this chapter

just make sure that you're inside your

login view as we are right here and then

ensure that your application or your

user is logged out so if you're in the

main interface of the application or

you're inside the notes view as we call

it ensure that you go to the menu and

then you log out of the application also

make sure that your telephone or your

emulator simulator also has internet

you can actually hit firebase back end

so as you've seen in our login view and

register view we have logic that tries

different kinds of errors that may arise

for instance in the registration view we

have weak password handling and we have

email already in use or an invalid email

and so here we have three error handling

and also in login view we have two error

aside from these we also need to handle

the case of any other exception that

might arise in this try block and we

don't have that at the moment you can

see we're only catching firebase off

exceptions so we have to have a generic

catch block at the end of our try

statement in the login view

and another catch block which is a

generic catch block at the end of the

try statement on our register view three

auth exceptions plus and a generic

exception handling here four total in

plus two here six and a generic one here

seven so we are going to handle seven

types of errors that might occur during

login and registration and for any one

of these we are going to display an

alert to the user so we're just gonna

alert the user that something has

happened and it needs to be taken care

the end of your main dart file and you

can see we already have a future bowl

show log out dial again this is a log

that you can see is an alert dialog that

at the moment just returns a boolean

future void as the caption shows here a

function that says show error dialog and

it has a context and a string to display

to the user so we're just going to use

it generically generically from anywhere

so for now i need you to go to your

and at the bottom of the login view

we're going to create the function

signature for this so let's just say

and as i've called it here show error

dialog and we're going to get a build

context called context and then we're

also going to say string text okay

and remember you can always put a comma

to make sure that the dart formatter

actually formats your functions

show error dialogue uh what it needs to

do all it has to do is just to create a

dialogue and then display it so to do

you i mean you may think that you always

start with the creation of the dialogue

but in fact you need to first think

about returning the result of the

dialogue which is in cases of void so

and the context is available for you as

a parameter to your function and also

let me should i make this a bit bigger

or is the size okay i think this size is

now that we have that let's then go and

say that we want to have a builder

and your builder i'm going to get help

from visual studio code to complete this

you see it takes the um it brings the

build context in as a parameter and it

to return let's get the documentation on

it and expect you to return a widget and

the widget that we're gonna have to

display in our short in our show dialog

is an alert dialog so let's go create

for the title of our alert dialog since

this is as you can see from the

function signature here that says show

air dialog this is this dialog is

explicitly going to be used and

exclusively gonna be used for displaying

errors to the user so something has

and we need to handle that error okay so

we are going to in this case write a

specific very specific title for our

alert dialogue that the user understands

something bad has happened and it needs

so for the title we're just going to say

a constant text remember the title

property if you just move your mouse

over you can see it's a widget it's not

a string you actually can configure the

title to be whatever you want so this is

flutter almost everything is a widget so

you'd expect oh the title should just be

a string but no you can configure the

title to be exactly what you want so it

can just be an icon if you wanted to so

so let's in here in the text say an

and then we're going to go for the

dialogue remember the content comes in

here as the text as a string so let's

widget and we just say we display the

and let's for the actions then say we're

gonna create a text button remember the

text button has two parameters

file the other one is unpressed the text

button always has to have both these

what do we want to do on the unpressed

we're going to just create the um

function signature for it and for its

child we're just going to say text

and uh let's just do some formatting in

there so let's think about what we need

to do on the on press just remember this

dialog is just going to be displayed to

the user the user is just going to get

the information such as we're going to

display an alert saying that oh

um your password is too weak or uh hey

this user already exists or this email

already exists or incorrect password so

it's just text and then ok button so

pressing the ok button the only thing is

going to do is just going to dismiss the

alert dialogue so only thing you need to

do in here is just to say navigator of

your context and then you'll just pop

this ensures that your dialogue then

i've done some videos about this before

on linkedin and twitter i've done live

videos about this where we talked about

a better way of displaying error

this way of displaying error dialects is

pressing of the button dismisses the

dialog however sometimes you may need to

have persistent dialogue displayed on

the screen even when you push new

screens on top of other screens so

it's a little bit strange that a

dialogue is doing navigation in that it

a better way of doing this is using

overlays but overlays are a little bit

complicated for this part of the course

so we're not going to talk about

overlays right now let's just say now we

have a generic dialogue that can display

a text with a title of an err occurred

all right so that is in place now and

now let's go to the next item that we

and that is to handle user not found

sorry i just need to have a look at my

notes to ensure that i'm telling you

everything that i i was supposed to tell

all right so in here on your login view

in the case that the error is used or

not found we are going to display an

alert to the user using our new function

okay so in if e code user not found

instead of devtools log we're going to

show error dialog the context is already

available for us because you see it is

your build function already so you don't

have to grab it from anywhere else it's

available right there and for a text

we're just gonna say user not found okay

and close the string you can see now if

i format this um code these two

parameters are displayed on the same

line as i mentioned in the previous

chapter all you have to do for the dart

formatter to be able to format this code

correctly is put a comma at the end of

the last parameter and just press

command s and it will format it again

for you so each parameter goes into its

okay um in case of the so now that we've

handled user not found okay so we could

literally test that let me do a hot

restart just to ensure every piece of

code is injected into the binary that is

let's go and place an email that doesn't

exist so that we get the user not found

and let's just enter some password and

then i'm going to press the login button

and you can see now we get our error

displayed on the screen that says an

error occurred user not found and you

can press the ok button to get rid of

um the dialog and getting rid of the

dialog is happening here you see

pressing that button says navigator of

that's what is happening there

all right great stuff what we need to do

now is to handle wrong password as well

and this one is going to be a breeze

because we've already handled user not

found so what you can do is copy and

paste this code that was placed here in

the user not found statement and bring

it here and replace this devtools log

wrong password with that and instead of

saying user not found what we're going

to say is going to say wrong credentials

try to log in you can also do that at

home or wherever you're watching this

course from you can enter the email

address of a user who's already

registered with your application so like

if you're testing you may enter the

email address of the person that or your

own email address if that's what you're

testing with but enter the wrong

and then press login and now you can see

that message being printed to the screen

is handle other firebase authentication

and you can see here in this case we're

saying if there is a firebase auth

exception and if the code is used or not

found or if the code is wrong password

however there might also be an exception

that you haven't accounted for and

although these are the most known error

codes that you can get there's always a

possibility that there will be another

error code in the future maybe not now

that you will receive from firebase

which you haven't accounted for in that

the code then goes in here and says oh

the code is not user not found

is not wrong password and it will just

fall through meaning that this entire

code will this entire catch block will

not be able to catch the actual

exception and your code will crash

so it is very or you will actually get

it's very important that you

think about your exception handling

early on so you don't send out a code to

production that doesn't have proper

that's what we're going to do

so two things we need to do we have to

handle other exceptions that might occur

and also other firebase off exceptions

actually we need to first do this so

let's first take care of other all

firebase auth exception so place an else

statement in here and then in that case

like i'm doing here and for the error

we're just going to say error and then

now you may not be familiar with this

syntax from before because maybe i

haven't explained this before but this

is like string formatting and guardian

is very elegant it's also available i

mean kind of the same thing is available

in almost every language that i work

with swift it's available in python when

you're working with django it's

available in ros it's available in

you're basically escaping a string and

injecting some actual variables inside

so in python for instance you would do a

f which means you're formatting and

and you would i think you would say

and then you would put your value at the

end something with a percentage sign

something like that and in javascript

back quotes like this so and in swift

you will do something like this uh e

code like that inside a string so this

is basically a way for dark to inject an

in the case of firebase auth exception

the e becomes then a firebase auth

exception of this type has a code of

and this is us basically injecting that

string inside our own string so every

code then will be prefixed with the

value of error and then a double double

column here and then space and the code

now that we've done that we also need to

handle the case where the exception is

not a firebase auth exception and that's

the next point that we need to talk

so in here uh at the end of this

on firebase auth exception block and if

you're kind of like unsure where things

start and then you can see that as you

end of this curly bracket here you can

see that visual studio code has

highlighted this curly bracket right

there saying that this is the beginning

of the code and even if that's not

enough for you you can always go to

gutter on the left hand side and like

here here you can easily see them you

can we not collapse this entire if

no we can't collapse that entire thing

but anyway so at the end of this we need

this is a generic catch block meaning

the exception that occurs in the try

statement is not a firebase auth

exception then go into this catch block

and in this cache block now e you can

see is an object so it's not like a

normal exception anymore it's just any

object because if you remember when we

talked about exceptions in dart you can

throw pretty much anything in dart as an

exception you can even throw an

that's why it's telling us saying that

any except any other exception other

than this is just an object it's not

known to me i don't know what it is so

it's up to you now to display that error

now if you remember from before from the

previous chapter objects all have a

so that's perfect then we can go here

let me expand these so that they don't

become a little bit cryptic like they

and paste that code to display a show

error dialogue again in here also we're

we we're handling wrong credentials with

handling any other error that might

arise and also sorry any other firebase

of exception and any other exception in

general that might arise during logging

that was a lot of information i

understand and i move past this quite

fast since when we talk about one thing

like we've already talked about

displaying dialogues i don't think it's

worth your time and my time to spend too

much time explaining all of these over

and that's why i move past these

what we need to do now is to do some

cleanup because you see now we have our

sorry login view dart file here and the

m in visual studio code means modified

since we last committed this into git

and we have that file however we also

have the show error dialog that is

sitting here that is also going to be

useful for the register view however

it's right now just sitting in the login

view so if register view wants to then

use this same code you will have to

import the login view and then use this

feature it's a little bit wrong this is

supposed to be like a generic show error

dialogue and it should be available for

pretty much any piece of code that needs

it so what we were going to do as a

caption says here we're going to create

um and folder as i can see under lib

so open your project explorer under lib

go and create and you can see here we

need to create a file called show error

dialog dart and it's it needs to be

a folder called utility so i'm going to

right click on lib and say new file and

i'm just going to type utilities

and go to your login view and grab that

uh for show error dialogue uh poof

however you cut in your operating system

in mac is command x in visual studio

code and bring it into your show error

dialog file all right we're gonna get a

lot of uh errors but as i've explained

in the previous chapters we can also

import these things material dart to get

rid of almost actually all of those

errors so that was fantastic

now that we've done that you can see

visual studio is already showing this

tab the login view as having an error

and that is because login view is using

show error dialog but now that we've

removed show error dialog from there it

doesn't know where this show error

so what we need to do is to use our new

file in the login view dart file

and you could do that you could ask

visual studio code to help you with this

and you could just say import library

that's it it imported it for us

now that we're we don't have any more

visual studio code is helping and saying

you're no more using you're no longer

using the dev tools or the dart

what you can do is just to safely remove

that and clean up your imports as well

that is working fine and we can just

confirm that so i'm just going to enter

with the wrong credentials and just to

ensure that we're getting the dialogue

now that we've done that i'm going to

change the screen layout a little bit

and what we're going to do is that we

need to wrap up this chapter we've

cleaned up our error handling and we

need to just make a commit remember

pretty much in every chapter from a few

chapters uh back onwards we're to commit

our code at the end of the chapter just

to make sure that you have traceability

for for your code and this is what you

will need to do even if you're working

for instance actually especially if

a team with other people doing flutter

code or any other code you need to

ensure that your code which is ready or

even if it's not ready it is committed

even if your code isn't ready you can

commit it into a specific branch but you

should never leave your work day

without committing your work remember

so let's now go and commit our work i'm

gonna bring up the terminal a little bit

here so and you can see that the

previous chapter we did a step five

and in here we're going to commit our

work as step 6 and also we're going to

so let's say git status you can see

utilities is a new folder i'm just going

to say git add all i'm going to increase

the size of the screen as well so you

make your studio code a little bit

and get add dash dash all and then git

status now you can see these are staged

for committing and i'm going to commit

after doing that let's tag it as well as

um and get push our changes and we're

all right that is absolutely perfect

so that was that to be honest with you

for this chapter so this was a quick

chapter as well and that's completely

okay actually quite refreshing to have

these short chapters for me as well

so now that we've done error handling in

we also need to clean up our register

view you can see our registry has kind

as login view had at the beginning of

this chapter in that we have a lot of

error like dev tools log stuff in here

which aren't so useful so for the next

what we need to do is to ensure that

we're logged out of the application and

that we can go to the register view as

we can do here so that's where you need

to be for the next chapter and before we

with the course to the next chapter so i

hope you enjoyed this chapter and i'll

hello everyone and welcome to chapter 22

in the previous chapters we've been

talking quite a lot about login and

register and email verification and as

you saw in the previous chapter and we

have some problems still in our register

view in that when we come to

error handling we're still doing logs

basically instead of using our new

function that was called show error

and also our register view basically

isn't really able to send us to the

correct place after a successful

registration you see we have email

verification set up in that every user

who registers also needs to

verify his or her email before entering

the main ui of the application so if

that is the default behavior in that a

newly registered user needs to verify

their email perhaps it would be best

send the user right after registration

to the email verification view and these

are the things that basically we're

going to solve in this chapter fixing

our log statements in the register view

and also sending the user to the email

sending the registered user to the email

verification view right after

so these are the goals of this chapter

so you know and i'm gonna bring up my

visual studio code to the screen so you

can also see it i'm gonna bring up scr

cpy to the right hand side so you see

you see that too position these windows

the first task that we we need to do

here is to make sure that we're using

and if you haven't watched the previous

chapter that's what we did in one of the

previous chapters that we talked about

this uh file here in utilities show

error dialog that increase the size of

the window so you see it better

so this show error dialog is a generic

has a title that says an error occurred

and also a text of your choosing

so let's go to our registry view as the

caption says here i'm going to minimize

the terminal here and get rid of the

and let's go to this weak password and

show error dialog and you can see it's

it's going to auto import it for us so

let's say show air dialog with that

and i'm just going to in this in the

we need to just say weak password okay

so that part is done and you can also

put a comma at the end of the second

parameter just to make sure that it is

clean but remember also that show error

is an asynchronous function so if you

move your mouse over it you'll see that

it says future void so by just calling

show air dial like you're not showing

the error dialogue you're basically just

telling the short i like to return the

future which in turn then uh can display

the error dialogue if you await on it so

after doing that let's remove our dev

devtools log from there from the weak

now what we're going to do is to copy

this code that we wrote here and go to

email already in use and display another

error dialog in here using the same

exact code and i'm just going to say

email is already in use okay

so that's for email rna news and also

for invalid email we're going to say

let me have a look for invalid email if

um this is an invalid email address

and i can see that we haven't really

handled other exceptions that might

occur because you remember in the login

handling for instance other uh

other exceptions that might occur like

firebase off exceptions that we did in

an else statement there and also we did

a generic catch statement that catches

any other exception that is not a

firebase auth exception and i can see

now we haven't done that in register

view so let's go and take care of that

so in this else statement we're catching

any other firebase off exception that

might occur okay so i'm just going to

and dollar e code okay so that's very

similar to what we're doing in

and i apologize i could just see that

you couldn't see the code because it was

hidden behind the caption but now you

can see it so i'm putting an else

statement here and then i'm saying

basically a weight shorter dialogue and

that's for if you if you look at have a

curly bracket right here which you can

now see this purple one it it starts

here because it's the beginning of where

we start catching firebase off

what we also need to do is put another l

another catch statement here which

catches any other exception that is not

a firebase auth exception okay

so we've covered this in the previous

chapter when we talked about exception

handling in the login view so i don't

think i need to explain that again um

okay so what we're going to do in here

we're also going to show the error

dialog in this case as well but for the

message we're just going to say e2

similar something similar we did in

our login view actually exactly the same

okay that was great so now we're using

short error dialog instead of log in the

basically i don't think we're using dev

over using devtools login here i don't

think we need to do that anymore so we

and we can also then get rid of devtools

it's gonna have a look at my notes a

little bit just to ensure that i'm

telling you all the information that you

um now that we've done all of this we

you can see as the cache that says after

every registration we need to confirm

the user's email and that is like the um

newly registered user in application

a newly registered user cannot have

already confirmed their email because

it's just not possible the two don't go

together a newly user a newly registered

user hasn't had their email address

registered in our system therefore has

not received a verification email during

this is a pattern that we need to

basically help our users with so after

every successful registration we're then

going to automatically send the user to

the verify email view and if you

remember from the previous chapters we

have this verify email view right here

i mean it doesn't necessarily have to be

a stateful widget i can see it's not

doing anything stateful but we've just

left it that state will stay full widget

and it can just be like that for now

um but we can also turn it into a

stateless widget if you want to

so that's for the pattern of what our

users are doing with the register view

uh oops no we are actually on the

um okay so what we need to do now is

since we're gonna send the user from the

register view we're gonna send to the

verify email view we need a route for

that and if you remember from the

previous chapters we're defining our

routes now inside this file lib

and we've right now defined login route

register route and nodes route

then we need a new route for the verify

email view so let's go ahead as the

caption says in here and just type that

slash verify email like that with a

now that we've defined the route

we need to then go excuse me we need to

go into our main dart file so i'm going

to close this file close this file and

then command p on mac in visual studio

or or control p in linux and windows and

in your main.dart you remember all the

routes were registered inside the routes

parameter of your material application

so let's go ahead and register the um

email verify email wrap here

and we say context and we just say const

and so that's also then registered

inside the main function okay

remember anything that you're doing

inside the main function is not going to

be reloading when you do hot uh

hot reload so you need to do a hot

restart here in order for for those to

for for those changes in the main

function to take effect so i'm just

going to do a hot restart here

let's now that we've registered that

let's go to our register and now that

we've registered there are so many

registered words i'm throwing out there

so i just want to clarify now that we've

registered to verify email routes in our

routes in main dart we need to go to the

register view and use this verify email

route in there after a successful

i'm going to close this and i'm going to

getting the user credentials and then

assigning it to this user credential we

don't have to do that anymore so let's

we are not going to actually use the

returning user credentials upon a

successful create user with email and

password we're going to go to the next

line automatically because we have a try

uh we're gonna show the verify email

uh verify email around in here and what

we're going to say is to say navigator

and then we're going to say push named

and you see in this case we're actually

going to say push name instead of using

the other functionality that says push

and the reason behind this is that

let's say that you enter some email in

here and then you enter some password

and you click the register button or you

and we send you to the verify email page

here you can verify your email et cetera

now in there if you if you realize that

oh i register with the wrong email you

need to be able to go back to the

register page so in order to avoid

having all these buttons that go send

one user from one page to the other it

would make a lot more sense if he from

the register view could just push the

new uh email verification route so we

don't replace the entire routes like the

register page with the new route so

basically the desired effect here is

that our register page is gonna stay

right here and then we're gonna push the

verify email route on top of it if the

user in the verify email route realizes

that they've done something wrong with

the email address then they can just

press the back button on the top bar and

go back to the register page so that

way of navigating between screens so

that's why we're using push named in

so i'm gonna say push names and push

name and and then in the name we're just

email route oops and verify email route

i'm gonna do a command s right there and

then let's make sure that we can put all

of this in action all right so i'm gonna

hot restart just to make sure you

change in our main function so if you

forgot to do hot restart please do that

now um so that your changes can actually

take effect from the login view which is

the first view that the user sees we're

gonna go to the register page

and inside this register page i'm going

to register with a new user so since

i've already registered my user and i

can actually go to firebase console so

the user which i usually use is already

registered with this application so my

let's go to authentication and i can see

pixelityab gmail.com is already

registered so i'm going to register with

a new user in here i'm going to say

and the password is foobarbaz i'm just

going to choose here and please don't

use this password in production for any

of your accounts anywhere at all this is

just a bad idea i'm using fubar bass for

consensus consistency and and for the

sake of simplicity in this project so

because for me it's a lot easier as i'm

typing and writing all the passwords

over and over again just to use

fullbarbass but this is not a good

password so i think just to make this

um now i'm going to register this user

after a successful registration now

we're ending up in this verify email

screen and this is really good

there is a way we can actually make this

better and let's go to firebase here and

i can see now that user is already

registered here you see and it has a

and here's the last sign-in date okay

how can we make this better you see

if this is the natural flow of going

like when the user is in the register

page or the register view and they

always end up in the verify email page

the way that we can make this better

that upon successful registration right

is that we actually send a verification

email to that user because otherwise

what you're creating you're creating a

logic for the user that they have to

take an extra step in order to verify

their account so they come here and now

they have to press another button but it

would be really good if you actually did

that button press kind of for them

before we went to that screen so

we're not actually going to physically

like tap that button for them but we're

going to execute the same code that that

button executes for the user okay

so that's what we're gonna do now so um

as the caption says in here in your

register view right before you navigate

to the verify email route ensure that

you get the current user basically so

instance i believe and current user okay

there is a function called send email

verification and remember your user is

an optional user and that's why you're

operator here which is kind of like a

moustache or something i don't know what

you want to call it some some people

call it elvis operator if you're coming

from kotlin or in swift you would say

like an optional invocation depending on

the language that you're coming from but

if you're not if you don't i have like a

software development background then you

may just call that a question mark

so user is optional and this function

returns a fusion voice so you can't just

call it you need to wait on it and

so now we're doing that so we're now

and also since now we've changed our

logic in that when you press the

register button upon successful

registration we're sending you an email

is not a good idea to end up on this

screen that just says please verify your

email address because let's let's just

face it we have already sent an email

verification so we don't want the user

to click this button actually we want

the user to click this button or tap

if they haven't received the email in a

while all right so we don't want like

double emails for users so it's just not

so uh sorry i'll just have a look at my

okay so what we need to do now is as the

caption now says here we need to go to

verify email view and add a text on top

to say we have already sent a

verification email okay and that's just

verify email route which is basically

and you can see that we have a column in

here and the first text at the moment

says please verify your email address so

let's create another text in here i'm

you see because i want to write the word

weave as in we have there is a single

code in here so i cannot have my own

string having single codes because then

dart doesn't understand where

this what this string is because it

thinks here's a string that starts here

and it ends here but what is this one

so in in order to have single quotes

inside your dark strings then you would

basically put your string inside double

quotes so you avoid that confusion

sent you an email verification

to verify your yeah so please open it to

and also this text then we need to

change that as well because you see we

don't want this text to be kind of like

a call to action saying that hello

like here we're saying we sent you an

email verification please open the

verifier again and then right after that

we're saying hey click this button so

that's not a good idea let's just change

and let's make this double quotes as

well just the same story as before

the button below something like this

okay so i'm just gonna press command s

and now you can see those texts being

displayed on the screen they're not very

pretty to be honest with you at the

um that's not a problem let it be like

all right so we're displaying that text

uh to the user and what we need to do

flow basically again just to make sure

that yeah it's working as expected so

in order to do that go to your firebase

and i'm gonna bring up the console in

here hopefully you can see it too and

i'm gonna go to that project then

authentication and this user i'm gonna

delete this user okay delete

all right that user is gone i'm gonna

and and what we're gonna do then is just

to hot restart the application in order

all right i'm gonna then uh verify email

i can see that there is no back button

uh we're ending up in in that screen

i believe that we're actually sending

the user to verify email view in this

case user firebase instance card okay

so this is a lot a little bit a bit of a

problem because now we're kind of like

view because firebase as a caption right

here says it says firebase doesn't

understand the remote changes

we removed that user completely but

firebase still believes that that user

exists and that is because you see

firebase can't like the client that is

inside the code that is inside the

client application which you are

developing can't constantly talk with

firebase and say give me the latest

state give me the latest state

this user that is right now on this on

is a local user that once had a

connection with the backend but it

doesn't anymore but firebase doesn't

like delete this user locally so

the best way to handle this case is to

have kind of like a restart uh

button in our verify email so if for

some reason the user like in this case

understands that hey um i'm stuck

i need to get out of here from verify

email i kind of want to go back to where

i was so what we need to do is to

upon the user pressing a restart button

sign that user out so firebase

understands well this user isn't signed

in anymore so that we don't end up in

this case that email is verified etc etc

and we also are going to send the user

to the register view okay and as you can

we can't send the user back to the

i mean that we can't expect the register

on the view stack in this case because

if a user has just freshly started the

application application so they will end

up in this future builder the future

builder would then check the user and

says oh you should go to the verify

email view and in this case there is no

um verify email view so in that case you

will see that we won't push but we will

actually do push name and remove until

but we will get there soon okay

first off let's go to your uh to your

verify email view and right after this

text button we're gonna add another text

up a little bit so you see it better

and let's just say a text button

unpressed is just going to be empty for

now and then for his child we're going

to add a const text that just says

so that's that and then here what we

then need to do is as i mentioned before

explains here we need to actually log

the user out so let's say firebase auth

and and then what we need to do is to

okay remember cyano i also believe is a

future of void so you need to await on

um see i just jumped screens without

actually really wanting to do that so

let's wait on it and it's going to give

you an error because now your unpressed

function is not async so make it async

after doing that using if i do command s

now we're gonna see the restart button

doing that just does a sign out it

doesn't actually send you to the

register view and we're gonna take care

of that soon so as a caption says

navigator of context i push named remove

until and in here we're going to send

the user to remember from our routes

view sorry a routes file there is a

register route okay so let's go there

out and in here we just leave the code

as it is and i come at the end to clean

and that should be good to go

okay now i'm gonna do a hot restart

you'll see now we end up in here

and because it's still the user is

logged in because we haven't executed

this code yet and i'm just gonna then

press the restart button and you'll see

we end up in the register view just to

make sure that we're not going to go

vicious cycle again that every time we

do a hot restart we're going to end up

and let's just do a hot restart now to

see what the state of the application is

going to be and as you can see upon hot

restart we end up in the login view

which means that the main dart file in

the future builder it went to this code

so the user is null at the moment and

that's exactly what we wanted because we

signed the current user out okay

all right so we are then going to use

as before to register let's just go to

the register view then and i'm going to

round.np np gmail.com and then fubarbas

and i'm going to then register this user

and you can see it says it sent you an

email verification please open it to

verify and i can see on my third screen

here that i actually got the email

as you can see in the caption it says

get the confirmation email but don't

confirm yet because we kind of need to

have a look at a problem that we have in

now let's see if we can log in so what

go back on the screen from the verify

email go back to the register view and

instead of doing a registration again go

to the login view now use your current

like the new user that you just created

but you haven't confirmed the email use

the credentials of that user and say

and then press the login button

you'll see now we've ended up in the

and that is problematic because

any user just like i did can go to the

register view then they will go to the

confirmation view automatically they say

okay i got a confirmation email and then

they don't confirm the email they press

the back button to go to the registry

view again and from registry google they

go to the login view and then they log

because you see in our login view

right after signing with email and

password we are not verifying that the

user has actually verified their email

address we're just saying sign in and

firebase says all right sign in great

the email and password match an entry in

the authentication database i'm good to

go and then we're just saying push to

that we have that we need to fix in the

but for now we've got a lot of code i

can see all the files are changed so

let's commit our code and tag it like

what we're doing in other chapters as

gonna go to the terminal i'm going to

change the screen layout a little bit so

views so you see it even better

and you can see the previous tag was

step 6. now let's have a look at the

status of our code and i can see there's

lots of changes modified you can always

which i call gopa and that will show you

all your changes but i'm just gonna say

i'm going to say git commit and we said

that we're going to commit this as step

and push those changes to github

and i'm going to also tag it as step 7

so like that step seven and then i'm

as the caption says here we need to get

ready for the next chapter and as you

can see it says user needs to verify

email before going to the main ui

because that is as i explained there is

a problem that we have which we haven't

addressed yet but it's quite easy to

address as you'll see in the next

hello everyone and welcome to chapter 23

of this vlog course as you saw in the

previous chapter we talked about

cleaning up our registration flow so

that when we tap on registration or the

register button we actually send an

email confirmation to the user and we

saw that we go to the email confirmation

view and before we even get there we

then receive our email confirmation in

our inbox so that all worked very well

except for the fact that now a user who

hasn't registered who hasn't verified

their email account can still end up in

the main ui of our application and

that's what we're going to fix in this

title shows here or as the caption shows

here what we need to do is to ensure

we first before we continue with the

chapter we need to make sure that we've

logged out of the application so um

now that you're in the main ui of the

application let's just go in here and

say log out and we're logging out to end

i'm gonna i'm also gonna bring up visual

studio code as we left it before

what we need to do now i'm going to

other tabs except for the login view

right after we're signing with email and

password right now we're sending the

user to the notes route and we need to

what we need to do is just to get the

the correct correct caption as well and

i'm gonna change the screen layouts a

so as you can see the caption says you

need to add an if statement before you

send the user to the main ui of the

and to make sure that the user is

in order to do that we also need to get

concurrent user so we can say final user

is equal to firebase off instance

and the current user okay so that's for

and we're going to say if the user

optional you see we need to optionally

access that email verified or false

when we get a boolean value here either

this returns a true or reuse false

so in here we say user's email is

if i can spell it is not verified okay

so now we have the two conditions in

so what we need to do now is to grab

this code that we had from before you

can see it sends the user to the main ui

of the application and of course that

needs to happen only if the user has

verified their email address so grab

that code and place it in user email is

and in the case that the user email is

not verified then we kind of need to do

but instead of going to the nodes route

which is the main ui of the application

we actually know we need to go to the

verify email route if you remember from

the previous chapters in a route start

we've already defined verify email route

let's go back in our login view and then

paste the same code except for going to

notes route we're gonna go to and verify

really all we have to do for this

chapter so it's just cleaning up the

logic one step at a time okay and that's

okay some chapters are going to be long

some chapters are going to be short it's

actually quite refreshing even for me to

have some shorter chapters so

um now what we need to do is let's put

and as you can see what we're going to

do is to remove that test user again

from firebase console and test the

entire flow again so i'm going to do a

and just to make sure that the state is

completely restarted i'm gonna bring up

a firebase console let's go to our

application which for me is called

i'm gonna go to authentication and

remove that test user that i created

and do another hot restart just to make

sure the cache is invalidated if there's

what we need to do now is to just oops

what we need to do now is to do kind of

like the same registration again so i'm

gonna go to the register page here and

then i'm gonna go to your enter your

write the same email address to register

the user again through bar bath

and we end up here then i'm going to do

the same hacked as we did before uh

press the back button and then go to the

login screen i'm going to type the same

credentials and say fubar baz if

everything is worked according to our

plan upon pressing the login button the

code is going to end up in here saying

that the user's email is not verified

and it's going to remove the login route

from the stack and push the verify email

route on the screen okay so both

and that is exactly what we're getting

here you can see we're going to the

verify email view as we planned

okay as i mentioned this chapter was a

short one and that's actually really

good so what we need to do now is to

focus on what we're gonna do in the next

chapter as you can see it says our

authentication logic is all over the ui

and we need to make a service for the

up until this point we've been working

with firebase directly in the source

code in that we've been like writing

firebase auth code pretty much in our ui

now you may think that well that's okay

if you're if you don't come from a

software development background you may

think that that is fine and it should as

the software development industry has

shown us over and over again that the

saying of oh if it if it's working if

it's not broken don't fix it that that

doesn't that doesn't really apply to all

cases as we've seen uh in the case of

for instance log 4j uh it was working

but then there was a security flying and

everybody had to go out to their code

base and fix everything so we're

entirely still of the weekends so the

but there's a problem with it in that

here you have your user interface so the

code is quite high level it's like

literally the user is here and then we

have our user interface here and then we

have like the code that we've written

and like a little bit more low level

like our if statements and then firebase

is sitting all the way down here and

we're like exposing this firebase layer

all the way to our ui layers the ui is

talking directly with a layer of the

code that is so level that they

shouldn't have direct connection with

if you're not from a software

development background this may be a

little bit alien to you but software

developers really like to make sure

what we need to do is in order to get

ready for the next chapter is just get a

good cup of coffee or tea because the

next chapter is actually going to be a

long one and it's going to be a

complicated one but i'm gonna do my best

to explain all the concepts as good as i

can but just know that the next chapter

so uh grab your refreshments juice tea

water coffee whatever you want and i'll

see you in the next chapter

hello and welcome to chapter 24 of this

flutter course in the previous chapter

we talked about ensuring that the user's

email is verified before he or she can

by before the user is able to go to the

um and what we are going to do now is

take a step back from developing our ui

and logic of the application by creating

i'm going to provide you with a caption

here and as you can see it says auth

provider auth service meaning an author

provide abstract class on an off service

if we have a look at the code that we've

created so far let me bring up visual

studio code so you can see it on the

screen like i do here um i'm going to

increase the size so you see better

and i'm going to bring up the

i have three screens here so it's a lot

it's a little bit difficult to juggle

so i'm going to change the screen layout

register and verify email view okay

or we actually have four views the other

one is the main ui of the application

um which we have right now created in

but if you have a look at the login view

you can see one of the things that we're

doing immediately as we go to the login

is not actually immediately by pressing

the login button we're talking with

firebase off signing in we are kind of

doing the same thing talking with

firebase by uh in the register view you

can see firebase auth instance create

and we also have firebase in our verify

so you can see here we are actually

importing firebase auth firebase so

if you're not uh like if you don't have

a software development background from

from before you may think well this is

this is fine very important firebase but

you also need to know that firebase is

kind of like a low-level abstraction

that is talking to the firebase backend

and providing you with a lot of

functionality but those high-level

functionalities at the firebase level

they're kind of high level but if you

a dependency that we're bringing into

our application that's talking with

firebase back-end in itself is

low-level compared with our ui so if you

the ui code is here then what we are

doing is that we're like saying here is

firebase and then the ui is talking

directly with the firebase libraries and

in the in the eyes of a like a software

developer has been doing this for a

while this is not a good idea simply

because we're missing a little bit of a

layer in between the ui and firebase

which abstracts away the firebase

functionality from the ui of the

and as we talked about it before um it

is possible that in the future you may

want to allow for instance apple login

or google login or sign in with facebook

etc various options for signing in and

if you look at um the console at

firebase you'll see immediately that

you have various ways of authenticating

a user at the moment we've enabled sign

in method for email and password but you

also have the ability to add a new

provider you can as you can see google

facebook and these as you can see

they're called providers a new provider

and that is what we're going to do in

this chapter of our flashlight course as

we're going to take firebase and

think of it as an authentication

provider okay so we're going to create a

which i believe we're calling at the

moment firebase auth provider

but we're gonna say that this firebase

auth provider comes from another class

which is called auth provider so what

we're gonna do then is gonna say okay

any auth provider that needs to that our

application can work with is expected to

have certain functionalities

and certain properties okay such as the

current auth provider should be able to

return the current user the author

provider should be able to log a user in

log user out register users send an

so that will be our abstract offs

provider class and then we will create

another class which is as we call it it

will be the concrete implementation of

that abstract class so think of the

abstract class as kind of like a

as it's it is our um contract

so we're saying any authentication

provider such as google facebook etc

functionality that we specified in this

then we will go and develop a concrete

implementation of that abstract class

and we will call it firebase auth

provider and we will actually place the

for firebase such as creating a user

logging user in etc etc in that concrete

and then what we will do also we will

create another class which we will call

it i believe we call it off service

and in this course it won't do so much

take a provider such as a firebase auth

provider a google auth provider and it

will just expose the functionalities of

that provider to the outside world and

and the goal of this is that so we will

with that service and that service will

talk to a provider which which is the

firebase auth provider and that firebase

auth provider will talk to firebase so

right now we have firebase ui

but after after the end of this chapter

auth service and then the ui so we will

have two layers sitting in in between

and you may actually correctly think

that well this is a lot of work why do

for me i if i wanted this course to be

just another course where i show you how

to include firebase then it wouldn't be

to be honest with you worth actually

doing yet another course about firebase

and flutter because there are lots of

courses available maybe not maybe not

courses that go through so much details

as i am going but i still believe that

my job here is not just to make you a

developer but also make you a good

developer where you take some extra

steps in order to make your code a

little bit better and this is why you

will actually notice as as you get more

into software development and working

with others in inside teams which you

may not be doing at the moment but when

you get your first job a software

developer you'll understand that other

software developers are actually taking

some extra steps in order to make their

code a little bit easier and better to

maintain so that's what we're gonna do

uh the intro for this chapter what we

um first think about how we're handling

if you look inside the i mean in the

verify view we're not taking care of

exceptions as such maybe that's

something we'll need to do as well

but if you look at the login screen for

instance we're having here a try block

and then when it gets to firebase off

exception we're handling user not found

wrong password and then if anything else

happens we just say show error

specific errors off errors that we're

handling wrong password and the user not

the register view you will also see we

have weak password email already used

so these are some of the exceptions that

we'll need to handle in our um in our

application but right now as you can see

our ui is going directly to firebase

auth exception and it's like importing

firebase auth exception which is

created inside let's have a look

firebase off accession src interface

it's in one of the files which i believe

is accessible through firebase auth so

that probably imports all the exceptions

as well there we go here it is

so our ui shouldn't really know anything

about firebase off by the end of this

chapter so let's take the first step

here then and let's go and create our

under folder called services auth and

exceptions.dart so i'm gonna do that

i'm going to collapse these and let's go

under lay down you can see that we don't

have con right now we have constants

utilities and views so we don't have

anything called services so let me right

click on lib and say new file and you

and in here just enter the entire path

oh that is our new file that we created

and what we need to do is to go and

define all those exceptions so let's

begin by saying that we need a new

exception called user not found off

exception and if you remember user not

found is something that we're handling

firebase off exception in the login view

and if we cannot find that user we're

just showing an error saying show error

dialog so let's define an exception for

that and i'm going to say class

and i'm going to say implements

exception so this is a typical way of

creating exception classes in your in

your application that you say

my own class that is that for instance

represents an exception and it's it's

good practice just to say that it

implements an existing exception

exception you can see here by command

pressing on it you can see it goes to

flutter bin cache core exception start

so it is already imported by default you

don't have to import any specific file

in order to get access to the exception

so it's it suffices that you just

so now let's go ahead and implement the

exception as the title as the caption

says here wrong password off exception

and that is also handled inside our

i'm just gonna go and kind of like copy

that code and in here i'm just gonna say

all right what else are we handling here

nothing else in the login view at least

so that's that's really good so

i'm just going to close the login view

so let's now start taking care of some

of the exceptions that we're handling in

our register view and let's go to

register view and you'll see here that

the first section exception that we're

handling is called weak password

i'm going to put a comment in here and

a comment in here i'm going to say login

so as the caption says let's create a

class called weak password auth

exception gonna copy this code from here

so that's for the register views weak

password the next one is email already

in use so that's what the caption says

here as well so let's go and copy this

and i'm gonna say email already in use

so now we have the password and email

and we also have the invalid email

which i don't think i had planned for

but let's go and implement that as well

now what we also need to do is to

other exceptions as you remember from

we also have the case of an else where

we basically say something else happened

here it's an off exception but something

else may have happened that we haven't

handled with this code or we may also

have another cat statement here that

catches like generic exceptions and

we're we're doing the same thing as you

can see the code here um and let me

change the screen layout so you see it

the login view as well because we're

doing the exact same thing in the login

upon getting a firebase auth exception

then we also have an else statement even

in there so we're saying if the code is

not like handled by us it may be another

code in that case also show the show

error dialog or in that case show error

and we're also doing a catch like a

generic catch as well so we need kind of

exception that handles all those cases

an unknown code during the firebase off

exception and an unknown exception so

we're gonna create a generic exception

i'm gonna change the screen layout a

um like that i'm gonna go to my notes

so let's just in here say generic

today i'm gonna bring this one first so

let's go ahead and create a generic auth

exception i'm gonna copy this code from

here i'm going to say generic auth

and what we also need to do is to

this thing user not logged in

and you will you will know now that

i mean you will need to know why we're

actually having a use or not logged in

this will be an exception that our um

that our firebase provider will be able

after registering that user for instance

so let's say that we tell our auth

provider we say register a user with

this email and password and no exception

so we the application thinks that all

right everything went as expected but

is null in that case our auth provider

should be able to handle that and send

an exception saying that oh i couldn't

find this user or this user isn't logged

in so let's create that exception as

well so i'm just going to say

user not logged in exception so let's

okay so user not logged in off exception

and i'm gonna save that as well

all right that was a lot of work now we

have created all those files oh sorry

maybe you didn't actually see the code

that i wrote i don't like having

captions up all the time but i also

think captions are so important so that

you always know what we're working with

but the downside of having these

captions at the bottom left of the

screen is that sometimes they hide what

i'm typing so i'm doing my best really

catch that issue and if i see that

happening i'll i'm gonna bring the

screen up like this so you see it but

sometimes i may be missing that i

apologize for that so let's let's say

that and now we've implemented all our

and as you can see in the captions it

says we need an auth user we shouldn't

expose firebase's user to the ui

and this to be honest with you is the

same story as we had for our exceptions

the ui code should not at all be working

with firebase the ui code should be so

high level and so abstracted from the

rest of your application that it

shouldn't even at all know how it is

functioning you're just giving it

providers and services and it should be

calling those services and providers not

really knowing how they're tied together

and at the moment you can see our login

you can see here in login view and for

me it's on line 67 for you maybe in a

different line but we're after calling

the sign in with email and password

function which we also shouldn't be

what we're doing after that is we're

getting the current user from firebase

and this user is of type you can see

let's go in here and see it's of type

user so if i go put the type in here and

command click on it you'll see this user

is part of firebase auth you see there's

a fun there's a class called user so

we are all we were also like exposing a

firebase user to our ui and that is not

so as a caption says here we shouldn't

expose firebase's user to the ui so we

need to have our own user that abstracts

or that that the current user at

let's go ahead and do that so

we're going to create an off user dart

file in lib services auth a file called

user so i'm going to remove or sorry i'm

going to close all the files that i've

services auth i'm going to then create

so i'm going to say off user.dark

and in this off user then we need to

basically start working with firebase in

this case so i'm going to go to my notes

just to ensure i'm telling you

everything that i'm um that i plan to

all right so let's go in here and import

firebase auth i believe and then we're

gonna say show user okay and as i've

mentioned before this is a great way of

just ensuring that you're not exposing

too much of a packages classes to your

current workspace except what you're

saying is that firebase auth is isn't it

maybe an entire dart file with its

structures maybe thousands of classes

now i'm exaggerating but a lot of

classes but you are only interested in

off like that and then you would say

show user and that will allow you so if

then you will be able to say

you can also do that if you if you

prefer to for instance ha prefix the

user in this case that comes from

firebase with the actual place that it

comes from you could also use as

some people may like it and i also do

but i haven't planned to do that in in

file so do it if you want to the way

that i'm doing it here so you can follow

along with the steps that i'm providing

for you in this course without diverging

okay now that we've done the um

what we need to do as a caption in the

case we need to create the actual class

and in here what we need is a field

called is email verified now remember

right now all we need from our off user

is to know whether that email is

verified or not so if you go for

you can see that we have this code here

that signs a user in with email and

password and right after that gets the

user and all it does with that user says

and we're doing the same thing in

register view i believe so let's go to

register view and you can see in here

actually there we're not doing anything

with the email verified all we're doing

is just saying a send email verification

so sorry about that so it's in login

screen okay so let's go in our off user

in here and say it has a property called

i'm gonna say final and bull is email

and you saw that firebase has

implemented this function this uh

property as email verified i personally

prefer to call boolean functions boolean

getters in this case like a property of

a class with is wherever i see that fit

it's just because it makes a lot more

sense for me at least to say user dot is

email verified rather than saying

it just makes it more like complete

grammatically is blah blah verified or

so that's the reason that we're

now you see this in here and we're

saying it's email verified you can get

help from visual studio code to

create a constructor for final fields

and even if you don't want to do that

you could always just type it by hand

you can say off user self is email

verified sorry this is email verified

and since this class it only has a

property that you can set upon

initialization and you're not changing

it because it's a final field

you can make your constructor a const

excuse me again and it would also be

immutable as another try defining

undefined i believe you actually have to

but immutable here i don't think we've

talked about that before but it's just

like an annotation telling that this

class and any subclasses of this class

are going to be immutable meaning that

their internals are never going to be

changed upon initialization so if you

then go and create for instance class my

off user and say extends the auth user

um let's say in here and you create a

constructor for it so let's create a

constructor for it so boom okay

prefer declaring what is a const okay

then we say const then you say okay well

i want a boolean flag in here bull is

now you see it says null not

non-nullable instance flab but it must

be initialized let's just initialize it

to false and and it says can't define a

cons constructor okay then we're not

going to make it a cons constructor and

now you see that little warning here it

says this class or a class that this

class inherits from is marked as

immutable but one or more of its

instance feels aren't final so

now you see what immutable means it

tells dart that this class and all its

subclasses need to be immune immutable

they cannot have any fields that change

so by removing this field then you get

little warning and you can make this

cons and the error completely goes away

so now you know what immutable means

all right great now we created that is

email verified at a cons constructor for

the next point as you can see here it

says we need a factory constructor

auth user from a firebase user and

factory constructors are really useful

for this purpose in that you have

let's say object x and you want to

create an object y from that instead of

you manually gluing things in some sort

of a middle layer saying now i take the

object x and add some blah blah and fuse

it together and then put object y you

can put that responsibility on object y

and saying that you need to be able to

initialize yourself or construct an

instance of yourself from this object

and this is like a typical pattern that

um well everywhere everywhere but where

you have the ability to do that so

that's what we're gonna do now with a

factory constructor so let's say we have

we'll say off user and we say from

firebase okay as the caption says then

we take a firebase user in here

like that and then we say what we will

do in here we will actually create an

instance of our own class an off user

given that user okay so let's say that

and a lot of user and it's email

verified comes from user email verified

all right so this shouldn't be they

shouldn't be that difficult to

and it takes the email verified value of

the firebase user and places it in this

class so all we did is just we kind of

made a copy of it into our own off user

exposing firebase's user and all of its

properties to our user interface

all right that was a lot of information

now let's talk about an auth provider as

i mentioned in the beginning of this

and as you saw in the firebase console

you will have the possibility to add

various auth providers to your

application when you're working with

and many many more okay an email and

password combination like we're doing so

what we need to do now is to create an

alt provider class that encapsulates

every provider that we may add in the

future and creates a nice interface for

them says every provider that our

application can work with should conform

to this particular interface okay

so let's go ahead and take care of that

now and i can see here we're going to

create that file on the lib services

off provider so we have lib services off

but we don't have auth provider files so

let's let's right click on auth and say

what we're going to do in here then is

the the functions that we're going to

provide for our auth provider are for

instance a getter that gets the current

user so that's not a function it's just

a getter the way we're actually doing it

in here if you see let me go to login

and you'll see in login view here this

thing at the moment say firebase auth

instance current user this is a getter

so this is a property and returns the

firebase user what we want is for our

auth provider to also be able to provide

us with the current user now remember

we've abstracted away the firebase user

with our own auth user which we just

created okay so what we need is this

abstract class that can return an

so for that we need to import this off

user into this dart file so let's just

this application that i've created as

you can see in the title it's called my

so let's go to my notes services

auth and then auth user so that's the

import statement as you can see in the

caption i've written package xxx and

that's where you need to put the name of

your package in this case for me is my

all right that's great now let's go and

create an abstract class so i've

mentioned this twice before but our auth

provider dart file is not gonna have

is not gonna have any logic it's an

abstract class though abstract classes

in dart can contain logic but in this

case our abstract class is just going to

be a protocol or you may know it as

interface or you may also know it as

well an abstract class so let's go ahead

and create that let's say abstract class

and so the abstract class creation is

done what we need to do is now give it

like the ability to return the current

off user okay so as the caption says

we're going to say off user and get

so we're saying any author provider

whether it works with email password

whether it's a google auth provider

whether it's an apple facebook twitter

whatever it needs to be able to

optionally return the current currently

authenticated user and that's what this

and then what we will also need to do is

be able to log a user in okay so we're

going to say we will have a function

and now we have to think what does this

login actually require well in our case

it requires email and password so let's

just put email and password we're

thinking that every author provider that

we're writing is going to have an email

and password combination of some sort

you could say id and password but i'm

just going to go with email and password

for now okay so let's make these

required parameters as well so i'm going

to put curly brackets here and curly

bracket here i'm going to say required

and then a required stream password like

and a semicolon at the end of that

command s to save the file so dark

and the reason where you see if we go to

author sorry if you go to our login

and in here we say sign in with user and

password you can see that it always

returns a user credential now you may

you may think how can i always return a

user credential if the current email and

password are actually incorrect and they

don't belong to a valid user well the

way that firebase is handling is that if

you say sign in with email and password

if you can grab the current user if he

can't sign in that user with the

information that you provide it returns

it otherwise it fails with an exception

meaning that it's saying that as long as

you call me and there's no exception i

will give you user credential if there

is an exception well you need to handle

that so that is a great way to avoid

having functions let me close the off

user as well avoid having functions that

do like this that option on your return

do your work in your functions

return the user and return the object

that you promised if you can't do that

throw an error so you don't have to do

this do this kind of a optional return

for a the login function now we need to

also have a function that can create a

user so that imagine that it's for the

yeah what else do we call it uh register

let's call it a create user so we say

this also returns a auth user

and we call it creates user like this

and this also has all these parameters

so i'm just going to copy and paste this

you don't have to do that twice and a

all right guard formatter do its thing

and create a function that allows us

then to log a user out because that's

what we're doing in the main ui of the

the log out it's not going to return any

value as you can see in the caption here

just a future void so we say future void

and also we will need a function that

can send an email verification okay so

this one's also very easy it's just a

future void and as you can see in

captions we're calling it send email

our office provider at the moment is

dictating an interface for any

authentication provider that we're gonna

we but just so you know we are only

going to add an email author provider

sorry a firebase author provider

but this way by creating an abstract

class with an author provider as a name

and then you create a concrete class

called firebase auth provider you're

able to in the future to extend this and

add more and more auth providers all of

which will follow the same interface

but we're only in this in this course

are gonna use firebase auth provider

as the caption says go ahead and create

a a file called firebase auth provider

in your services auth folder i'm gonna

right click here and i'm gonna say oops

uh and say new file i'm gonna call it

um i'm gonna go to my notes a little bit

like that okay so this is gonna be like

of this chapter we are actually going to

abstract the way firebase authentication

into our own provider so expect this

file to grow a little bit in size i can

see my notes it's going to go to about

100 lines of code but that's okay too so

and um we can just get started with it

as you can see in the caption we need to

import a few of files auth user

auth provider and off exceptions we need

auth user because this sorry actually

explain why we need to import auth

provider because our firebase auth

provider is going to be a concrete

implementation of the file auth provider

or the class auth provider that we just

created so that's the reason for that

the os user import is going to be

because as you can see in the auth

the login and create user functions they

need to return an off user so that's why

we need to import off users so that our

provider can return instances of that

and last but not least we also need to

import auth exceptions because remember

our firebase auth provider is also going

abstract away all the authentication

errors and exceptions that otherwise

happen at the firebase level into our

own exceptions that we've created

here off exceptions okay so let me go

ahead and first import off user so

and this application called my notes

off user okay so i'm gonna import that

and i'm gonna copy this file then and

this line and the next one is gonna be

and as you can see in the captures we

also have to import auth exceptions

so those are the three imports

since we have our own imports

and this file is going to talk directly

with firebase we also need to import

firebase of course so and let's go ahead

and i'm going to actually copy that code

so i don't have to type all of it

because it's a little bit boring but you

in the captions at least what you need

to import the firebase off and you need

to also import firebase off exception

um now what we need to do is to create

um as you can see it's going to be

called firebase all provider and

implements auth provider which is our

own class so let's say firebase

a provider just like that okay and now

you can see you get an error same

missing concrete implementation i'm

going to change the layout of the screen

so you see the code in its entirety

and then what we need to do is to

implement you see those function

functions and getters that auth provider

says that every class that implements it

needs to implement those things as well

so you may try to do those things by

i i i'm not at all a fan of doing things

by hand sorry about that so i prefer to

get help from the editor to complete

these things so i'm just going to say

and make class firebase off abstract

create five missing overrides okay so

there we go so visual studio code

created all those functions in here and

you can see in all of them it just says

i'm gonna decrease the size of the font

same layout that we had before

so the first thing that we need to do in

here let's go ahead and implement this

so this is going to have a lot of

not a lot but it's going to have a bit

of logic so i'm going to do this instead

and let's go ahead in here and try to

you see our job is now to get the

firebase user and turn it into an off

user remember our off user had a factory

constructor so we need to call that

factory constructor okay so let's just

say final user is equal to firebase off

and then we say if user is not null

and we need to create an instance of it

as off users so we just say return

off user from firebase user okay

otherwise we return null like this so

if firebase says there's a user then we

create an off user out of that and we

okay that was for a current user it

wasn't so much of code to be honest with

now what we need to do is to take care

of create user which is this function

so create user is going to be a little

first do a little bit of formatting in

append a comma at the end of the last

parameter of my function so that when i

or dart format it's going to break all

these parameters into their own

lines okay because before it looked like

this and it's not so clean in my eyes at

in here what we need to do is to

so i'm going to put this entire thing in

in a try block and then we're going to

catch firebase off exception

on firebase off exception catch e okay

and then we're going to have a generic

all right uh now what we need to do in

create user in the tri-state main

statement we need to actually tell

firebase that we want to create a new

instant and then we say create user with

email and password okay so we have the

email here and the password and we can

see those parameters already there so we

um but what we need to do here is you

can first actually see yeah this

function needs to return a value we're

gonna fix this so don't worry about that

but we also need to await on this

because remember creating a user or

email password is not a function that

just returns immediately and this is one

of the things that is absolutely

beautiful about dart in that in the

interface we didn't actually say that

this function has to be async but you

can in this concrete implementation make

this function async so it's absolutely

beautiful so async is not the part of

the signature of the function but it has

more to do with the internals of that

function so in order to call this

function with an await you see if we put

a weight here we get an error we need to

make this function async all right so

all right so after doing that what we're

going to do is to get the current user

if the current user is there then we're

just gonna return the current user if

the current user after creating a user

or email and password and no exceptions

is not there then that is a bad sign and

we need to return then one of our auth

exceptions called user not logged in off

so i'm going to close this so let's go

get or just user is the current user

remember we already have a getter for a

and it just gets the current user from

firebase so we say here's the user

if the user is available there

otherwise you should throw a user not

found or i think that's what we call the

that's for the creation of the user if

everything goes fine except for this

now we need to go to our firebase auth

exception and we need to handle a few

so if you look at where in our register

in here we are handling weak password

email already in use and invalid email

so let's just copy these three things

okay actually these four things because

we have an else block in there as well

so i'm gonna copy that code just do the

same thing please so go to your registry

and copy that code go back to your

firebase auth provider inside the

firebase off exception where you're

paste that code but remove everything

that has anything to do with the show

error dialog okay so at least we have

like this so you should end up with a

where there is a weak password we are

actually going to throw our own error so

weak password off exception

it is an email already in use we're

going to throw email already and use

in case on invalid email throw invalid

email off exception and if there is any

other code that we don't know about

we're just going to throw a generic auth

and also if there is a final catch

basically meaning that by calling the

create user an email with email and

password if there is any other exception

other than firebase auth exception we

also need to handle that and throw

a generic auth exception there as well

hopefully this makes our ui code

easier to read okay so we're doing this

create user i'm gonna fall create user

uh if it allows me to fold the entire

create user poof and i'm gonna fold

current user as well so this is a

technique that you can or not a

technique that's just a trick you can do

in your editor if it supports folding

and unfolding just to make sure that it

looks a little bit cleaner okay because

now that you've written create user you

may not be directly interested in all

its details you may just want to know

all right the next thing we need to do

is to implement send email verification

so let's find that function and i can

see it's right here send email

verification i'm gonna scroll a little

i'm gonna go to my notes as well okay

so what we need to do then is to

incent email verification what we need

is to also mark this as async because

it's going to call an asynchronous

function on firebase as well okay

call the send email verification

function on the firebase user remember

our user doesn't have that functionality

our user only has is email verified

property so in here let's get the

firebase user so i'm going to say user

if user is not null then we call that

function so we say await user send email

verification i remember i think this was

the future of void so that's why we're

doing a weight on it and that is why we

have the async tag in here okay now

if the user is nil then we're gonna just

say user is not logged in you cannot

send an email verification from user

who's not logged in okay so then you

so that's our send email verification

let's then fold this function as well so

as the caption says now we need to go

and implement a login login is just as

important as creating a user i'm going

to start by putting a comma at the end

of password parameter here and command s

and in here in the login function we're

going to do something very similar to

what we're doing in the register

function i can see in my notes

and then we say on firebase off

let's in in here then start by um

telling firebase that we want to log in

with those credentials so let's say

firebase auth instance and then we say

sign in with email and password so

there's a function in there okay

semicolon at the end so you can see the

all right so that's what we're doing but

remember again these functions are

asynchronous so you can't just call that

function and expect it to work it's a

future of user credential okay so make

your function asynchronous and then

function so we're going to do something

very similar similar to what we're doing

in register sorry in the create user in

in that we're saying final user is

i hope you can see that code yes i can

see that you can see so in this in this

uh code we're gonna take the exact same

create user so i'm gonna expand that you

i'm gonna copy that code and you could

do the same what we're doing is just

making sure after signing in then there

is a current user okay copy that code

gonna fold this then i'm gonna bring it

to the login and right after sign in

with email and password i'm gonna paste

that code okay so that's that part

authexception again to handle just like

we did with create so let's go to your

and which exceptions we were handling so

i can see here we're handling these

i'm actually going to copy that entire

code from login view you see a firebase

off exception username wrong password

etc and including the catch any other

exception block right here copy that

replace let me actually see how it looks

yeah replace all of this with that okay

and then remove your weights as we did

before to be honest with you this this

is just a lot of big talk for saying

need some code from another place to

bring here so your code now should look

like this so it says on firebase off

exception and we're handling user not

found wrong password off exceptions from

firebase and a generic catch block okay

so in the case of a user not found a

firebase office session we're going to

say throw user not found alt exception

in the case of a wrong password we're

going to say throw on password boss

and any other case that might occur here

we're just going to throw generic off

and in here as well we're going to say

throw generic with exception

thing i really like to do is you see in

dart it's not yet possible to say that i

want to ignore a variable in this case

you can see that in this like where we

we actually have to pattern match

against an exception and then we have to

assign a name to it and that name is

called e inside this function so if i

type e you can see it's an object

however as you can see in the body of

this function we're not actually

interested in e at all we're not using

it so in in other languages it is

possible to ignore like in javascript

python swift rust it is possible to

ignore a variable and saying that hey

i'm not interested in this value by

putting something called like an

underscore or something you can do the

same thing in art the difference is that

in dart if you say underscore you're not

actually ignoring it that variable is

also there but it's just called

underscore in this case so you can see

you can still call to string on it so

you may want to do it or you may just

want to leave it alone because you can

see guard an analyzer it doesn't give

of any kind saying that yeah your

pattern matching but you're not using it

so it's up to you how you want to do it

wow that was a lot of code um or maybe

more like a lot of explanations so let's

go to login and fold that and as you can

see in the caption now we have to take

care of the logout function and

the caption also says that this function

and you know why because we're going to

call a function on firebase in order to

so in order for a user to be logged out

the user should actually exist so let's

and then we're going to say current user

and we say if user is not null

and it's a user sign uh logout what's it

oh we have to tell a firebase off so we

otherwise we say throw user not

so we're basically saying here that you

cannot log out a user if that user

doesn't exist okay or that user isn't

lots of code lots of description but

that's okay we've now implemented an

auth provider firebase auth provider

which is a concrete implementation of

now as the caption indicates here we

um now what is an auth service i

mentioned this a little bit before but

an auth service is also going to

in itself is going to take an instance

but as you'll see in this chapter and in

our auth service is really just the

exposing all the functionalities of the

and it's not and it has absolutely no

other logic at the moment okay but the

reason we're doing that is for me to

just to show you that you need to have

providers and then you need to have

services that they talk to each other

and then this service can then expose

more value to your user interface to

your ui code than the provider does

that's usually the case that the service

a few other providers talk to few

providers and at the end it grabs the

data fuses together and provides that

information to the ui now in our case

that's not gonna be the case okay our

firebit our auth service is only going

to talk with our the given auth provider

and expose all its functionalities to

the ui but we're doing this exercise so

that you see how you can abstract away

various bits and pieces of functionality

from the ui code so remember that that's

the reason we have our auth service

which we're gonna soon create okay

so as a caption in the case here let's

go ahead and create our odd service

inside the auth folder here so auth and

i'm going to create a new file here i'm

just going to call it all service

in this dart file then we need to create

sorry gonna go to my notes in here as

import a few things we need to import

our auth provider and an off user so i'm

not to explain this again so um package

and we have and we need to import auth

and copy this kind of code and then i'm

going to say off news user i believe

so let's have a look in here in the

okay so we need to create now as you can

see we need to create an auth service

that also implements auth provider okay

if i look at the captions here why is

auth service an author provider i've

already explained this to you but you

can see it says but can have more logic

so that's the reason okay so don't

forget that so let's go and create a

and it implements an off of the auth

now what you'll need to do what you need

to know is that the auth service in

itself isn't going to be hard coded to

use the firebase auth provider

what it's going to do is that it's going

to actually take an audit provider from

and saying that okay i will then expose

the functionalities from that auth

provider to the outside world with the

ability to maybe even change that data

before it returns it to you but in our

chapter and then the rest of this course

it's not going to do that it's just

going to expose the same auth providers

functionality to the outside world so

let's go ahead and as the caption says

say we take an auth provider and we just

we need to do then is to create a

for your auth servicing here so command

dot on mac or control dot windows and

linux and say create constructor for

final fields and make it constant as

okay so now we have this beautiful

little off service that takes the

provider but as you can see it says

missing concrete implementations and

that's because we said our auth service

is also an auth provider so we have to

implement those auth provider classes

overrides as well so let's add them in

here as well but this time it's gonna be

a lot easier uh to implement these

functions because our because our auth

service internally has a provider and

expose the functionalities of the

as the caption also says we need to

before we do that i'm going to do a

little bit of a clean up here and i

suggest that you do too and in places

that we have more than one parameter

let's go and put a comma at the end of

the last parameter right here and there

that was it i'm going to do command s so

that dart formatter formats the code a

and let's just go and go ahead and

expose the functionalities of our

concrete implementations of the auth

provider so in here we say provider dot

creates user email and password perfect

for the current user we return the

provider's current user we say provider

for the login we then expose the

providers login function we say provider

and for our logout we do the same thing

so i'm going to say provider logout okay

and notification great stuff that was uh

that went really fast as you can see

you see we've done a lot of code now if

we go to our if if i change the screen

layout a little bit better a little bit

so you see the code better and let's go

to our terminal the built-in terminal i

absolutely love it in visual studio code

that there is an integrated terminal

and let's have a look at our git status

you'll see that we have changed login

view but also there is an entirely new

folder here called lib services so if

and to get status you'll see that we

actually have done a lot of work so

if i increase the size you see we've

added all exceptions auth provider all

service auth user and firebase auth

plus the changes in the login view

um actually i don't know what did we

that's interesting to know if you go to

did we change anything in login view

because at the moment i can't really

remember if we change anything special

so it would be interesting to actually

see what we've done so if i go to my

if i issue this command as you can see

here i'm going to remove that

login view from the staging environment

and i'm gonna say git status and then

i'm gonna say bit diff i can say okay

have added firebase core in here

has this navigator been removed

there's a lot of code in here that may

have not been committed from the

previous chapter that may be it so that

may be the reason okay but that's all

right as well so now let's get at all

and let's then go to the next stage as

you can see we've done a lot of work

let's just make sure everything is

committed this time okay so get status

everything is added to the staging

environment then i'm just gonna say git

message and step eight this time

and i'm going to push all those changes

and get status i can see everything's

also let's tag our code because i

chapter we didn't tag anything but the

one before that we tagged that step

seven and that was chapter number 22

where we talked about error handling in

the registry and going to the next

screen after registration so we didn't

tag anything in the previous chapter so

now we're going to tag things as step 8

so let's just say git tag step 8

if you can say git log you will see get

step 8 is there step 7 every step is

there an initial commit is there as well

which is step one and if you say git tag

you'll see all your tags available as

we've committed and tagged we've done a

lot of work in this chapter and i don't

think we need to actually drag it on for

longer because yeah it will be

unbearable maybe if it's too long

as we usually do which is the tradition

here before going to the next chapter we

prepare ourselves for what is coming as

you can see in the caches that we need

to migrate our existing code to using

our own auth service we have an auth

which abstracts away the provider and we

have a firebase auth provider but we

still are not using that code so that's

exactly what we're going to do in the

next chapter and if i look a little bit

in my in my notes i can actually see the

next chapter will also be quite a long

one maybe not as long as this chapter so

maybe you'll need a cup of coffee or tea

let's do that and without further ado

i'll see you in the next chapter

hello everyone and welcome to chapter 25

in the previous chapter we talked about

earth service and that was quite a big

chapter we talked about cleaning up

making sure that our authentication

one central place we created the auth

provider the firebase auth provider then

both the service and the provider are

conforming to the interface provided by

our abstract class for authentication

so um we call those the off service and

the firebase auth provider and then our

abstract class was called auth provider

now we've done all that work but we

haven't really even started using that

auth service and that's what we're going

the first thing that we have to do is

making sure that we have easy access to

um you see the way we created the auth

bring the code here so we can all see

change visual studio codes um

let's then have a look at our um let me

see if i can resize this a little bit as

well okay let's have a look here at our

auth service you see that with the way

that we created our off service is that

it in its initializer or constructor

however you want to call it um it is

taking a provider so for us to be able

to use our auth service every time you

want to use our auth service we actually

have to provide it with an auth provider

which in our case is going to be the

firebase auth provider which it resides

so this could be cumbersome especially

if you're working with firebase quite a

lot in your user interface every time

you want to use it then you need to say

auth service initialize the auth service

and then initialize your firebase auth

provider and give that to your

we don't want to do that every time

and that is exactly why we need to

initializer as you can see here in the

the captions so uh it says add firebase

factory to officers and that's exactly

so let's go to our auth service and as

the code is provided for you just write

factory and i'm going to say auth

in firebase so the responsibility of

this off service firebase factory here

or sorry the the responsibility of the

on our off service is to return an

instance of our auth service that is

already configured with a firebase auth

then we're going to say it returns an

change the layout of the code here the

screen as well so you can see it better

and we're going to say firebase

so that's that um now you see i have a

column here in visual studio code that

tells me where the code is going to

break some people even for one parameter

in their uh dart code or flutter code

they prefer to have a comma at the end

of it so that it is ready to take new

parameters in the future so if you do

dart format is going to break that code

for you into multiple lines ready for

you to enter the next parameter if

that's your preference go for it but i

have no preference here i just leave it

like that when i have one parameter i

just leave it in one line okay

before we actually go about uh starting

to use our auth service we need to take

a little trip back to the main dart file

as the caption indicates here so you

either go to the explorer but the way i

usually like to do it is with command p

and i say main dart and then i go there

remember if you are linux or windows

then you have to do control p okay so

let's have a look at our main dar file

and let's see if i can close these

places firebase off firebase provider

what did we change there save that as

well let's go back to the main now so

basically i just closed all the files

uh because i just want to have them in

our files so as the caption is

is telling you here um our menu action

and the notes view are right now spread

just around in the main dart file and

this is usually not a good idea because

you need to as part of your journey into

becoming a software developer you need

to make sure that your code is clean and

it's easy for other people to read now

i'm not saying i mean i'm not a true

true believer that the code has to be so

easy to understand that even if you grab

a random person from the street they

have to understand the code because

sometimes you need to make sure that

the person looking at your code has a

certain level of knowledge from before

but with all that said you need to make

sure that your code is easy to

let's make sure that the menu action and

notes view are refactored and that

they're in the right place and not just

spread around in main dart file

so as a caption indicates we're going to

a new new folder called enums inside lib

and the file name is going to be menu

the caption was a little bit wrong it

shouldn't be dark 10 it should be dart

so i'm going to save the caption and

bring it back up so it's with the right

so let's go and create that file i'm

gonna go here into lib i'm gonna right

click on lib and i'm gonna say new file

and in the new file i'm just going to

bring it up as well so you see it better

or you see it at all enums and then menu

let's just go and grab that menu action

from there and paste it inside this menu

action and save that file okay don't

worry main.dart at the moment has a

problem because menu action doesn't

exist here anymore so we're getting some

errors and that's okay we're gonna fix

to the main dark file again and we have

to clean up this notes view and as the

caption in the case we're going to move

lib views notes view okay we already

have the views folder remember from

before all we're going to do is just to

move this notes view into its own file

so i'm going to right right click on

okay let's go to main guard grab the

notes view and it's state so from there

notes view stateful widget and i'm gonna

take the show log out dialog with it

to note2 and paste that there okay so

now we have a lot of problems because uh

in an empty dart file as i've mentioned

before there's no material import so i'm

going to do the material import now so

command dot and say import library

package flower material and that is

now this file doesn't have it hasn't

uh menu action so let's fix that as well

with visual studio command dot and get

help from visual studio code to

automatically import our menu action

so that is also fixed and also remember

now in notes view also right now is

using firebase off and we're going to

fix somebody into this chapter so that

note2 isn't or any of our views none of

them are going to talk directly with

firebase so that's going to be fixed by

but for now let's go ahead and clean

this up and make sure that firebase auth

is imported and also remember login

route was used here when we log out of

the main interface of the application so

when we log out then it sends us back to

the login route and that is defined in

dart file here so let's import that too

all right so that was a lot of work

we've we've done that now so we're done

so i'm going to save this notes view dot

now as the the case we need to go back

to the main dart and remedy this issue

which we have and we need to import

notes view uh get help from visual

studio code or your favorite editor or

if you don't have this functionality in

your editor if you're using vim or

something you may just need to import

that by hand and the import is just the

package name of your application views

notes view okay so i'm gonna

get help from visual studio code to do

now let's have a look at something that

we actually forgot in the previous

um you see we've done everything in our

off service if you have a look at our

auth service it has almost all the

functionalities that we need it has

create view sorry create user it has

current user it has login log out and

send email verification but there's one

detail that we forgot about let's go to

main dart and have a look at it

you can see in here our entire main dart

like the home page build function is

built around a future builder that i i

know i'm saying build quite a lot maybe

i should say it's revol it's revolving

around a future builder which in turn

initializes firebase you see it calls

firebase initialize app and now that we

want to move away from our user

interacting directly with firebase we

this user interface it shouldn't go to

firebase directly it should ideally go

and that's what the caption says

auth provider abstract class so let's

close all these files make sure

and make sure that we have a function

and let me actually bring up my notes

we're going to say future void

remember now that we've added this

function to our auth provider we're

going to have problems because both the

firebase auth provider and auth service

they're they're conforming currently to

the author provider abstract class and

adding a new function to this abstract

class means that we're gonna get two

errors indicating that this function

isn't implemented in firebase auth

provider and in our auth service so we

need to fix those problems you can see

they're actually highlighted as red here

let's go then to the next caption

and i'm gonna get rid of that bottom

view so it doesn't bother us so let's go

now as you can see in the firebase auth

provider and overwrite initialize and

make it async and call initialize app on

so to in order to do the firebase

initialize code we need to have a look

at our main dart and see how that is

done at the moment you can see it is

called firebase initialize app so i'm

gonna grab that code and i suggest that

you do the same thing i'm just gonna

copy that code for initialize app

and let's then go to our firebase auth

and get help from visual studio code or

android studio in order to complete that

one missing override for initialize

and i believe it gets added here

we should have an initialize a missing

create one missing override initialize i

i'm gonna do that here myself future

void initialize like this okay

and uh what we're gonna do as the name

indicates it's gonna be an async

function here and what we need to do is

just to save firebase initialize app so

and we're gonna await on this so like

and remember we have we need to have two

imports here and one is for the firebase

and the other one is default firebase

options so let's get help from visual

studio code to import those firebase

firebase options dark file which if you

remember when we set up firebase

application from the firebase cli so

is is not a file that we've created

ourselves except it's the firebase cli

that created this for us okay

here now it says annotate over members

and that's exactly what we need to do so

right like this and now we have

initialize uh over member of our author

provider inside firebase author provider

basically all we're saying is firebase

auth provider implements initialize

all right we have one error left and

that is inside auth service so let's go

and we'll have the exact same problem

here and says missing concrete

implementation so i'm gonna see if i can

get visual studio code to add that

implementation and it added it here

so in here what we have to do is just to

delegate this function to the actual

provider so we're going to say provider

and we're going to say initialize just

like that all right so this was the easy

and if you don't remember from the

previous chapter or maybe you jumped

over the previous chapter i don't know

how you ended up in this chapter if you

haven't watched the previous chapter i

strongly suggest that you do that there

is a reason we have our off service that

and the reason behind that is that

usually services have more logic in them

bring into themselves so if a service

has two other services connected to

itself then it may actually take bits

and pieces from the service and other

bits and pieces from another service and

fuse them together with some extra logic

and that is exactly why the author

services as an odd provider so the goal

for us is to allow the officers to do

more work than an author provider even

though right now only thing it does is

just delegates all its functionality to

the auth provider and remember you could

also see make sure that i mean if you

don't like this implementation you can

for instance remove this and then

basically remove all these functions and

by doing that you're just saying that an

auth service includes an off provider

and that's all you're doing or you could

completely kill you your off service so

it's up to you but if you're following

along with this uh with this course i

suggest that you keep it the way it is

because there's a there's a point to it

now that we've done that uh it's time to

do some cleanup and this is this is a

very exciting part of this uh

chapter because we now have our auth

service and our firebase auth provider

and in and additionally we have an off

service firebase factory which allows us

to anywhere inside our code we could

and in that way we get access to

our um firebase auth provider inside the

auth services so it's it's really

magical you're gonna see it soon

so i'm going to close all files here

ensure everything is saved then as the

caption indicates i'm going to go into

and as you can see it says remove

everything related to firebase and

replace with auth service by importing

auth service okay so one way of doing

that is just to ensure that you go and

kill it from the source so you can see

here we have two firebase imports and if

you remove these two firebase imports

my preferred way of usually working with

software is that i try to like remove

something from its source so now that

i've removed those then visual studio is

telling me that hey you're using

firebase in two places you need to fix

this because you don't have the imports

here are the two places that i have to

as you can see here it says firebase

initialize app and we need to make sure

that we're not doing that anymore so

in this case our future remember is um

it's auth service and since i haven't

imported that yet visual studio is

offering to auto import it so i'm gonna

um it's auto imported now but if you

don't wanna if you're you're working

with vim or some other a text editor

that doesn't have that capability you

per package the name of your package

services off auth service dart

and i just noticed that this is another

firebase import which i'm going to

so auth service now we want to tell

because we're using firebase we're going

to say auth service dot firebase and in

here we're just going to say initialize

okay so that fits in perfectly

you can see we're using firebase um

instance firebase auth instance current

user in this case we're just going to

dot our base man current user just like

that okay and now remember odd i talked

about this in previous chapters but

i prefer to have boolean flags prefix

whenever that makes sense and in this

case you can see firebase implementation

had email verified but we have is email

verified so i'm going to say is email

and s or control x and linux and windows

a command is on on mac to save this file

it looks fine right now but we're not

we also have problems in our login view

i mean problems not errors or warnings

but problems in that we're using

firebase directly and we're going to the

firebase auth directly in our login view

and we need to fix as you can see the

caption system login view remove

firebase and replace with off service

so let's go to uh to the source and

remove firebase completely from

command s and now you'll see we have a

lot of problems here and one two three

yep that was it so three three places

so let's go ahead and fix those places

there's a lot to handle here so we start

by this one at the moment we're saying

firebase off instant sign in with email

and what we need to do is just to uh

so we're gonna say auth service and

and auth service has firebase auth

provider and we're then gonna say assign

in or do we say login yeah email

password okay so i'm gonna i'm gonna

take this code the way it is

and i'm not paste then them in

so now we're saying auth service

then we're seeing here that we're

getting the current user and the right

way now to get the current user is by

and email verified should be ms email

verified okay so now we fix those

problems in this area by going to all

the search instead of going directly to

okay that was that now we need to start

looking a little bit at our error

you can see here we have on firebase off

so we need to fix these with various um

exception handlings not firebase auth

but now remember we have our own

exceptions in auth exception start

all coming from exception but what we're

going to do is we're going to have like

blah blah for various of those

exceptions as you'll see soon so um i'm

gonna what i'm gonna do is i'm gonna

take this code and keep it the way it is

and i'm going to add new on statement so

let's take care of user not found so i'm

going to say on user not found exception

and you can see that it says user not

found exception is an exception that we

created manually but it's not imported

here because it was inside the auth

exceptions dart file so i'm going to say

visual studio code please complete that

and also import it for me okay

so say in this case then we have to do

show error dialog so grab that code and

what else do we have wrong password

because it's this thing i'm going to say

on wrong password of exception

and go in here and grab then your show

and then we also need to have the on

generic auth exception so on generic

and we do this show error i like

so then we go and bring that here and

you can see on generic error off

exception we don't have any specific

like information like any e or anything

to string so all we're gonna do in here

we'll just say we're gonna say

okay and then you need to go and remove

catch blocks so your code should

okay so a try block and then three

special exception handlings one after

great command s on your login view now

you shouldn't have any problems in your

login view and there's no import of

firebase in your login view just as it

was in the main dart file let's just

make sure that there's no firebase

yeah firebase yeah no imports of

and as the caption now says we need to

go to register view and remove firebase

and replace with auth service now that

we've done the same exercise now for

login view you should now know basically

what we're gonna do in register view

we're gonna go to pretty much the exact

same thing we did in login view except

in registry removing firebase from the

imports get all the errors that we're

going to get and after we get those

errors we're going to fix the problems

in register so let's go ahead and do

let's go to our imports there's firebase

imported right there we're going to

probably quite a lot of errors yeah

and let's go then and fix that i'm going

to go to my notes just to ensure that

notes that i was supposed to tell you

we don't create user with email and

password in our auth server so let's

and it's not imported so let's auto

import it dot firebase and we're gonna

say sign and what do we call it create

on the end of the last parameter grab

the code and replace your firebase auth

create user email and password with our

and in the place where we're getting the

user let's then say auth service

firebase and we're gonna say current

and now we have send email verification

but i think we called it some something

oh we didn't implement the send email

um send email verification yeah it is

right there so i'm gonna oh i see

firebase implements send email

verification at the user level but we

don't have we don't want that anymore

and our user doesn't have that

functionality actually our user has just

so what we need to do in here we're

going to ask our service to to send that

email verification so we're going to say

and this send email verification just

then we need to fix these exceptions as

well because as you saw in the login

view we don't have firebase auth

exception in this case like we've

ability to talk directly with firebase

by removing all the imports so now we

need to make sure that we handle

exceptions just like we did in the login

each password because i think that's the

um i mean you see almost the entire

screen is now red and that's one of the

downsides of using the extension that i

talked to about during one of the first

course where i'm using an extension

called air lens and air lens extends and

expands all the errors that would

otherwise just happen with little icons

next to the lines it's expanding them

into their own separate lines and it

kind of makes the code look a little bit

angry at times when you're making

drastic changes to your code but don't

worry about it just have a look at your

syntax and kind of see that yeah i'm

kind of doing the right thing i'm going

to fix it soon so don't be intimidated

flags in here okay or these red lines

so let's handle weak password exception

now it's going to be a little bit

then grab your show error dialog

from there and that's for a week

on email already in use off exception

and we're gonna then take the code from

email already and use which is just a

shorter dialog right there put it there

invalid email so i'm gonna go in here

and say on invalid email off exception

let's grab the code from invalid email

and and that part is done as well

also we need to have on generic als

exception so let's go in here and just

say on generic auth exception

and actually this is what we did for the

generic auth exception so i'm just going

put it there and since on generic off

exception we're not accepting any e so

we're not saying on catch like e like

that we could have done that but we're

just ignoring completely at the e and in

here and we're just gonna say failed to

and then let's clean up the rest of the

code remove the other cat statements

okay so your code basically is going to

look clean like this now so you have a

try block and then you say okay i'm

trying this code right here create user

if weak password auth exception happens

do this if email is already in use do

this if invalid email do this or any

other auth exception do this so

it looks cleaner in my eyes at least the

way we've done it now than the way we've

done it before in that before we were

going to firebase and firebase do this

do that on firebase auth exception do

so now the only thing we're doing is

auth related exceptions and that's it

now that we've we've done our work in

the register you can see there's no

errors in the register we need to go to

as the caption indicates so i close

register view now let's open up our

and see what we are doing with firebase

and notes view so do the same thing like

we did before remove firebase as one of

your imports so you get the you get the

idea like an overall idea of what is

happening in here and how we're using

firebase and i can see the only place

where using firebase in notes view is

firebase off instance sign out that's

good it's just one place but we have to

let's then go um sorry i'm just gonna

bring up my notes as well um we're in

so let's just then go to um

here and we're gonna we're just gonna

all right and then we're going to say

log out i think we call it and we need

it's bad so what we could do now

we've removed firebase from there as

as the caption indicates we need to now

go through the entire app and make sure

that everything is working as expected

but before we do that let's have a look

at our views and make sure none of them

is importing firebase so i can see login

view is not importing anything related

to firebase meaning that it's not using

firebase let's go to notes view

no imports related to firebase either

or at least not using firebase directly

remember it's using firebase but through

our auth service okay so no imports from

firebase here either and we have our

verify email view which at the moment i

verify email view oh i see that we

haven't clean up our verify email view

and that's something that we also need

to do so we forgot about that let's

let's take care of that okay

remove this firebase auth from here as

so let's have a look at that now let's

say that uh send email verification

shouldn't be there so let's just then

a current user and i can see you see

here it was using the current user just

to send the email verification but we

don't do that anymore we just

because send email verification is not

at a user level anymore when we've

developed our off service remember so

we'll just say send email verification

and then remove those two lines of code

which were just getting the user and

sending an email verification remove

and and to answer you i hadn't planned

for this i can actually see in my notes

fixed the verify email view and that's

why i'm not showing it in the captions

and that's completely okay i have to

improvise as well sometimes so

let's then go ahead in here in them

in the text button that says restart as

you can see here that needs to just sign

the user out so let's just say off

base log out and make sure that you wait

on it okay just like that and remove

this line of code as well so verify view

now doesn't have any imports to uh from

all of our views except for also main

let's make sure there's no firebase

perfect so now we're done with this and

what we could do as the caption in the

case we're going to do a hot a restart

and let's see if things are working yeah

and i'm just going to say restart here

the current state of the application i'm

going to bring up a firebase console

go to my notes application here

authentication and i can see i have two

users here okay so i'm gonna i'm just

gonna say pixelityab.gmail.com

and let's say register and then it

should give us an error saying email is

already in use so email is already in

use let's go in here and say pixelityab

gmail.combarbaz and i remember from the

previous chapters this is a user that's

already verified his um email address so

by pressing login we should actually go

to the main ui of the application so

logout should work as it did before

uh and try to log in with the user

verified his email address so

you can see then we're getting sent here

verify email and then we can press the

send email verification which in turn

then sends the email and to the user

that was a lot of information and

some improvised edition as well in this

chapter for the verify email view that i

hadn't planned for so it's good for me

to know as well that sometimes i can

miss things as well but now we haven't

missed it during talking about it in

wrap up this chapter we've done quite a

lot and the main goal of this chapter is

we've achieved that because we wanted to

go away from using firebase directly in

our ui and going away from that using

our auth service for everything related

to firebase and that's achieved so

now what we need to do is as we're doing

in other chapters we need to uh commit

and tag all the code that we've done

lost all this code for some reason

so let me change the um layout of the

browse the editor a little bit bigger so

you see it better and i'm going to go

into the terminal which i absolutely

love in visual studio called the

integrated terminal and you can see that

in the previous chapter we had committed

and tagged our code as step that's step

eight now we need to commit as step nine

first let's have a look at status and

status and we say git commit and we say

nine as well and we first push our

all right that's pushed as well

well done great job we are done with

this chapter and as it is uh for the

case for other chapters i've talked

about we usually talk about what we're

gonna do in the next chapter at the end

we're done with auth service it's

but what we don't have are some um tests

there are three different types of tests

that you can write in flutter

unit tests integration tests and widget

a unit test is where you for instance

your current off service and then you uh

want to just say okay auth service log

in register do this do that and

given this condition i expect you to do

this now our auth service is working

we can't be 100 sure that it is working

as it should and let's say you're

working inside a team and there are

three other people working on the same

code base with you and you work on the

auth service and then you committed

everybody reviews the code or

the way i like to do my code is to a

pair program or mob program so there's

no code reviewing because everyone's

working on the same code at the same

time so it depending on how you're

working inside your team then you send

your code then two weeks later a new

developer comes in changes your auth

and to and they change the service that

it makes sense to them but then they

break your code so maybe for instance

screen stops working because they change

the code so that it's not executing the

logic the way you thought it should

execute the logic so that's why we need

the way we design software is actually

uh is the way that it should perform its

work so that it's not missing any points

that's what we're going to do in the

um grab some refreshments and i'll see

hello and welcome to chapter 26 of this

in the previous chapter you saw that we

started using our auth service in

our user interface code so we're not

firebase directly so we removed all the

to firebase in our user interface

and we have a good working auth service

however what we're missing are some

tests and tests are one of my absolute

favorite topics when i talk about

software development because

they make your code a lot more robust

just writing the code and leaving it in

there and i understand some software

look at things as black and white

saying that you have to have codes or

you don't have to have codes but i'm

thinking that well you have to be

realistic sometimes you if you're for

instance writing an application for

yourself in a hackathon for instance and

in in your you're in time pressure and

you just want to get something out well

that's not the right place to write a

unit test if you're in a hackathon

but if you're working with a company and

they and you're getting paid to write

good software and you're getting paid to

write your tests as well to make sure

everything's working out as it should

especially if you're a back-end

developer software like a front-end

then you will need to ensure that your

i'm going to bring up the caption

about why we actually need tests and

um and we're going to talk about the

different types of tests in a while but

let's just talk about unit tests um i

like the outro to the previous chapter

for me the main reason having a unit

test is to ensure that if you if you

think here's the auth provider we left

it in a state that well it's working

okay code codes on code working so

it's working but what if a new developer

tries to change some code so that it

but unintentionally changes it changes

the code so that it's not working for us

the way that we intended it so

that's why that's one of the reasons we

um so that's what we're going to do in

this chapter and i completely understand

that this you if you're watching this of

course you're probably sitting somewhere

in a calm area a calm room and you're

watching this course yourself it's the

chat i think the chances of you watching

this course with a group of people are

um and chances are you're just following

along with the course and you're trying

to write an application or release it to

the app store or play store and play

maybe you're not so interested in making

sure that your auth service is actually

tested and i completely understand that

but i'm basically designing this course

for people who are trying to become also

good software developers so if you're

coming as i've mentioned like one of the

personas that i developed this course

for are designers so if you're a

designer have no background in flutter

development you may also be interested

in writing tests for your application

especially if your goal is to go into a

bigger organization and actually get a

job as a flutter developer or as a

given that background you should know

what tests are what unit tests are

integration tests are and what for

instance widget tests are in flutter

now i need to also mention that

there's something called a tdd or test

doing test driven development is to

write the tests and then you write your

software at the moment we're doing it

the exact opposite because i didn't want

to complicate uh things as we're going

because i have this as i said i designed

this course for someone who's probably

new to flutter development or software

development in general so like going

into test development test driven

development directly and then writing

our off service probably would have

complicated things more so in for the

sake of simplicity we wrote the code and

then we're writing the test but just so

you know if you're if you hear people

talking about tdd tested with the test

driven development what they mean is

that you write the tests and in the

writing of the tests you come towards

the conclusion of how the interface of

the class you're actually writing the

tests for should look like if you're

so test driven development is there's

very important and we should be aware of

it how to use it and if you're

working in a software development

organization you should do test

driven development if time allows and if

um all the constraints are in the right

place for you to actually do tests and

as i said i look at things more like in

vision more like a gray vision

i say that you should do tests but that

is again something that is completely up

to you and up to the situation that

just be aware of what tdd is and that

the right way of doing test driven

development is that you first write your

and then you write the interfaces and

the code that the tests are actually

performing their tests on there's lots

uh lots and lots of resources online

about tdd and what it actually means how

it should be used tdd flutter as well so

i strongly suggest that you have a look

at those resources as well and maybe

perhaps after you've gone through this

chapter and done like the basics of

now um you see we have time limit in

this course because this course can't go

on for hundreds and hundreds of hours um

first because i i wouldn't probably be

able to put so much time i know that

this course is already gonna go over 20

it is it is going to take a lot of time

if you want to go and cover everything

and all different types of testing

for the sake of simplicity and making

sure that you follow along with this

course without dropping off and getting

scared of all testing things that we're

gonna do i'm gonna give you like the

basics and i'm gonna give you the

building blocks that you're you need in

order to be able to carry on later on

your own and write more and more tests

i just know that the reason we're

dedicating this chapter to testing is to

make sure that everybody understands

that testing is very important but also

we are not going to have many many many

hours just to focus on testing

though it is a very important subject

now let's talk about different types of

tests i mentioned this in the outro to

the previous chapter and but i'll

mention it here in case you've jumped

over that chapter which i don't

recommend and if if you talk about

different types of tests in the flutter

you should know that there are unit

tests widget tests and integration tests

and let's just quickly talk about

what these different types of tests are

let's go and talk about the concept for

instance of a class let's say you've

created a class called auth service

which is the case for us and you want to

write some tests for this class now this

class is very isolated in its own in its

own like it is it has a set of function

functionalities functions and it has a

if you don't remember that let me just

bring it to the screen so you see better

um so let's go to our auth service

it conforms to and implements the auth

provider it has a constructor it has a

factory constructor here as well and it

has all the functionalities that are

provided by the auth provider because it

implements auth provider so i'm gonna

actually increase the size so you see

this is a unit of itself so it's a an

isolated piece of code that talks with

an auth provider and then it gives us uh

basically mirrors the functionalities of

that author provider which in in this

case is that in the firebase case is the

it doesn't have so much functionality

but it has functionality good enough in

order for it to be tested and it's

actually important to test it just to

make sure nobody unintentionally changes

this code without without consulting

with us or without like and making sure

that their changes aren't gonna break

our code so that's unit tests so you

have a unit of code you have a piece of

code isolated and you want to test that

piece of code and to ensure the

different functions inside that code um

are working as they should so that's

just like a general idea of what a unit

is now a widget test as its name

indicates is a way for you as a software

developer in order to make it as a way

for you as a software developer to make

sure that your widgets like the ui that

you are creating is working as a shift

for instance if you have a login view in

and this login view allows the user to

tap on a button in order to log in and

you're saying that okay in the ui i'm

going to make sure as soon as you press

until the user is logged in that this

login button should be disabled okay so

that's a piece of logic that you thought

about good idea you put that code in

but how do you test it how do you make

sure that the login button stays

disabled until login is successful

that's where widget testing comes into

play so widget testing is some sort of

uh like an end to end test and by that

we mean that your widgets are probably

talking with your services and with your

your widget for instance the login

or the login screen upon pressing the

login button is gonna call into your

service in this case the auth service

and it's going to go into this login

function this login function in turn is

going to talk with a provider the

provider in turn is going to talk with

the firebase code which in turn is going

to talk with the firebase backend so you

see the layers are stacking up ui is

here the button is on the ui

ui is talking with auth service

here auth service is talking with the

provider the provider is talking with

firebase firebase is talking with the

firebase backend and maybe the backend

is also talking with some other services

that's end to end it's one end and the

you are basically by writing widget

tests you're doing end-to-end testing in

a way okay so that's widget tests

the other things are integration tests

an integration test is where you for

instance have a service which we have in

this case the auth service and the auth

service is in this case the auth service

constructor or the factory constructor

is talking with firebase so if you test

our off service the exact way it is in

that you go and say auth service

issue commands against this auth service

firebase you create a user you sign in

with the user you log out you send an

if you're doing these tests you are

actually doing integration tests so

you're because you're making sure that

the code is also working end-to-end but

i mentioned i mean you're now thinking

okay what if testing auth service the

way it is is integration tests how come

you said in the beginning of this

chapter that we're going to do unit

and that's what we need to talk about

now because you see in this unit test

exercise that we're going to do in this

chapter we're not actually going to call

firebase we're going to call we're going

to do something called mocking

i don't know if i've actually

mentioned some something here

yes i can see that later i'm actually

and mocking in english it could mean

that you're making fun of someone and

that's not this and what we're talking

about here mocking is kind of like you

imitating um a real service so imagine

you have the auth service the off

service has a firebase factory talks

with firebase and it turns talks with

the firebase code and then talks to the

backend we're going to get rid of all of

that pipeline and say we're going to

test off service but we're going to give

another provider a provider that we

control you see the fire the firebase

auth provider has a lot of code in it so

let's go in the firebase auth provider

it talks directly with firebase but what

auth provider that conforms to auth

provider and then write a lot of logic

in that auth provider and provide that

author provider to the auth service

now all of a sudden we have an auth

service that delegates all his tasks to

auth provider that we control the code

for so we know exactly what the sign-in

is going to do we know exactly what the

sign out is going to do or log in and

lock it depending on the terminology

what we are going to do in this chapter

is mocking and i'm going to explain that

soon so let's just jump over that for

the next thing that we need to talk

if you're coming from like a node

background if you've worked with nodejs

or express you know already about npm

which is the node package manager

and you know what dev dependencies are

if you're coming from an ios background

there isn't much of a dev dependency to

be honest with you except if you're

coming from an ios development

background then you know when you're

writing your tests those test frameworks

etc that you bring into your test target

there are inside their own target so

that they're not shipped with the final

product if you're not coming from any of

those backgrounds and you just want to

know what dev dependencies are all

explaining now you see when we're

working with our application if we go to

you'll see that we have a section here

called dependencies and at the moment we

have dependencies on various libraries

firebase auth cloud firestore and

firebase analytics these are the

dependencies or libraries that we're

which if you think this is our

application these are the various

libraries coming in and then we're at

actually at the end of this um

course we're gonna send our application

to app store and google play store

when we create our application to send

to these respective stores we're

bundling the application and all the

dependencies together and sending this

as a complete binary to the respective

however you also have a section here in

your pop spec yaml called def

now dev dependencies are dependencies

that you use and bring into your

during the development of your

application meaning that when you ship

your application which is a term used

saying that when you create the

application and post it to the

respective app store for instance for

review then those dependencies aren't

application so they're only inside your

application while you're developing it

and as soon as you package it up and

send it for release then those

dependencies are not going to be packed

inside the application all right

so as you can see here we need to bring

into our flutter application to make

sure that we can actually run our tests

so you will see here flutter test is

already included i'm going to show you

the command that you'll need to issue in

terminal in order to bring it manually

and that is if we go in here and just

type flutter pop add test dev

okay this job is done now now let's have

and you can see now we have a dev

dependency called test and that's how

you bring it into your application using

this command so i'm going to bring it up

again just so you see it flutter pop add

test and and a dash dash dev if as i

node.js developer you'll know this from

d which adds it as a development

requirement or dependency to your

i'm not going to assume that you brought

in this test package into your

application with the command that i

provided here for you in the terminal so

if then you look at your pops back yaml

file so i'm going to bring this down

if you look at your pop spec yaml file

inside dev dependency then you should

have this test package only inside your

dev dependencies if you see that is

brought into the dependency section that

is incorrect it shouldn't be there and

that is because you've missed perhaps

adding the dash dash dev at the end of

your flutter pop add test command so if

then test is going to be added to

dependencies and that's incorrect so

make sure that you fix that error

okay so let's go to the next section and

talk about that now if you bring up your

explorer you will notice that if you go

to your test folder the entire test

folder at the moment is marked as red

uh actually it's not marked as red like

rendered in red color that's what i mean

heard in in the wrong tone so if you go

in there that folder was read and then

if you click on on this file which is

called a widget test that file is also

red has a lot of errors here actually no

it has one error because it's creating

what we need to do in here because we

don't need this existing test you see

this test was created for us when we

created our flutter application we need

to get rid of it okay so let's go in

here and right click on it and just say

delete and that file is gone okay

so that's the first thing that we have

and collapse this leap folder here as

now what we need to do here as a caption

indicates we need to create a new file

called auth test dot dart okay

so let's go ahead and do that under the

let me go ahead and do that right now

under the test folder right click and

say new file and then call it off test

okay and what we need to do then in this

off test start right now this function

is completely empty so let's first

like that and you can see as soon as we

add the main function in here dart is

intelligent enough to give us a run and

a debug functionality here and that's

displayed in visual studio code i think

android studio also does the same thing

i don't think vim is availa is able to

do that it may be vim is time and time

again has surprised me with all this uh

um on the tool or the text editor or the

id that you're using this could be

different but don't worry about it we're

not actually going to click on these

things so if you don't see these things

in your text editor you don't have to

adding the test package now that we've

imported test packages that depends we

also need to import it so let's go in

and get rid of this editor sorry

explorer on the left hand side and i'm

going to say if we import a package

and there's a file in there called test

start so now we're ready basically okay

you may not have noticed it but

i have this application already running

on my actual android phone as we've done

in the previous chapter so i never

killed this application without a reason

it's always running on that android

phone i can always bring it up with scr

cpy so i can see right here that is

remember one of the previous chapters

one of the first previous chapters when

we talked about adding firebase to our

application i think it was chapter five

or six it was very early in the course

when we brought in firebase we need to

we needed to kill the application

meaning that we needed to terminate the

application and run it from scratch

depending on some dependent actually no

i don't think it's depending when you

bring in a new dependency in your

project you need to always ensure that

you rebuild your project so you cannot

do hot reload and hot restart because

some of these dependencies they actually

need your application to be

then be brought into your binary so hot

reload and hot restart aren't going to

like be able to bring those dependencies

yet at least into your flutter

application so what i need you to do

is to stop the execution of your program

and then let's go in here save these

and let's run the application

without debugging and let's see if this

is going to launch the application

correctly on the right device as well

and i can see yes it is going to run it

on the correct device i change the

screen layout a little bit here as well

let's just then wait for uh this gradle

belt to finish doing its work

it might take some time depending on the

changes that you've made to the

application in this case we brought in a

whole new package called testing to our

it is taking its time and that's

run our code without a problem great

stuff for this chapter i don't think we

need our um device with scr cpy if

you're using ios simulator i don't think

you need it if you're using an emulator

i don't think you need it either so we

could just get rid of it so we don't

have to display it on the screen but

remember my application is still running

um let me get rid of this here get rid

of the widget inspector get rid of the

main dart and let's go to our auth test

now one thing that we also need to fix

before we start writing our tests is

this little functionality here this

you'll see that it has the way we left

um we added a member variable to this

off user immutable class here called is

email verified and the way we're

constructing this auth user if you see

here we're saying off user just give us

this william so if from anywhere inside

a if from anywhere inside of your

application you want to create an

instance of off user you'll probably do

like this off user and then you have to

pass that boolean is email verified

if i as a programmer see auth user true

obvious or false i don't understand what

this true or false is what does that

even mean does that mean the auth user

is turned on is turned off what does it

for that dart has the capability to give

you required named parameters and that

instead of passing true in here you will

be forced to write off user his email

verified true or false like that

so in order to do that as the caption

indicates we need to go and make this a

required parameter and the way to do

wrap it inside curly brackets like this

and then prefix it with the word for the

so after you've done that and this

function is not going to work anymore

because this parameter is missing so

okay and let's just move that remove

now we've achieved what we said we're

um because you see we're not gonna we're

not actually you may think that okay

we've changed this parameter to required

so where are all the errors in our code

why didn't anything break and that's one

of the beauties of what we've done so

far and that we've abstracted away so

much code that the code is a lot more

robust now so because nowhere inside our

application we're actually creating us

users except from this factory function

the only place we have to fix this is

email verified is inside this factory

to me that's beautiful because

doing something like drastic by adding a

required parameter to a class it didn't

break anything so we're just good to go

now this is the point that i mentioned

previously that we need a mock off

in order to do a mock author provider i

need to go a little bit more into what

mocks are and why we need them you see

we have especially in testing as well or

even as the app architecture level or

software architect architecture level we

have something called dependency in

just quickly explaining it is very

similar to our auth service let's have a

look at our off service here you see off

service is dependent on an auth provider

and it's not just making the assumption

that it's auth providers always firebase

it provides a factory for firebase but

it's not making an assumption about that

hey i'm always locked to firebase auth

this is dependency injection so this off

service is dependent on a provider using

constant constructor initializer we're

injecting the provider into it

in a nutshell is dependency injection in

you could go into a lot more details

about it but we don't have time for it

so what is a mock the mock goes very

hand in hand with dependency injection

in that in this case you can see we have

an off service that is mirroring the

functionality of its provider which you

the provider that we're using at the

moment is called firebase what if we

completely new provider that we have

complete control over we can we can make

sure that it conforms and implements

auth provider and we can make sure that

it implements all those functionalities

that is that auth provider implements

and overrides all those but we have some

then we will give this auth provider to

our auth service and then let the auth

service do its magic and and mirror all

those functionalities of the provider so

we're gonna mock an off provider and

service so that's what mocking is when

a new function or a class and then you

place and then test that another place

so let's go in our off test dart file

that we have right here i'm going to

command s on it and let's go and create

our little off like mock off provider

so i'm gonna go in here and i'm just

gonna say class mock off provider and

suggest you do the same thing and this

the auth provider okay auto imported for

now what we need to do is just to get

to implement all the functionalities

that the auth provider apps abstract

class requires us to implement so i'm

going to command dot on it and

respectfully ask visual studio code to

create those six missing overrides thank

you so much visual studio code for

now what we need to do is just to do the

heavy lifting of this mock auth provider

which means to go ahead and create the

functionality for the auth provider okay

i understand that the code is completely

ginormous right now so i'm going to

decrease the size a little bit so you

so let's go ahead and take care of the

first function in here which is create

has a function called initialize all

now when we're using auth provider in

the context of firebase firebase

internally has the concept of whether it

but when we're creating a mock auth

provider where is that functionality we

don't keep track yet of whether our mock

auth provider is actually initialized or

and we just have an initialize function

but what if someone calls create user on

our mock auth provider without having

initialized the provider yet and that's

so let's go ahead and keep track of that

so what we're going to do here is we're

just going to say var is initialized

it is false to begin with okay

and the reason i'm saying underscore is

this is making this property pretty much

private to our mock-off provider so

we're indicating to the outside world

that hey you shouldn't be reading from

this property or writing to this

okay that is done now let's create a

little getter for this property so that

when we're testing our mock auth

provider we can actually say

and we can also create a test for a mock

auth provider which we're actually going

to do is to say okay when we create the

mock auth provider it shouldn't

initially be initialized however after

calling initialize on it then we make a

test to make sure that initialize flag

is set to true so let's in order to do

that we need to be able to read this is

initialize flag let's go ahead and

create a boolean getter for it we call

it's initialized and we just return is

now let's go into our create user i'm

going to put a comma at the end of that

parameter i'm also going to take the

liberty of going and creating and

putting a comma at the end of login

and that's the only two places that had

that required a comma at the end of

their parameter list so now dart

formatter is able to format the code a

okay let's go to create user now you see

in create user i'm pretty much in all

these functions that we're writing in

here for instance login send email

verification we're we need to make sure

that this mock auth provider is already

initialized so we're actually going to

throw an exception if you call these

functions that require initialization

without having initialized the mock auth

provider first so let's go and define a

so let me see actually if i have written

nope so let's go in here and just say

exception so you should know this from

so what we need to do in here we need to

is initialized if it's not initialized

so that's an if statement it's a

one-liner that's why we don't really

break it in here otherwise you put curly

brackets in here and then do the

throwing in there but you could also use

a one-liner if statement if that's all

what you're doing just one line of code

all right and i kind of like these

one-liner if statements to be honest

with you so i hope you got this if the

mock auth provider is not initialized

throw that particular exception

and what we're going to do is just we're

going to fake creating a user okay so

if you call the create user on firebase

for instance it probably needs to go and

talk with firebase back-end so it's

going to take some time so let's build

in some little uh delay in here

and what we're going to do is just to

and here you have to pass the duration

to it so we say const duration

let's just say one in here and remember

future delayed if i go and move over

it's a function signature it returns a

future of dynamic so by creating a

future you're not actually waiting on it

so let's mark our function as async and

this create user actually returns an

author user but remember also in

firebase um or i don't actually know if

firebase works like this by but by

creating a user what we're going to do

in our mock auth provider is actually

logging that user in as well okay

let's just say you see login returns

also a future of auth user so at the end

of this create user we're just going to

make our lives easier and just return

the result of logging in so let's just

so this is a very dumb and very easy

mock implementation of create user in

itself it does three things checks to

make sure that you're initialized and if

you're not initialized it throws an

it does a mock uh one second wait just

to like fake making an api call and the

third thing that it does is that it

calls the login function with the same

email and password and returns the

result of login just so that it can get

okay now we need the mock current user

how do we do that how do we get a

firebase has the ability to keep track

of the current user but how do we do

that we can't just go and delegate this

functionality to firebase right now so

we also need to create an auth user in

here okay so let's go to deter mock auth

off is initialized or below it doesn't

matter somewhere i'm gonna do it above

you see in far in a dart if you make a

member variable optional by default it

is null so it has no value so you don't

have to actually go and say no and you

can see it says don't explicitly

initialize variables to no good good

i don't have a user that we're

internally going to manage and i'm

actually going to make it prefix it with

an underscore so that it is marked as a

private function as a private member

then in the current user simply return

we need to go and take care of the

initialize function let's see if we can

the only thing we're going to do in

initializers we're going to fake waiting

and and then set r is initialize flag to

true so let's grab this code of a weight

from our create user function and then

bring it to initialize and then just say

asynchronous and then we're gonna just

and we're just going to say initialized

so that was an easy one all right so

then the meatiest part of our

mock author provider is actually the

login function because it's not that

it's doing login but it's also

the function that the register

function is using or do we say create

create user so that function is also

it's calling the login function so we

need to really test this function to

ensure that it's working properly okay

as i mentioned before in most of these

functions when we need to make sure that

our mock auth providers initialize

before these functions are called on

them so let's go and grab this code you

see it says if is initialized and bring

that code as well in our login function

so that's the first thing that we're

we're also going to build in some fake

functionality into the login function

just so we can write tests for them

because you see in the real world you

probably have like lots and lots of real

inside your uh auth providers and auth

services but we don't have all that real

logic right now because our application

is quite small right now so we're gonna

build some fake functionality into our

mod provider and then sorry in our mock

auth provider and then we're going to

scenarios so you learn about mocking and

you'll also learn about writing tests

for those mocks okay so that's the

entire purpose of this chapter

what we're going to do then is we're

and so we're going to make up an email

that we don't like we're going to say if

then throw user not found exception okay

so if you're trying to log in with this

email address we're just gonna say user

unlike the foobar password either then

wrong password off exception so

login in itself if we go to our

firebase auth provider so go to this

file firebase auth provider dart it has

those functionalities like if you have a

look at login it has a functionality

like handling user not found wrong

password generic auth exception so what

we're doing is that we're creating some

sort of a mock of kind of the same thing

but we're locking it to specific email

okay so that's for password we don't

like the email of foo at bar.com and we

don't like the password of foobar

we're also going to remove the

unimplemented error here now in this

case let's just create a user so we're

going to say user is and off user

and it's email verified we just say true

or let's just say false actually so we

say when you're trying to log in we're

just saying is email verify false okay

now that we've created a user let's

like this because remember we have a

just keep hold of it like this

and then we will do because remember we

need to return a future of that auth

user then we say return future

of a value equal to our user like this

that was quite a lot of work but i think

you hopefully understand what we did

now we have to look at a logout function

and the logout function is gonna have

um it's not just gonna be saying okay i

logged out as i mentioned before we need

mock provider is initialized so let's

boom okay and we also need to make sure

if you want to log out that you've

actually logged in before so let's just

uh user not found off exception okay

otherwise what we're gonna do is we're

so let's find an await code from before

we're just gonna fake waiting a little

and and we're gonna set our user as well

to null we're just gonna say the current

user then is not you can see it's

complaining that we're using a weight

but let me just say in here then

just like that then the error goes away

because if you mark your logout function

as async then you can wait on a future

so easy as well logout says am i

and in order for me to log out there

needs to be a user and then i'm gonna

fake waiting one second and then i'm

gonna set that user to null so easy pc

now let's mock our email verification

so same thing so you should now be

familiar with this let's just make sure

that we are initialized i'm going to

grab a code from there room throw

unimplemented error actually let's leave

then during the send email verification

what we're gonna do is you see when we

did a login we said that uh let's have a

look at the login we said by default the

email for the user's email verification

is false but upon send doing a send

email verification we're just gonna flip

that flag where all of a sudden i'm

gonna say oh now outside of your email

which which isn't so realistic but

that's the logic that we're mocking

right now okay and remember a an auth

has a and it's email verified it's read

only like you it's a constant you cannot

just because we have an optional user in

our mock auth provider it doesn't mean

that we can just go and say off user is

email verified true we can't write to it

so we need to rewrite this entire user

after checking that you're initialized

what we're doing is saying that

let's get the user actually final user

this let's get your current user and we

and throw user not found so our

send email verification code is make

sure making sure that you've logged in

verification or at least you register

then what we're going to do is to create

a new user we're saying new user is an

off user and his email verified is true

this time and then we set that as our

current user so we say the current user

and then we just remove that and we make

our sure our code async as well

it did take a while but we've actually

written now a mock auth provider that

has its own code and it has its own

now what we need to do is to

so what are test groups and what are

if you think of tests as or at least

unit tests as pieces of code that test

you may think okay i'm going to write a

here i'm going to then write a test for

current user i'm going to write test for

initialized login blah blah now all of

these are common and group they're kind

of related they're all testing mock auth

provider and that's what test groups are

for in your test functions in flutter

sorry in your tests and test suites in

florida you can actually group your test

functionalities into a group that has a

name and then you can ask flutter to run

that entire group of tests for you so

that's what test groups are for

so now what we need to do is to go into

our main test function right there and

basically create a group and then add

provider inside that so let's just go

and in here we're just going to say mock

and let's go in here the second

and like that so now you should have

your code like this so basically you

created a test group and you can see

visual studio code is telling me that oh

so we're gonna put all our mock

authentication tests inside this group

and as a caption says the first thing

we're gonna do is we're gonna create our

an instance of our mock aus provider so

let's go ahead and say a final

is a mock-off provider just like that

so now we're getting to the juicy parts

and i'm so happy about this because

we've done quite a lot of groundwork

just to get to this point for this

so now we're gonna write our first test

so as you can see the title says testing

provider is initialized providers

shouldn't be initialized to begin with

you see we're starting with

an assertion we're saying that according

to our implementation the way we've

implemented our mock auth provider it

should not be initialized to start with

so we're just making sure that by

creating an instance of mock auth

provider it's is initialized the boolean

should return false if it if it returns

true we're going to fail our tests so

meaning that if someone then sneakily

goes into the code later and says oh

this is true by default then the tests

are gonna fail and all the developers in

the team are gonna be notified about

let's create our first test the way to

create tests in flutter is that you

and you give it a name in this case i'm

be initialized to begin with okay so

that's the name then you're gonna

provide it with a function to execute

and in here you could say you could use

it should be false to begin with

that's the first test that we wrote so

test function then you write a name for

it then a function to be executed and in

there you can use various flavors of the

expect there are various flavors of that

right now we're just expecting the easy

now the next test that we have to do um

so as the captioning case test logging

out before initialization the provider

should throw and not initialize

basically what we're saying is that

according to the log out function it

shouldn't be able to log out if it's not

initialized first so we're literally

testing this line of code okay to make

sure that no one just unintentionally

comments it out or unintentionally

removes the same we don't need it all

functionality so let's just say test i'm

going to look at my notes to see what

if not initialize okay now you know that

as a second parameter to your test

function you need to provide a function

and then curly brackets and in here

and now we're using a new flavor of this

expect and in here i'm just going to say

and upon calling this logout function

we actually want to expect an exception

uh catch that you can use in here that

and you can see throws a is a matcher

and it matches the result of the log out

function against whatever you provide

an exception in here you see the const

height matcher is just going to say not

exception so i'm going to type this and

then i'm going to show you what i'm

see what i've done through jose const

and let's see why type manager is not

extract method cons throws i probably

so let's see what is happening here so

what we're telling expect in here is

saying that execute the logout function

we're now testing the result of that

function against something called a

matcher and matcher is because you see

in here you can't say that this result

should be an exception because what are

you going to do are you going to create

an instance of that exception that's not

that's not a good way of testing your

functionality in here you're saying

you're matching the result of calling

the logout function it gains that

expected type as you can see type

matcher is if you go into it you can see

okay so that's how you would expect a

function to throw an exception all right

all right a lot of information um

now what we need to do after testing

that functionality we just need to make

sure that we can actually initialize our

i'm going to bring the code a little bit

up here so you can see it better

go in here and say test and let me see

it should be able to be initialized

and create an empty function in here

then what we're going to do is just to

and remember just like everywhere in

your dart code you can make your

functions asynchronous just by putting

async right before the curly bracket so

it's not a part of the signature of the

function it's just telling dart that

inside this function i'm going to

execute some code asynchronously okay

so upon initializing we then after

initialize if you look at the code that

and a weight of one second and then it

sets the flag of is initialized to true

and we can read that flag by reading

this boolean getter so let's say away

provider initialize and then we're going

the provider is initialized flag to be

all right so that one was an easy one

so after we've done all of this you see

is initialized and doing initialization

is not actually going to create a user

for us so let's make sure upon

initializing our provider that the user

user should be null after initialization

and then let's just expect the user the

current user to be known so let's say

that it should be known all right so

easy to read and it's almost like

all right now what we're going to do is

doing some asynchronous testing i want

you to see this as well because it's

very important now let's say that you're

we want to test as the caption is

telling you testing the time required to

initialize we can test timeouts in this

what we're going to do is look at our

initialization code here and let's see

at the moment is waiting one second what

we're going to do in our test just for

the sake of using how you can test

timeouts and how you you can test for

instance api calls in the future we're

going to do some asynchronous testing in

here with a timeout saying that our test

if initialize on our provider takes more

than x amount of seconds all right so

now let's go in here and say test um

okay and an empty function which is

and what we're going to do in here is to

on the provider's initialization

and after initialization we're also

going to expect the is initialize flag

parameter of our test called timeout

now timeout will provide a constant

duration and in this case we're just

going to say two seconds and i think we

have one extra parameter in here

argument zero expected what one found

cons time and then here seconds

and avoid cons here okay so this is very

simple simply said we're saying that

we're created a test that calls the

initialize function on our provider and

just ensures that that function returns

to the test context before the timeout

has passed so internally this test

function which you provided timeout to

is going to create a little timer and

then it's going to set the timer to

start with as soon as it calls the

this function in here let me show you

progressing and doing its work it's

going to terminate its result processing

as soon as the timeout basically passes

so in this case our initialize function

is going to take one second to process

this work if it can't do that during

these two seconds of timeout that test

is going to fail okay so now you know

so let's go in here and now test the

provider which is creating a user as you

can see we have to test make sure that

creating a user actually delegates to

our login function and we have to test

all the edge cases all right

so let's go ahead and do that let's then

uh create user should delegate um

function and in here we're gonna create

a function which is an asynchronous

need to do is to create this

basically if you remember create user

doesn't have internal logic of its own

it's just going to call login but login

has this beautiful logic that first test

with any password should throw this

error user not found off exception so

let's just test that scenario okay let's

and say final bad email user is

writer oh don't we have our provider

oh i've added this test i apologize i've

added this test i believe at the end of

this entire test group i should have

added it here so if you've made the same

mistake i apologize for that it's my

fault you should fix that and make make

sure that your test is in the same group

where it has access to the provider so

then i'm going to say provider and so

and password could just be any password

comma semicolon make sure dart formatter

formats your code properly so then what

basically returned to us then it should

actually contain a user not found off

exception so let's go ahead and say

not found off exception like this

have to close that here as well

so we're basically saying calling the

bad email user the creation of a user

with that specific email should throw a

user not found off exception and

remember you may think oh we've tested

this before yet but that was in the

actually no we haven't tested that

before it's it's this thing that we've

tested so sorry about that so we've

tested a lot yeah we haven't tested this

now we've tested that now let's test

this scenario with a bad password a

password of fubar you see we have that

logic in our mock provider here for the

login function let's test this scenario

now let's test this code we should throw

the wrong password off exception okay so

i can see that you can't see the code so

bad password user is provider and create

user with the email of let's just say

someone at bar.com and the password is

fubar and that's the password we didn't

now we copy the code from here

that that password user should throw an

exception called wrong password

off exception okay so we've tested that

now we actually should test the um

the positive scenario so let's go ahead

and say final user is awaits provider

foo and the password is going to be bar

remember our our mock auth provider is

not actually testing whether an email is

firebase is doing that but a mock

provider isn't doing that so

we could just provide any email

foo and password a bar and it will just

accept it as long as it's not

it the password isn't foobar and as long

as the email is not footbar.com okay

all right now let's let's make sure that

this user is then being assigned to the

current user of our auth provider okay

so let's expect the auth provider

offer sorry the provider's current user

to actually be equal to this user okay

that's what we did in our create user

remember we create user delegates this

work to the login and then login

internally sets the current user to that

user they just created okay so that's

the scenario now we're testing with this

so what we need to do then is just to

by just creating a user which we're

doing here that the is email verified

functionality sorry that is email

verified um parameter of our auth user

is set to false by default remember

is set is email verified false let's

test that functionality okay so we just

we use email verified to be false

code to be honest with you and i hope

that you got everything that i mentioned

so now that we've done that let's test

the email verification functionality uh

and let's have a look at what we

actually did in email verification

you see we have this functionality not

then we take the current user if the

current user is null then we say user

not found exception and then we create a

new user with is email verified to true

and we're then setting that user as the

current user so that's what the send

email verification code is doing okay

when flutter then runs our code it's

going to run them sequentially so it's

just going to go from top to bottom and

before we test the email verification

we're actually testing create user which

in turn calls the login function so

since we're keeping a hold of our

this create user calling login function

ensures that the current user actually

sets and is not email verified so we can

and we say login user should be able to

get verified uh logged in user should be

okay and then an empty function in here

so in here we then say provider send

and with the final user is providers

and we now make sure that the current

user is not null so we say expect user

yeah expect the user is not null which

as you can see is a great matcher that

you can match something against it so

you say shouldn't be no okay like that

and then we also we need to make sure

that this user's uh verification is set

so it's email verified should be true

then we say expect and we'll get an

error now you'll see user is email

okay and you can see you get an error

here saying that a user is optional but

and do an asterisk here saying that

force force on rapid for us okay

now what we should do as the last test

we as the caption says test logging out

and logging in and this is normal

scenario that should just work let's

create a test for it so let's just say

and we're going to call it should be

able to log out and log in again should

be able to log out and log in

so and a semicolon at the end

so what we're going to do here then is

log out and log in and then we get the

current user and we just make sure that

null so let's say a wait on the provider

and we say await on the provider to log

with an email of just user and password

just like that okay so or just email

because we're not actually validating

the email and password in our auth

provider in our mock author provider

and then we're going to get the current

user so we say final user is provider

current user and we just make sure that

that user is not known so let's just say

which is a method built into

all right that was a lot of work and i'm

we talked a lot about tests there's so

much that you need to go through so much

material and you need to learn on your

own as well about different types of

matters and different flavors of expect

and talking about expect i kind of

and read these things also on your own

and learn about them in your own time as

now the exciting part we need to run our

tests so let me change the screen layout

uh break this and as you can see you can

tell flutter to run your test by saying

flutter test and providing that path to

your test so now flutter is going to go

ahead and issue and go through those

and let's see what we get as the result

and you can see it's giving like time

for all of these tests and it says all

tests passed now i just want to

highlight this before we go on we did a

lot of tests i've prepared these tests

manually so to make sure that they

actually testing important functionality

inside our auth provider however i've

written the tests very carefully to make

this is not the case when you're doing

things in real life your tests should

fail if you've done things right your

tests should fail to begin with and you

then need to go and write your and fix

your logic if you're doing things even

more right you should write your tests

first nothing is going to work then you

should go and write your logic to fit

those tests and expectations so just

because these tests are passing right

now i know we have joy inside we say oh

everything's passing everything's great

but in reality that's not going to be

a lot of work we did let's do as we

usually do keep the tradition and let's

commit our work and and also tag it so

let's then say git status to see the

status lots of things changed

all right we're going to commit this as

and we're going to say in here get push

it's going to push our commit to github

and then we get the tag as well as step

traditions as it is tradition in this uh

philosophy course we always talk about

what we're going to do in the next

chapter before we wrap up the current

chapter so as you can see the cache has

said let's get ready for the next

chapter we need a database to store user

notes before you use or if we use

you see we at the moment we're not

actually writing anything anywhere there

the user can't even create new nodes so

but what if we wanted to give the

ability for the user to create new nodes

and then delete those nodes and update

uh to begin with uh we're going to store

these nodes in a local database inside

the application so you will learn in the

and local databases and how to use them

sorry and how to use them in flutter

in the later chapters we will change

that logic so we'll be won't use sql

lite uh but i believe for any developer

i can't say any developer but if you're

a front-end developer or a back-end

developer you should be comfortable with

databases and that's exactly what we're

in the next chapter so grab some

refreshments and i'll see you in the

hello and welcome to chapter 27 of this

in the previous chapters we've been

our user interface and also we've been

time also to create some um

tests for our services and providers

up until this up until this point we've

been talking quite a lot about like the

logic of going from one screen to the

other uh integrating with firebase etc

however we haven't actually talked about

storing um user created content

inside our application or inside some

what we're going to do in this chapter

is we're going to talk about sql lite

and storing user generated content in

this case the user generated nodes

i'm gonna get to what sqlite is but

first of all let's have a look at the

title of this chapter which as you can

see it says crotlocal storage for

those of you who are software developers

from before and are comfortable with

crowd you can just jump over this

part of the chapter for those who are

not familiar with crowdcrot stands for

create read update and delete these are

four very fundamental operations that

any developer would perform on their

data and for instance if you're a flask

or a django developer node express um

developer you're you're probably already

you're probably using some sort of a

um and you're storing your data in there

and you're just working with the data

and you're familiar with the term crop

but if you're not familiar with it then

think of it as c which is create is you

some sort of a an object inside a

database some such as for instance a

you read of course want to be able to

read that data back for instance in our

application's main user interface you

may want to read the entire contents of

not the entire contents but at least in

user generated notes for that specific

user so that's the r in crowd

which it stands for update um or it

doesn't stand for update it means update

because u is the first letter of update

so on update is for instance if i have

already generated a node inside this

application i want to go and change the

contents of that node then that's the u

and um last but not least you have d

which is delete um and as its name

you allow the user to be able to delete

their own generated content from the

what we're going to do in this course is

talk about sqlite that is a database or

library and a library created in c

see as a programmer language c that

allows us to store data inside a file

now if you're if you're coming from like

the backend world if you're if you're

programmed with inside with python in

django you're already familiar with this

because sqlite is the default database

that will be provided to you in django

and a flask as well i believe is using

sqlite by default which is very similar

but if you're not familiar with sqlite

is i've prepared a website here which i

mean i haven't prepared the website i've

so you can see here i'll increase the

size of the font here and you can see

sqlite is a c language library that

implements a small fast self-contained

high reliable full-featured sql database

used database engine in the world well

just think of sqlite as the database

engine that we're going to use in our

application and it's not something that

is built in inside um flutter we will

have to use a so-called plug-in for it

but that's also okay and i mean not many

languages have support for talking with

but we'll get there we'll get to that

now let's talk about how we're actually

going to integrate with sqlite and to

start with so i'm assuming that you

don't you have never worked with sqlite

before or you haven't worked with any

type of database before and you're

trying to learn how to do that okay so

that's that's been my assumption from

the beginning of this course so if

you're already seasoned developer you

know exactly how school sql light works

you may want to jump over this section

of this chapter and get to like more

juicy parts where we integrate actually

with equal light inside the floater

so let me close this um or maybe let's

and what i'm going to talk about now is

a free program called db browser for sql

lite you see sqlite allows you to

sql lite has different components first

you have your database which is just a

and then you will have the sqlite

engine that can read from this this file

and write to this file so that's the

engine and then this engine should run

somewhere so it's either going to run

inside an application such as the one

i'm mentioning here a db browser for sql

light okay so sqlite's like baked into

that application or you can also bring

sql light into your terminal so that you

can actually talk with sql lite

databases from within your terminal

or if you for instance have install

django on your computer then you can use

django in order to integrate with sql

iso sqlite is the engine that talks to

uh which are your databases but then

it this engine should run somewhere it's

not just an executable that like you say

here take this file you now have to have

like some sort of a container where the

sequel light engine basically resides

when we then talk about our flutter

application we're going to bring this

engine into the flutter application so

our app can talk with that database but

for now we're going to look at a program

called db browser for lite db browser

for sql lite is a free and i believe

it's an open source program let's search

website and um and as you can see the

official home of the db browser for

sqlite and this is how the program kind

um i'm not sure if yeah i can see now

it's actually available for windows mac

os and it would be amazing if it was

uh and you can actually use snap so

that's great so if you're on ubuntu like

not on this machine right now but if

you're on ubuntu you can actually use

snapstore or even debian any type of

operating system linux space operating

system that has snapstore so that is

really good even on arch linux fantastic

all right on debian you used apt so

that's fine but anyway so it's available

for windows linux and mac os so i need

you to basically go to sqlite browser or

db browser as it's called db browser for

sqlite if you go to the home page i need

and let me change the screen layout so

and i need you to download this program

okay i've already downloaded it on my

computer so i'm going to close that

safari window and i'm going to bring you

the db browser for sqlite as it looks

the only thing i've changed on my

interface here is i've changed the font

not because i don't like the number 13.

it has nothing to do with that but it's

just i thought 20 is a little bit of a

nicer font size for this course um

all right so what are we gonna do now so

the structure of our database and how

if you think about how we've created our

user interface in that here's the user

interface if we go here you can see that

we can register with different users so

then we have a user entity or a user

table as we're going to call it

the creation of these users in our

database so imagine that we will have

some sort of a table some sort of entity

in our database that is dedicated to

users and users are probably just going

what are they going to have they're

going to have an id and an email so as

you remember when you create a

when you register a user with firebase

you always get a user identifier so

plus the user's email in our database

okay so we're not gonna store the user's

password that isn't that is an absolute

so user id which comes from firebase and

the email address we're gonna store in

we are going to have another table and

another table in our database dedicated

to notes so as a user when i log into

the application i should be able to

create my own notes and these notes

should be kind of like bound to and like

they should be glued to my user so if my

user is in the database i should be able

to have notes and if my user is deleted

all those notes should kind of also be

deleted from the database so it's kind

of like a cascade for those of you who

are familiar with back-end development

that is like the structure that we're

going to set up for our database so

in our i can see in my notes that for

our notes table we are actually going to

integer in that table that like binds

every node object to the user who

created it but we'll get there so don't

so i'm going to get rid of this

now what we need to do is start testing

so we want to create a database a simple

database and start creating some tables

in there okay so what i need you to do

is just to press the new database and

i'm going to save it on my desktop and

let's just call it testing okay

okay you can see now we created a

database and we have a table here it

doesn't look so nice i mean it's not

rendered so fine because i've changed

but you i think you can you get the idea

so what we need to do is to as the

caption says we need to create a table

so go in here at the table section here

and i'm improvising a little bit here

because this is like something that i

plan to show you but i haven't actually

prepared any notes for it so let's just

go ahead and create a table here called

user and as you can see we're gonna be

fields in here what is called a field in

here is pretty much just like a column

by creating a field you're creating a

column okay and the great thing about db

browser for sqlite is that you can see

code that will be generated for you

which we're actually going to use later

when we integrate sqlite into our

flutter application but for now i just

want you to get the idea of how sqlite

works how it creates the tables et

empty table it doesn't have any fields

or columns i need you to press this add

button right here and what we're going

to do is we're going to just create um

now if you're not a developer or

software engineer friend before you may

know about id field and why it's

important or if you're a developer from

before you may know id as primary key

um an id is just usually an integer

identifier an integer is a number so a

number identifier for every row that you

later later insert into your table so

usually an id is something called a

primary key and a primary key by default

unique what that means is that for you

to be able to create a user in this

table it has to have its unique

how we are basically treating users in

our user interface is that we're

treating them by their email so you may

think well the email is a unique

thing as well so why don't we go with

uniqueness off the email well we can

apply uniqueness constraints on the

email field and or the email column but

it is very well established pattern in

world where you're working with

databases that you i mean you can make a

unique such as then such as an email but

a primary key is usually an integer such

as pk or id so it's just a convention

and it's also a good practice to not go

like a uniqueness of a string because it

takes more resources in order to

calculate the uniqueness of a string

than it takes for an integer so we're

then going to call this field id

going to be integer and there are some

fields in here which are not rendered so

well i'm going to increase the size of

what we're going to do in here um

we're going to take you see n n in here

at the type we're going to leave as

integer that's fine n n means not null

meaning that this field should always be

present it should never allow the value

and emptiness of the value or the

absence of a value to be present there

okay the absence of value to be present

i hope that makes sense basically just

means that the value cannot not be

either so we're we're going to leave it

like that pk stands for primary key and

that is what i oh actually i can move my

mouse over them that's great primary key

it means that it is the key using which

table using which we should be able to

different users from this table so what

we're going to do is we're going to take

ai is auto increment i believe and auto

increment is a great functionality in

sqlite and many other uh databases that

allows you as the as the name uh

and as the name indicates that by you

creating for instance a user with a

specific email and you insert that user

into the database in this table

and you don't even have to assign an id

to that user you just say here is the

user email boof put it in the database

excuse me then sqlite is smart enough to

say oh i but i need an id field as well

you haven't provided it and then it

looks at this field and says oh id is

auto increment so it's going to create

that id for you and increment the

previously generated id and assign the

new id to your object for instance if

you have no objects inside this table

and then you add a new user then it

automatically gets the id of zero

and then if you generate the next user

and put it in there then it will get the

id of one so you get the idea okay and

that is exactly what we're gonna do for

and unique is just yeah as its name

indicates this field needs to be unique

but if you indicate something as primary

key implicitly it is a unique field okay

and to be honest with you we could

actually check not null as well meaning

that yeah it should always be there so

so that's for the user field okay

and now let's go ahead and create a new

like this and for the email you should

and what we'll do we'll say it shouldn't

be null and also the emails are unique

so have a look at this now it generated

code for it that says create table user

id integer not null email text not now

unique and it sets a primary key of id

with an auto auto increment so

this is kind of like the code that we're

actually going to use in our flutter

application in order to programmatically

later but for now just keep it in mind

this is kind of like the syntax of

sqlite table programmatically okay

all right so then you can press ok in

and now you can see the user table has

been created for you and here's the code

for it or the schema as it says right

great stuff now as we did the user table

we need to go and create our notes table

because remember from before i said

we're going to allow the user to create

notes when they're logged into the

application and by the time they're

actually logged into the application we

should have already created a user uh

and then by creation of every note we're

going to create also a new note in the

database in our note table which we're

just going to create as the caption

and then we're going to bind that note

to that user in the database so

i need you to go here then and then we

need to create a new table by pressing

so as the caption in the case here let's

and we're then gonna start by creating a

new field called id and we've already

gone through this you know exactly what

to do in here an id field as integer and

we say it shouldn't be in it shouldn't

and i think that's it to be honest with

auto increment as well of course so

all right so that's for that's for the

what other fields do we need in here so

what we could say is for instance that

you have a a user id and so you want to

and what we're gonna do in here we're

gonna bind this we're gonna say

literally that this oops where did it go

oh it's a little bit strange interfacing

um so user id integer and we're going to

and also what we're going to do is to

what we want to do is for this user id

a user tables id field and that's that's

foreign key so you have a primary key

which is the key that your table itself

manages as its own field and then you'll

have a foreign key as its name indicates

that it is it is a field inside your

table that is bound to another tables

something else column so in this case

our user id should be bound to the user

tables id column and you can create that

with db browser for sqlite inside

we add a constraint and we say we have a

and you can see now it says foreign keys

or id references it's not at the moment

field is hidden somewhere to the right

and how we could possibly create that

let's see i just remember from before

that this was a little bit strange to

get working from the beginning so

name oh maybe it's it's the name right

so let's say user id references

sqlite foreign key let's see how it's

created foreign key user id

should we say um in here if i say blob

foreign keys ready references

so that's not that's not really what i

wanted in there so i'm going to remove

this plot that i just created and let's

see if we can change the sequel we can't

are there no other fields available here

and i want to remove this just to see if

i've made any mistakes in there so

so here i can see we have a user id and

then there is a foreign key and i can

see here this is perhaps the right

actual way of doing i remember there was

something really strange about it and

now i remember that it is hidden under

this foreign key um column unfortunately

i believe it's a little bit of a strange

interface that's okay i'm just still

very very grateful that we have db

browser for sqlite as a free software

and perhaps even an open source software

i'm not sure about that and i'm very

grateful for every developer who's

that's understood but what we're going

to do here in here we want to bind this

user id to the id field of the user

table so just click here under foreign

key and double click actually i can see

then this magic thing appears here

so let's go ahead and say that we want

to bind this to the user table id field

i believe that should be it yeah and you

can see now the code generated here says

we have a foreign key called user id and

it references the user table id field

perfect um now we also need to do is to

create another field in here and that's

so what we're going to do for notes is

going to be very simple our notes are

not going to include any sort of

they're not going to include any sort of

images they're not going to include any

ordered list or unordered list they're

going to be simple texts okay and they

don't even have titles the title of a

note we're going to derive from the text

so for the text of the note let's just

i believe i believe that's all we need

user id text and yeah that's fine and

also to be honest with you if you want

to you could also create a other fields

in here you see in this uh in this

course what i what i want to do in the

beginning is to allow us to create a

local database that you can store all

the users notes in it but i want you to

later in the future get rid of this

local database and replace it with

firebase that's like the goal um however

some of you may actually decide to keep

this local database store the user's

information in this local database and

not the user's information the user's

notes in this database and then you may

want to decide to have some sort of a um

utility service that sits in the

background and syncs these notes with

firebase at appropriate time so

that's up to you if you want to do that

then you may want to actually create a

little fill in here that's called is

synced with server or something like

or it's synced with cloud i've

called it in my note so let's go ahead

and do that although we're not actually

going to use this field but i just want

to demonstrate to you that this field is

then in here let's say it is an integer

um and we're going to say the default is

true could be translated to any value

that is not 0 and 0 could be translated

to the value of false so putting the

zero in here meaning that it is not

so let's then go ahead and say that uh

this is integer and it's um we should

say it's not null and um and it doesn't

have to be unique so now you can see

that this is the result of the creation

of our tables this is id integer not

null and the id is also primary key in

auto increment then there is a user id

which is integer not null but it's also

a foreign key to the user table under

or the id field and then we have another

field here says text of type text and

then another field that's called isync

with cloud integer not null default zero

and i'm going to press okay and i need

to do the same thing on your side all

let's go ahead and move on to the next

point that we're going to talk about you

see as the captioning case we need to

create these programmatically otherwise

database that we just created called

manually into the documents folder of an

application i'm going to explain what

now we have a file called testingdb it

has the database for our application

we need to be able to create these

tables programmatically if they don't

exist inside our application you see

this testing db for me is sitting on my

desktop it has absolutely nothing to do

with our flutter application and you

could be smart and like drag this db

into your firebase application flutter

application and then kind of copy it to

the right place when the application is

is executed in the user's telephone or

and then try to read from that database

it is possible but what i'm going to do

in here is i'm going to show you

a better way of doing this in that we're

going to actually create these tables

programmatically in our flutter

you also see that process and how that

works how can you integrate with

sqlite inside your flutter application

all right so in order to do that as a

captioning case we need a few

dependencies uh we need sql sqflight

and um i'm gonna then explain to you why

we need these dependencies you see sql

sqflight is a package it's a third-party

package that we need to add to our

application in order for our flutter

application to be able to talk with sql

so that's that's that and that is for

storage actual storage and talking with

the database that package used for okay

now there is a dependency that we have

to drag into our application called path

and path is used for us to be able to

grab the applications documents folder

so that we can actually create a file

inside a documents folder and place our

data inside that file just like i'm

placing the data for nodes and user

inside this testing db file on my

uh provider and the path provider uh i

may have actually taught set paths but

it's actually called path provider path

provider dependency allows us to grab

documents folder and if you're not

familiar with mobile application

development you may not know this but

applications that sit on the uh on an

android phone or tablet and on ios

they have their own file structure so

every application in itself has a

whereas on your computer like if you're

sitting on a from a laptop or a desktop

you have a documents folder that other

applications that run on your operating

system could get access to so it's one

documents folder every application can

request access to and store information

in it and read from it but that's not

the same concept in mobile devices and

on tablets in that every application

runs inside something called sandbox the

sandbox is like a it's like a

cage inside where the application

resides and all the application data

every application can request access

from the operating system to read its

own documents folder okay and that is

package is gonna allow us to do

to find our applications documents

folder in which we're gonna store our

we also need as i mentioned a

we need this path just for a very single

let's say that we have uh use path

provider to get our documents folder now

create a file in this documents folder

and kind of like get the full path of

this file documents folder slash

this file and that's what we need the

path package because it has a great

function called join that allows us to

take the path or of a directory or

join that path with a file name and it

back so we can access that file okay

a lot of information i'm gonna take this

screen so you don't see it and i can see

here it's asking for to control this

computer's access now i'm going to deny

um all right so what we're going to do

i'm going to bring our code up if i can

and here's the code how we left it in

and i can see that it is running

excuse me in scrcpy i'm going to bring

it here i'm not actually sure if you

need a crcpy in this chapter so it may

be better for me to just to minimize scr

and i'm going to make this code a little

bit bigger here as well okay

is to first before we go ahead and

actually create our notes service is to

bring in those dependencies okay

let me change this screen layout a

little bit so you see better i'm going

so i need you to go to your uh

editor text editor or id if you're using

and we need to bring in those uh

so let's go and bring up uh your web

browser and say pop.dev and in public

dev search for sql flights okay and you

can see it's right there and the way to

install it is very simple you should be

uh flutter pop at sqflight so let's go

and let's give it a flight remember it's

okay that dependency has been added then

i'm going to say flutter pop add provide

a path provider and we can actually

search for it in popdev path provider

it's developed by the people who have

brought us flutter and so to begin with

at google so it's not really a third

party application or third party uh

package and we can actually have a look

at sql flight as well and see who's

oh it's another yeah it's another

publisher is not flutter themselves so

let's go back to path provider

installing as we can see is flutter pop

add path provider let me just copy that

and then we also need path so let's go

back in here and just type path i

believe this is my flutter team yeah

dark dev so let's just say flutter pop

alright that's going to do its work and

then you should be able to see those uh

dependencies sqflight path provider and

now that we've done that we can go and

do what we uh are supposed to do in here

which is create our notes service you

uh in the description i've provided here

in the caption i said that we're in

creating inside a folder called crud

and we already have lib services you can

see in here lib services and lib

services auth but we don't have crud so

i'm gonna go in here in lib and just say

new file and i'm gonna say services

absolutely it's saying that it already

exists so inside services i'm going to

say new file then i'm going to bring it

so you can see it as well oh where did

i think i need to change the screen

layout so unfortunately so you'll see it

better services again new file in here

a new file uh third time or fourth time

lucky crud and then nodes service

what we're going to do with this node

a hold of our database it is the primary

service that is gonna work with

our sqlite database it's gonna grab

create new users delete users it's gonna

find users it's gonna create notes

delete nodes update nodes everything

everything that we need from our user

what we need to do inside uh are

so what we need to do now is to actually

i think before we do that we need to

let's import our dependencies we need uh

three dependencies if you remember path

path provider and sqlite so

bring those in here so we don't have to

so imports are kind of like boring and i

i don't rather not type them so let's go

in here and you can have a look at what

i've imported here package sql flight

then we also have the path provider okay

so that we can get the documents folder

for this application and then we also

are importing package path path and then

i'm doing this show syntax in order to

bring in this particular function called

you could also skip that but the problem

is that then you get everything inside

path of dart and that's not what i want

so i just want us to get this particular

path.dart and you could also do the same

thing in here to be honest with you you

could just say show um and i think the

function is called get application

documents directory so let's do that why

not let's just get that particular

function from path provider as well okay

we don't need the entire path provider

what we need then is for us to be able

current database path as i mentioned are

every application that you develop with

flutter for mobile application mobile

devices such as android and ios and ipad

os they have their own documents

directory and we're going to create and

we're going to get the path of the

documents directory and then we're what

we're going to say is we're going to

with a name that we are going to specify

what we need to do then is to let's go

ahead first actually and take care of

some other important matters that uh

need to be dealt with before we actually

create the function functionality for

for our database uh implementation you

see note service is going to talk with

database but before you can do that it

needs to have some sort of dart

representation of those two two very

important tables that we created um user

and note so if you read that data from

the database how are we going to

represent it inside our dart application

and for that we need dart classes

what we need now is to as a caption in

the case we need database users create a

class called database user inside notes

all right that is going to be a bit of

code so i hope you're ready for it

and let's just go ahead i'm looking at

let's go ahead and create as the caption

indicates we create a class in here

a little bit bigger class and i'm just

going to say database user okay

now if you remember from db browser for

sqlite i'm going to bring it here every

oh we can browse it but i want to go

and modify the table save it and you

remember it had an id and an email id

was integer and email was text so that's

what we're going to define in here okay

so we're going to say final and id and

get help from visual studio to

completely complete this i'm not going

to explain these again and again because

we've explained this quite a lot in

previous chapters so by this point i

just assume that you know what these are

let's make this a constant initializer

and then let's go ahead and say these

parameters are required parameters so

they become also named parameters by

and that's that put a comma here so we

get dark formatter to do its magic

actually you shouldn't remember because

you don't know this maybe yet but when

our database we are going to read

for every row that we read from our for

from that table so every user inside

table called user is going to be

represented by this object a map of a

string and an optional object okay so

that's a row inside the user table

node service that we're going to create

users from the database and it should be

able to pass this to our database user

class and the database user class should

create an instance of itself

depending on the values inside this map

all right so let's go ahead and create

a constructor we call it database user

and then we say we get a map of a string

and an optional object in here and then

let's just call it map okay

so what we're going to do in here is

we're going to create the shorthand for

creating and constructing our object and

we'll say the id is equal to inside this

map there needs to be some sort of a

column called an id column so instead of

hard coding that in here like this let's

go and define a constant here and just

call it id column and let's just say

that this is equal to id and in here

we're just going to say id is equal to

ib column just like that all right

and then what we're going to say is we

also need the email an email is equal to

and remember we have the email i'm going

and let's go and have a look at this

email which is text right there okay

the table that column basically is

called email so let's go and go ahead

and create const i'm going to make this

a single single code as well because

that's like the preferred way of doing

it and let's call it email column and

full email and in here i'm just going to

and this should be as inked so

i mean it looks complicated but it

really isn't so and you can see it's a

constant so we could also actually tag

this as immutable and we need to import

foundation in order to be able

now that we have our database user we

need to also implement a few more

this class before we're actually done

so the three things that we need to do

for it is first to create like a string

descriptor for this class so that if

we're printing out this user to the

i mean before i say otherwise if we're

printing out an instance of the database

user to the debug console so we're

looking at the various users that are

if we do not implement two string on our

class it's literally just gonna say

instance of database user in the console

and that's not so useful so it's my it's

habit to if i'm planning to print out

these things to the console it's my

habit to go and implement two strings so

let's just in here say to string

and it gives us the overwrite and what

we're going to do in here is just we're

and email is equal to dollar email okay

so that's for your to string

then what we need to do is also

implement some sort of equality

behavior for our class you see we want

to be able to see if two different

peoples that we've retrieved from the

database are equal to each other or not

so if if i say if person x is equal to

person y then like read the person wise

notes such as something like that so

let's go and implement equality for our

class and the way to do that is you

a boolean operator and it's called bool

and in here you would have a covariant

which we haven't talked about yet and i

will talk talk to you right now about it

what covariance is is a keyword in dart

that not many people know about but it

allows you to change the behavior of

your input parameters so that they do

the signature of that parameter in the

super class so remember we're doing

overwrite here meaning that there this

functionality this operator is already

defined at the object level so let's go

just type object somewhere for instance

and then say object and then command

click on it just so you can go there and

equal equal and you'll see in here that

it says external operator equally and

the parameter should be of type object

now we don't want to do that we want our

classes to be compared to other classes

of the same type so if you don't

put covariant in here you'll get an

analyzer and you'll soon see that

actually we're going to remove that soon

in here we're saying that we're going to

compare our class with equal equal and

instance of our class with equal equal

and we're going to compare with another

user of the same class okay and then

here we're just going to say our id

should be equal to the other id that's

now let's go ahead then and remove this

and now you'll see you'll get an error

saying that oh wait a minute according

to object equal equals should compare

the current object with another object

but using covariant you're telling dart

that hey i'm not comparable with other

objects of any other class i'll only

comparable with database user instances

so make that happen all right

then after you implement equal you have

to also implement hashcode as is

suggested by the analyzer so i'm going

from visual studio code and i'm going to

and in the overwriting of hashcode i'm

just going to return my id's hashcode

okay so this basically the id is

becoming the primary key of this class

using which it will hash itself so it

can be placed inside maps or

if you're a ros developer or

a dictionary if you're a swift developer

uh that's hashing okay so it feels like

we're actually done now with this um

with the with our database user so

and that was quite a bit of code but we

all right now that we've done the

database user we need to do something

similar but this time we need to do it

for our nodes so we have a database user

now we have to create something called a

and i'm going to do that under the

database user just so that we can have

closer access to these constants all

so i suggest you do the same thing so

let's just say we create a class and we

and remember from our database schema

that a note so if i go in here and say

right clicks right click and modify

table then we had id user id text and a

field call is synced with cloud all

right so let's go ahead and do that id

is integer user ids integer text is text

or string as ins is synced with cloud

integer in here but we're gonna

represent it as a boolean all right

so keep those four fields in mind so

let's go ahead and say final id and

and we have a final int in our database

we call the user underscore id because

that's a convention in sqlite

or sql generally that you don't put you

like you don't write your fields with

id usually you don't type like this the

way we type with camel case in dart in

other languages we just say user

everything's under everything is

lowercase and different words are

separated from each other with

underscore but that's not the case in

dart and other languages instead we say

user id like this with panel case all

and we're also going to create let me

just move this a little bit there and

we're also going to create um

last we're going to say is synced with

cloud something like that all right and

again remember we're not going to use

this input cloud it's just for you to

understand how we create different

and yeah it's just it's just something

that you future you guard yourself

against future changes in your database

schema so by doing this you're allowing

yourself to play with this field so that

you know every note that is locally

created in the local database is not by

default sync with the cloud all right

i want to get help from visual studio

code to complete the constructor for

this and i'm going to go and do

all of these fields as required so i'm

going to say required and i'm going to

copy that paste it right there paste it

right there and there and then i'm going

to put a comma at the end and command s

on mac or control s in windows and linux

to save this and get dart formatter to

all right so that's the initializer

and we kind of also need to do the same

thing that we did here for our database

user and that we need to instantiate it

from a row so let me copy this code the

and i'm going to bring it into our

database note i'm going to paste it

right there and instead i'm going to say

this from row initializer creates a

in our database note we have an id

but we don't have email so in here we're

is map then we need a new column which

is called user id column okay so let me

just see my notes how i created it

yes i can see it's called just user id

call so go ahead and create a new

user id column which is if you remember

from our schema it was called user

and here we say user id is equal to map

as a string and it's complaining right

now because we have two more fields to

initialize but we haven't really read

their values from the map so text and is

synced with cloud so for text we're just

going to say text is equal to map

consonant in here we say text column

and that's equal to text so it's just

the name of the field or the column here

so let's go ahead and say that's text

and we say add string and i believe

and we'll be calling a string can be

initialized oh sorry about this the user

id can't be a string it should be added

in so let's just say it's an int and

last but not least is synced with cloud

async with cloud actually is read from

from our database as an integer remember

is synced with cloud as an integer so

we're going to first define a column for

and we're going to call it async with

i mean i'm saying uh we're going to call

it but actually we've already called it

we called it is synced with cloud so

just need to copy and paste that in here

okay and then we're going to say is

synced with cloud as equal to now

you see we don't have this uh

data we don't have this field as a

boolean in the database we have it as an

integer so we have to read it as an

integer so we're going to say in the map

there's a column called async with cloud

column and it's an integer okay

if that is equal to one then

is equal to one true otherwise false so

you see what happened here we read the

and oh if it's equal to one then this

guy is equal to true otherwise this guy

now that we've done the initialization

database notes from the from the row we

we need to create the tostring as well

so let's go and overwrite to string

and we're just going to say this is a

and its id is equal to dollar id is text

or just its user id is equal to dollar

which is a field that we have

and then we are not going to print its

entire scene is an entire text instead

we're going to say is synced with cloud

other is synced with cloud just like

all right so yeah i mean optionally you

you may also add text if you want to

the problem is that the text of a note

could be so long that it actually gets

in the way of you getting information of

your class instance such as its id user

id and a single class so maybe if you

want the text to be there just add it at

the end so it basically doesn't disrupt

the rest of the fields that you may

actually have interest in reading okay

from uh tostring right now but we

haven't done the equality so let's go

and overwrite the equality as well and

the hash node hash code sorry

i'm going to copy that code from our

database user and bring it into the

database node and i'm going to then

paste it right here so you can see it as

we're in the equality we're saying that

we're comparable with a database note as

long as our id is equal to the other id

for the hash code then we're going to

get our id's hash code all right just

like we did for the other class

wow that was a lot of work to do

okay now we've created the database note

as well as the caption indicates um

so what we need to do now is just to

make sure we have all our constants in

place before we carry on now remember

right after doing these classes we're

our um the actual note service that

talks with our database all right so

before we do that let's create all the

necessary constants such as

the file under which our database is

going to be saved so let's just call it

bb name and we're just going to call it

notes.db all right remember this is like

the file name okay now we're going to

create and you can see in here in our um

file here in as db browser for sqlite we

call this file testing.db and in our

case we're just going to call it nodesdb

and we're going to store it in documents

folder inside that application okay

and then we have two tables and notes

table and a user table so let's go ahead

and create them notes table is

user table means user and these are like

table names as we define them here node

so those are those and what else do we

need um i think i think that's pretty

much it to be honest with you i think

these are all the constants that are

needed in order for us to be able to

all right let's go ahead now and start

with our note server so i'm gonna clear

this go to the top of this file and then

i'm gonna make some empty space in here

and actually create our notes service so

let's go ahead and create a circuit

class here and call it node service

it's very exciting this is the beginning

of us creating a cross service that

works with our database which we're soon

going to create actually okay

as the cache indicates we need a

function an async function that opens

the database you see opening a database

is not a functionality that you can just

say open now it it will happen

asynchronously because we may need to

for instance grab the current um

do documents folder and then append or

join that documents folder with

our database name which we define here

as a console so it's a lot of

asynchronous stuff that we're going to

happen in there well not a lot but a few

and that is the reason this open

function is going to be asynchronous

so as i caption any case let's go ahead

and we call it async like that

now this open function is going to keep

i mean after it has opened the database

store it somewhere in our node service

so it's going to say hey i've opened the

here is the object so that other

functions in the future such as the

functions are going to let us

users from the database or you read

notes from the database those functions

then they're going to say ah oh here's

the database instance i know how to grab

what we're going to do is to say we have

as you can see it is brought by our

and we're just going to call it db all

to begin with is null and we're going to

let's go ahead then and start by doing a

test and see if this database is already

opened you see if we have an instance of

this database then we can kind of like

assume that this database file has

already been opened and we don't have to

open it anymore so let's just say if

uh a new exception and we're gonna just

call it a database already open

exception so let's go and define an

let me see if i can copy and paste that

but you see this is just an exception

that's a database already open exception

all right so in here we're just going to

say database already open exception all

simple if you call the open function

multiple times while the database is

already open you're going to get an

exception okay so that kind of makes

so let's go ahead and now get the

directory path and we have to do a try

because this can actually throw an

exception so let's say find final

and you need to say get documents get

application documents directory if you

have a look at the signature of this

method it says i return a future of

directory so let's go ahead and do that

so we need to await on it and that's the

reason our function is async and that's

the reason we're awaiting because this

path asynchronously now if you look at

the documentation for this you can see

that it can actually throw an exception

called missing platform directory

exception if the system is unable to

all right if for some reason this the

system isn't able to provide a document

um to us is going to throw this

exception and that is exactly why we

have our code inside a try statement

here so let's say if that exception is

thrown like this then we're going to

throw our own exception so let's define

an exception we call it unable to get

this so it's just a class unable to get

exception nothing special about that

and then we in here we say throw

the name missing platform oh i see you

see it's it's complaining now and i can

see that you couldn't see the codes i

apologize for that it's complaining and

saying that i can't find this missing

platform directory exception and that is

because this is specified in this um

path provider but for our path provider

get application documents directory so

all other symbols are hidden from us so

we could just remove that and just

import the entire path provider and that

now let's do this now let's say

i apologize let's get the the actual

database so to do that you will say and

what are we calling it db path is equal

to join remember we have this function

joined here that we imported from path

the docs path the path and our db name

remember the db name is a constant as a

string we define it down here we just

that is now going to be joined with the

actual path of our documents folder all

is we're going to say we now want to

open the database with a function called

open database which comes from

and the path is dbpath and remember this

open database i believe is the future of

our database you see so we await on it

then we assign that to our uh local

database instance that's it

opening the database so we've now opened

all we've been working on right now is

inside this db browser for sqlite

thing this program here is managing its

own database file this database file is

not going to exist in your flutter

application we've just played around i

just showed you how to create a sqlite

database how to create different tables

what fields are what primary key is so

you need to kind of like forget about

this this application and where it

you need to now focus on how is your

flutter application going to be able to

create those tables how is your flutter

application going to be re reading data

from the tables or deleting data from

if you think about it if you've

completely forgotten about the

db browser for sqlite then you could

just say at this point in time you see

open database also can create the

database for you if it doesn't exist

we can look at the documentation for it

opens the database at a given path by

uh on is the first let's see encrypt is

called if the database did not exist

prior to calling opendatabase okay so it

can create the database for you which is

what it's gonna do but those tables are

not gonna exist and we have to have a

way of creating those tables if they

don't exist upon us opening the database

okay and that's what we're gonna do here

so let's go ahead and actually grab the

code for creating the user table so i'm

just going to say const create

user table is equal to and this is now

i'm going to actually use the syntax

that we haven't used before and that's

and then triple quotation marks on the

next line and then a semicolon now what

this does is that it allows you to place

pretty much anything inside this string

without you having to escape that string

because triple quotation marks are very

unique so if you paste any program other

programming languages code in here

chances are that programming languages

code is not going to include three

three quotation marks so the purpose of

this is that now you can go ahead in

your sqlite uh db browser for sqlite and

grab those users um if i go here

database structure user modify table and

you can literally now grab this code

that was created by a db browser for

sqlite and paste it in here you see

so there we go now you have a beautiful

database creation code in here sorry

table creation code that says create

table user blah blah id integer not null

and however we need to take care of

something in here and we just say if not

and we have to put it before user as

well so that's the only thing we're

adding here we're basically saying

create a table call user if it doesn't

you see we don't want to get an error

because if you create a table that

already exists in the database then

skflight is going to throw an error

saying that this table already exists

okay so that's why we need if not exists

and then what we need to do is to tell

our database this database that we

created up here to execute that command

so we're just going to say execute and

you see it says give me a sequel to

execute and i'm going to give you a

future void and we say okay execute

some comment in here we just say create

after we've executed the create user

table we also have to then take care of

uh the creation of our note table

so i'm just going to do the same thing

that we did up here and just say create

equal to as single quotes triple

single quote semicolon let's go to db

browser for sqlite and grab this node

here and say modify table and grab the

code that was generated for you and just

paste it in here do some formatting so

it becomes a little bit more bearable to

read and have a look at and we do the

same thing that we did up there we say

if not exists like that all right

i think i think to be honest with you

we're good to go there i don't think we

need to do anything special in there we

also have to execute that command so i'm

just going to grab the code from there

and like that and i'm going to say

create note table so that's going to

do the creation of the note table as

well done that was it that was a big

i mean by the standards of what we've

done so far that was quite a big

function okay but generally this is not

considered such a big function i

remember now you have actually constants

in here you could you could i mean

if it's me deciding i would bring this

constant somewhere else not inside this

function we could literally go ahead i

mean i hadn't planned for this but let's

go ahead and grab this constant from

here and bring it to the end of this

file okay where we have all the other

and let's go and grab the other constant

and bring it down as well so we put it

at the end of our file right there

as i said i hadn't planned for this but

i just think it makes sense because now

our function is a lot cleaner to have a

look at here we have a comment for

create the user table let's create a

comment as well here we say

and remove those empty spaces and just

now we have the open function

let's go ahead and have a look at how we

can do closing of our database right

closing code so i'm going to fold the

open function in here so we don't see it

anymore and let's go ahead and create as

you can see in the caption we have to

say future void close um okay and it's

what we need to do then is we shouldn't

allow any person to close the database

if the database is not open so let's go

ahead and define an exception for that

and we're going to call the database is

not open okay so i'm going to copy that

exception so i don't have to type it

manually manually because by this point

you know how to create exceptions so

it's nothing extraordinary for you to

database is not open that's a new

so what we're going to do is we're going

we have our database final db is equal

to our local db up there and we say if

and then we throw database not open oops

else we're gonna ask skflight to close

that database for us and the way to do

that is just to say db.close and you can

see it's a future of void so that's why

we're waiting on it all right

and then at that point we have to also

reset this local database which is

called underscore data underscore db so

right so easy peasy close went very fast

now what we need you see as we're now as

we have to open and close now we're

going to start working with data in the

database so that it can for instance

like every function that tries to read

something from the database it has to

have some code in order to make sure

that the database is open otherwise it

has to throw an error so we're gonna

have like five six of these functions

and each of which is gonna check the

database and then do the same thing is

the database open yes if it's not open

throw this error we could put that

particular code inside on our function

that we are going to call getdatabase or

throw okay so let's go ahead in here and

just say this function returns a

prefix it without underscore saying that

this is a private function and then

we're going to say final db is db

we return the db okay so this is a

private function that our reading and

writing internal functions in this class

are going to use in order to get the

current database so that they avoid

doing the same if statement everywhere

all right now we're going to start with

to read and write from the database in

this case we're gonna start with a

function called delete user that allows

us to provide as you can see an email

and using that email address then we're

gonna delete that user from our database

so you you will learn how to manipulate

data from our or inside our database

so let's go ahead and do that function

signature as it's indicated here i'm

just going to say future void delete

and required uh string email

and make this function asynchronous okay

what we're gonna do is just to get our

database with this absolutely beautiful

get database or throw function that we

created here so i'm just going to say

final vb is get database or throw so

this in turn is going to throw an

exception called database it's not open

if the database is not open so we don't

okay so in order to delete something

from sql flight uh or in this case

sqlite that is managed by sqflight we

d b dot delete and as you can see it

returns a future of the number of rows

that were deleted and then it says okay

which table and then a where clause and

a list of objects to pass to your word

clause so we're going to say the delete

and the where arts are in this case are

gonna be email to lowercase okay so i'm

semicolon there and a call in here and

then we're going to wait on it and we're

and delete the account is a weight

so in this case i mean as you can see

here is what we're basically doing is

just we're doing formatting we're going

to say we're going to say delete

something from the user table as long as

that something's email is equal to

something and that something is again

that email so you're basically saying

as many objects as possible in the user

table as long as their email is equal to

this and remember we made email unique

so if if we've done our homework right

then deleted count is it should either

be zero meaning that no personal

account or no user with this email

exists in it into table or it should be

one meaning that yeah i could delete uh

we're actually gonna assert that we're

all right then we're gonna throw an

error could not delete the user so i'm

gonna grab that um exception i'm gonna

so we say if we couldn't delete that

user we're just gonna say throw could

so we couldn't delete that user

now that we have done the delete user

and and remember you may be asking okay

why are we throwing a user maybe that

user doesn't exist and it should just

work fine and of course i mean

it is going to work fine if you have

your try and catch statements when you

what we're saying is that the interface

of the node service is going to throw an

error through an exception if you call

the lead user with a non-existing email

and that's completely fine for a service

to do but where you're consuming the

service then you can manage and say oh

this delete function is going to throw

an exception by like for instance

looking at a documentation looking at

the code then i'm going to handle it

where i'm calling it as at the call site

then what we're going to do as the next

point is to create a user and you can

it's going to be a future of database

user so this is beautiful it's going to

actually create a user given an email

address and then it's going to return

that database user to us so let's go

ahead and do that let's just say

and we're going to say create user

and a required string field of email

and we're going to make it asynchronous

so in here what we're going to do is

just going to get the database we're

going to say final vb is equal to get db

and then we're going to say um

um like that because we're going to

actually issue a query to the database

so as you can see this is a helper to

query table and return items found all

optional clauses are unfiltered or

formatted as sql queries okay

in here what we're going to first do the

first thing we're going to encrypt user

now we're going to actually check if a

user with a given email already exists

okay and that's where why we're doing

query and we're not like inserting

something into the database to begin

with we're asking the data to say hey

we're looking for and we're acquiring

the database for a person or a user

whose email is this and that this thing

is actually going to return and let's

have a look at it it's going to return

a list of rows that were available in

the database okay and that list is going

no entities matched our query okay so

let's just call it final results is

we're querying the user table

we're looking for the email and where

email to lowercase semicolon at the end

making a query to the database and

checking whether a user with the same

email exists we're basically avoiding

for the uniqueness of that email later

so in this case you can see results if i

move my mouse over it and it says that

it is a list of rows and if this list is

it literally means that a user with that

co without email address already exists

results is not empty then we're going to

exception and we don't have that

exception yet so let's go ahead and

find that exception for me at least and

so define this exception use already

and let's go ahead and throw that

exception user already exists okay

statement so at that point we've

basically made sure that that user does

not exist in the database all right

is to go and insert that user now that

we've checked that he or she doesn't

exist in the database so we have to go

and insert that user so the way we do

that is by going and telling our

database we say db insert and you can

see it says in which table and then give

keys and values which is the column name

and the value for that column all right

so let's just say we insert into the

which is a constant we've defined from

before remember and then the map is

for the uh let's go back to our db

browser for sql for note sorry for user

we have id which is primary key not null

and auto increment so we don't have to

insert the id but we need to insert the

email so let's go ahead and say we have

is equal to b it's going to be equal to

so like that and insert if you can have

a look here it returns a feature of pins

and if you read the documentation

uh let's see if if it gives us some

zero could be returned for some specific

conflict algorithm algorithm algorithms

if not inserted so this is going to

so what it's going to do in this case is

actually going to give us a user id back

i wish there was some good documentation

oh here you can see it says insert

so this is very very good this is

actually really cool because remember we

said we return a database user and a

database user actually has an id in it

if this function here did not return the

id how else would we get the id then

we'd have to insert and then read that

same user in order to get the id but we

don't have to do that so in here then we

and we say user id is equal to await on

and then we just return a database user

up so you actually see the code then we

say user id and the email is email the

fantastic now we've taken care of the

function in our database so that's

create user i'm gonna follow so now we

have create user delete user and open

and close and a private function in

order to get the current database

as the caption indicates now we have to

take care of a function called get user

which it can retrieve a user given its

basically write that function signature

in here by pasting it from my note so i

don't have to type it manually but you

have it in the captions in case you need

to go go to it we just like we did in

the other functions we're going to get

the current database or throw an error

if the database isn't open so we're

going to say db is get database or throw

then what we're going to do is we're

going to query the database for that

email address and if you remember in the

create user we already did that so let's

and i'm going to fold create user and

let's go in here and paste that code we

so in this case we have to do the

opposite you see in create user we

results are actually empty because we

want to make sure before we create a new

user with that email that email doesn't

already exist but in this case we

actually have to do the opposite when

you want to get a user we want to make

sure that it does exist so we have to

say if results is empty meaning that we

couldn't find this user with the given

email address then we say a throw

actually we don't have that yet so we

need to define a new exception called

could not find user and i'm gonna bring

just like we have to delete user we also

have could not find user okay and then

here we have to throw that could not

if the results were empty then we throw

it up otherwise we have to then

construct a database a user so we say

from row and we say results

which is the first row that was read

user table also remember we set a limit

rows or one row which is the user with

all right perfect uh let's go ahead to

the next function that we have to

that is for us to be able to create new

nodes so if you want to be like me and

like clean up the code a little bit here

just fold everything so you only see the

function signatures now we can focus on

creates nodes i'm just going to find it

just to make sure i give you the exact

code necessary in order to create the

uh if i can find it um creates notes

as the caption indicates we have to have

a an asynchronous function called create

node it returns a database node and it

also says who is the owner of this node

and it's just going to create a new node

with an empty text and it's going to

associate that and nodes with the given

database user and for you see the

parameter is of type database user and a

way to get a user is either to create

one if it doesn't exist and you get the

database user or you get an existing

excuse me let's go ahead and say future

and we call this function as the nodes

indicate create node and we say it's a

required field of a database user

oops sorry it shouldn't return a

database user it should be database

nodes all right and the parameter is the

owner which is the database user

so just like we did in the other places

we're going to say final db is get

get the current database or throw

so what we need to do first is just to

make sure that the current user that we

are passing here already exists in the

database because remember database user

is just a class it can be created by

calling its constructor which is right

i could just create a new database user

instance as a database user and a random

but in here when we're trying to create

a node for that particular database user

we need to first make sure that that

database user's actually inside the

database okay and to do that we say

and we actually call our own get user

function in here we say get user with

the email of the um owner's email

so in here we're literally reusing the

what we're going to do is we're going to

check whether this database user is

what do i mean by that i mean that let's

say that i go and hack things up and i

say oh i create a new instance of

database user manually without inserting

into the database and here's the id some

sort of a random id and then here's the

email which i know exists in the

now what we need to do in our code is

id that you provided in your database

user here is actually an id of an

existing user in our database and to do

that we could literally use this little

beautiful function that we wrote earlier

which is the equality function of our

database user which actually checks our

database user's id so if we literally

say here in here we say if the db user

is not the owner which goes into our

equal equal operator and negates it it

says oh if it's not equal to that then

if we if we actually found the db user

with that email and the id was exact id

as the owner then we can actually be

sure that that user does exist in the

database with the correct email and the

correct id okay so let's just put

comments here in here and say make sure

owner exists in the database with the

all right after we've done that we also

have to take care of actually creating

the note so let's go ahead and create a

um text and here we say the text is uh

i'm sorry i noticed that you couldn't

i hope that you saw this code at least

that i wrote here but if you didn't i

apologize for that because just because

i'm using a software that i don't see

the software all the time on my main

monitor which is the monitor i'm coding

i have to look at a secondary monitor

which is down here so i'm doing my best

to look at that secondary monitor just

to make sure you're seeing all the

content but sometimes i could miss that

now you can see this code all right i'm

going to bring this code a little bit up

so let's go ahead and actually create

the notes so i'm going to put a comment

in here and say our work now is to

create notes create the notes

and what we're going to say we're going

db insert just like we did an insert

previously for create user we're going

do a db insert for the notes and it's in

and you see the values in here is going

and the map is if you look at the

insert function is literally a map of

let's have a look at our note table in

here and you can see notes right click

modify table it needs user id text and

is synced with cloud columns so let's go

ahead and say user id column user id

and we had what else do we have we have

and that is equal to this text that we

just created out there which is an empty

you don't have to do this you don't have

to do that part you could just literally

to me it's more readable if i define

these things beforehand like that okay

and then here we just say is synced

cloud column and its value is one in

this case so we're basically saying that

and i just noticed that i had missed a

column in there remember insert it

returns the id of the inserted object in

the database and it's a future so let's

then say final note id is equal to a

waiting on that function to insert the

all right now that that is done we're

actually return a new note instance and

return it a database note so what we're

going to do in here we're going to say

note is equal to database note

and for the id we're going to say note

id i'm going to bring it up so you see

and for the user id we're going to say

owner id text is text so this is another

reason to have it defined like a

constant like i did so that we can reuse

and is synced with cloud what should we

do there we should probably just say

creating a note you have to return it

then inside your um asynchronous

function all right i'm going to put a

comma here as well just to make sure

all right now we inserted notes into the

database and we also created a database

node to return that from our function

a lot of code a lot of code but i hope

you're sticking with me throughout this

chapter so now we have create note

as the caption indicates now we have to

work on a function that allows us to

delete a node because remember we're

going to allow the user to select a node

in the database later sorry select the

node on the user interface which that

user themselves have created and be able

to delete that notes all right so we

need a function that allows us to delete

a node using its id all right

let's go i'm just going to bring the

basics of this function or almost the

entirety of this function actually here

so we don't have to code that manually

and as you can see here the signature of

this function i'm going to explain it

all the signature up to this function is

called delete node as an asynchronous

function as the caption at the bottom of

the screen in case we do the get db

and then we're literally just calling

the delete function which is the exact

same thing which i believe we did

in delete user let's have a look at that

you see delete count db delete in the

and then your work clause and in this

case inside the delete note we're saying

from the note table delete an object

which has its column id equal to

something and then we're passing that

now if we couldn't delete anything if

that note didn't exist with the given id

and we're throwing an exception called

could not delete node and that's an

exception that we haven't defined yet

and we're gonna have to define that at

the bottom all the other exceptions that

we've defined so far so that's could not

delete node implements exception all

so i thought to i mean i usually don't

copy paste code even if it's my own code

but i thought this is such an easy code

we have literally done every part of

something similar before we've done the

get db we've done the deletes before

we've done this if statement before so

it's nothing new and i don't think you

me here spending time explaining the

same thing over and over again and

that's why i copy pasted this delete

all right then what we need also is the

ability for us to delete all nodes from

our database how do we do that as you

can see we need a function called future

means which is which indicates a number

of nodes that were deleted from the

all nodes and it's an async function

and uh what we need to do in here is

just it's very simple we're going to say

final db is equal to get or throw

and then we say db delete and then we

uh boom boom await on it all right

this if you issue the delete command on

on your database with a given table all

what it does is that it deletes every

row inside that uh table for you and it

will return the number of rows that were

affected so you can see it returns the

number of rows affected so that's

exactly what we want to return so just

return that value in this function right

we've done some big functions and some

small functions so it's so refreshing to

have some small functions as well

so what we need to do now is to create

the functionality for fetching a

specific node you see when we actually

get to the ui where we render all the

nodes that are inside the database to

our user in the main ui of our

application we're going to list all the

nodes and then if the user presses on

any specific node then we're going to

get the id of that node and then read

that node's information from the

database and that's why we need a

function that takes an id of a node and

actually grabs that node for us from the

so let's go ahead and program that so

function signature and we're not gonna

copy paste it this time let me copy

paste the function actually i mean so

let's go ahead and get the db so this is

easy for you now you know how to do that

and we're going to query the database so

we're just going to say final notes

maps that the sqlite database can read

and we're going to say in the notes

table i'm going to remove all these

overlays so you see the code better

notes table and we're going to just say

um remit one because we want to get one

and the word clause is going to be

um using its id you see we're gonna say

id equal to something and the where arts

are gonna be just the id itself like

that boom and a semicolon like that all

you can see it's a list if notes

is empty we're going to throw an

exception so we're going to say um could

not find notes do we have that

uh could not find user we have could not

find notes we don't have so let's go and

my own notes so we don't have to write

so define an exception called could not

find node implements exception all right

and then here we just throw it could not

find nodes so if you gave us an id we

couldn't find it in database we just

we need to actually create an instance

of our database node so we say return

database note from row and nodes first

okay so that's similar to how we did it

before for getting a user as well

a functionality that allows us to get

all nodes in the system you see we have

get node to delete all nodes delete node

create node but we don't have any

functionality that can get all the nodes

and that is the exact function we're

going to use the main interface of our

application to render all the nodes for

let me just make sure that i have that

we can find a functionality get all

and perhaps i don't actually have a

functionality right now i can see in my

notes that i don't actually have get all

notes but that is actually not a problem

at all in the get note here you see we

have that we have to define this gets

all notes so let's go ahead and do that

i'm going to copy the signature of this

and i'm going to bring it here and we're

going to say we're going to return a

of list of database notes and we're

all notes like this all right excuse me

and it shouldn't require any parameters

we're just going to ask the database to

return all the notes all right

and i'm going to copy the functionality

and in here we're not now going to limit

anything and we don't have anywhere

clause okay so just like that we're

going to say db query from the note

table and we get all the notes then if

notes is empty then we say could not

notes we can see it's a list we can

not have any special logic in here that

says could not find note or anything

and i'm gonna have a look at my notes in

what we need to do now now that we have

our notes we can map them so we say

notes map and you can name this

parameter and and in your mapping you

need to say okay i get a database note

which which you can see is of type let

me see if i can move my mouse over here

it's a map of string object this matches

perfectly into our database notes

but from row and then you say from this

let's actually call it note row or

something like that and we put it there

and now i think this is an eye treble to

be honest with you so you can see it's

an iterable of database notes okay so

what we could do is actually change our

future in here instead of saying list we

in order for the sake of uh cleanliness

i'm also gonna change our captioning

here and say iterable so you see the

correct information on your screen as

so that's our result so all we need to

do in here just to return it that's it

um and that's the functionality of get

all nodes so it's very simple nothing

now uh what we need to do is just to

wrap it up there's one last function

that we have to implement and remember

when we go to the main ui of the

application we're going to allow the

user to create nodes list all their

created nodes and also be able to click

on any specific node in order to update

the contents of that node so we need a

function called update note so let's go

and bring my notes in here update notes

so let's go ahead and create the

signature for that function and future

like that and we're going to have some

required parameters which we actually

grab an existing database note object

expect the user to also provide a new

text so let's just say required

notes and then we say it's the required

you're already familiar with this we're

gonna get the database we say get or

and we're just gonna issue an update to

database we haven't done updates before

for our sql like database so that's what

we're going to do now so let's just say

and you can see it says give us a table

your list of updates so let's go in here

and actually before doing that how do we

make sure that this table that note

already exists in the database because

like we saw earlier anybody can go and

or create an instance of a database node

it doesn't necessarily have to be in the

database but we kind of need to make

sure that it already is stored in the

database because before we can updates

to update its text so we already have a

functionality that does that remember

gets notes with an id so we could

and you see this actually throws an

if you go to this function it throws an

error called could not find note which

is exactly what we're after but we're

not actually after the the result of it

we don't want the actual note because

we're assuming that that is the same

object as this so we're just ignoring

in the update we're going to say the

and the values that we're going to

provide are two we're going to say the

and we're upon you updating the text of

a node we're also going to assume that

well all of a sudden this node is not

synced with the back end or with the

uh with the cloud database anymore okay

so let's go in here and say is synced

with cloud column then it's going to be

set to zero remember that was an integer

asynchronous function so you have the

and it also returns the number of feel a

number of rows that were updated so

updates count is equal to a weight on db

at the call side calling the updates

note function we're assuming that that

in the database okay so in this case the

updates count should it should be a

value other than zero okay so we say if

updates count is equal to zero

bring the code up so you can see it

and then we have to throw a new

exception called could not update

so it should look like this class could

not update node implements exception all

right so i need you to write this code

if updates count is zero then we're

gonna say throw could not update

now you can see what we promised is to

return a new database note so let's go

do we then i mean that's that's the

thing we've updated that uh and how do

we return an update a database note to

you well we could just do this

its uh notes with that note id because

we already have gets notes function

very well done if you could stick with

me throughout this chapter because we

did a lot of work so um i'm gonna fold

this fold this you can see we have a lot

quite a lot of work and i think so far

this has been the biggest chapter of

this uh of this course but we've also

had a lot to do a lot of information i

let's go ahead now and clean up our

exceptions as the caption indicates

let's put all our crowd exceptions in

one file inside lib services crowd crud

underscore quad exceptions okay

uh actually it should say crowd slash

crowd exceptions so um if i look at my

notes inside services crud i'm gonna

fix this caption and i apologize for

that i'm just gonna fix it on on the go

like this and i'm gonna bring it up

and actually it should say crowd slash

crud underscore exception so i think

there was more than one error in there

it should be lip services slash quad

exceptions all right so let's go and fix

inside services we have crowd already

and we have nodes service dart let's

create a new file in there and we just

call it crud exceptions dot art now i

need you to go into your node service

dart file and grab all those exceptions

that you define here and just cut them

with command x on macintosh or control x

in linux and windows and then bring it

into your quad exceptions alright and

and let me also have a look here

just to make sure my notes are clean as

uh so because i i noticed that the next

caption was also a little bit incorrect

now we need to go and use that crowd

exceptions in our note series because as

you can see it is marked as red right

now because there were so many

exceptions thrown that um this file

doesn't have access to anymore so i'm

gonna get help from visual studio code

here with command dot and say import

and all those errors are gonna go away

all right well done huge chapter a lot

of work done and congratulations for

sticking with me through this chapter

now as is the tradition we're gonna now

go ahead and commit our work and um also

tag it so i'm going to make the screen a

let's go to our terminal here

and i'm then going to say in here we're

going to tag and commit our work as step

11 so let's first get status

hit status again here are the things

we've done pop spec was changed because

we added three dependencies uh provide a

and and also i believe actually it was

called path and path provider right

path path provider and sqlite so that's

why these two files have been changed

node service is completely new and crowd

uh step 11 as the caption indicates um

which they commit first remember and

now congratulations again for going

through this chapter with me it was a

huge chapter i think the biggest so far

now we need to get ready for the next

chapter as a tradition for the other

chapters at the end we talk a little bit

about what we're going to do in the next

chapter just to get ready for it

we've done a lot of work on the data now

we need to fuse it together with our uh

with our ui and in order to do that we

need to talk about streams and stream

when you're in the main ui of your

application after you've logged in you

need to see a list of your notes

but what happens if you see the list of

your notes and then you press the plus

button to create a new note and this

plus button is a button that we're going

to create soon in the next chapters what

happens if you press the plus button

should you then send manually a signal

to your ui and say hey a new note was

created update the list that is a lot of

work and for that you can do things a

lot cleaner if you use streams and

stream controllers and that's what we're

going to talk about in the next chapter

you may want to have a short pause after

this chapter since it was so big so do

that please get your refreshments coffee

tea whatever you want and i'll see you

hello everyone and welcome to chapter 28

of the swata course in previous chapters

we've been talking quite a lot about

crud create read update delete and we

talked about how we can for instance

have raw functionality in our node

service so that we can read from the

database delete stuff from the database

create users etc etc now we haven't

really worked in the past two chapters

so much with our user interface and

that's completely okay because sometimes

as you're developing applications or

you're developing software you may have

to take detours in order to create the

functionality that is later gonna be

for your user interface and you'll do

the same thing if you're doing um

back-end development like uh web

development so i myself do web

development with django and sometimes i

have to go and create a lot of

functionality on the backend first

before i can actually go and mirror that

functionality on the ui which is for

instance the web browser where the user

is consuming the content so

if even if you're a designer for

instance you're working with figma you

can't always produce user-facing content

like prototypes you may have to

sometimes go and design for sure

components and then after you've done

your components and you'll be ready to

put those components into screens and

display that to your product owner or

so far we've been working a lot with

what the user doesn't see and we have to

up those last bits and pieces before we

can actually go to the ui and manipulate

that data which our notes service can

right now manipulate we're missing a few

functionalities which we're going to

develop in this chapter in the node

what we're going to work with in this

chapter especially is with streams and

that i'm going to talk about now so what

are streams and what are stream

if you are a developer already you've

done software development you may know

about reactive programming and reactive

programming is where you have

a bunch of data sitting somewhere for

instance and then you perform some

operations on that data and this data

gets updated and you will be notified of

these updates through some sort of a

and if you haven't done software

development before so reactive

programming and streams and stream

overwhelming but we're going to start

very slow so there's nothing to be

worried about i'm going to explain

everything as much as i can to make

but if you don't have development

background from before software

engineering background there's not so

much that i can explain about streams

and stream controllers for you to

completely understand how they work all

i can say is that imagine a stream is

just a point of time or a stream is

basically an entity that controls data

all right just say something that keeps

hold of data and then you perform things

on it so you say add this data or remove

this data add this data with this data

it keeps hold of its data and it has a

timeline so it starts at some point

manipulates its data and then it either

errors out at the end saying that oops i

can't do this and then it just dies or

it will just complete at some point and

also there is a third category of

where the data just keeps living on so

so just think of streams as pipes of

data types of information that you can

manipulate and you can also perform

so if that's what streams are then what

are streams stream controllers in dart a

stream controller is your interface

you have the stream which is sitting

you you don't basically usually go and

add stuff to a stream directly or read

stuff from the stream what you can do is

to have a stream controller where you're

manipulating the stream for instance our

node service and this stream controller

is able to for instance add stuff to the

stream or read stuff from the stream so

just imagine the stream controller is

kind of like the manager of that stream

so if all of this sounds a little bit um

high level and abstract i completely

understand that it usually is when

you're working with reactive programming

some people actually hate reactive

as one of my colleagues used to say it's

hate than to learn and my approach is

usually if i hate something is because

maybe i haven't really fully understood

it so there are very few things in my

life that i've actually learned which i

if you're a bit overwhelmed by streams

and stream controllers or reactive

programming don't be they're actually

really good if you know how to use them

so they're very easy to use as long as

how basically it's getting a handle of

the right way of using them so that's

what i'm going to show you in this

so let's go excuse me let's go to our

application i'm going to put the code

right here let's have a look at what

we've written so far i'm going to

increase the size of the screen and then

decrease the font size a little bit so

let's have a look at what we've done so

far you can see we have quite a lot of

we have for instance delete all nodes

we have update nodes so quite a lot of

but if you see all of these are directly

talking with our database with our

sqlite database none of these

we don't even have to talk about

functions but if you look at the node

service in it itself it doesn't contain

a list of nodes so it doesn't have the

ability to cache these nodes so it's as

soon as you give it a command the node

services i don't know what to do i'm

just going to go to the database and do

however this could i mean in not in our

application but in an application that

has millions and millions of rows of

data for instance this could not be such

a good idea that you always go to the

read the entire thing in order to for

instance delete one row or um basically

these operations should kind of be like

cached inside your application before

you go and hit the database hopefully

and what we're going to do as you can

see in the caption here we're going to

actually start caching a list of notes

that the node service has so the goal is

for the note servers to be able to

expose a list of notes that the ui can

then render on this on the user screen

so if the user goes and presses the plus

button then that plus button is then

gonna send a message here to our note

servers we're going to then go to this

function create node and this create

node function internally is then going

to manipulate that list of nodes inside

node service say hey here's a new node

and then our ui is going to listen to a

list of these notes available in note

service and if things change in that

then the ui is just going to

automatically update itself and this

interface between the ui and the node

servers is going to be done through a

i know it's a lot of a lot of

information but you'll get it you'll get

it as long as we go through this chapter

so what we need to do first is let's go

and as then as the caption at the bottom

of the screen indicates we're going to

go and expose a list of notes in our

note service okay so let's just let's go

and we're just gonna call it notes and

we're gonna start with an empty list all

so that's really good now we have let's

say this is our cache this is where

we're keeping all the notes that this

node service manipulates all right

so now let's go and talk a little bit

you see what we need to do as the as the

what we need is for the node service to

be able to control a stream of nodes so

when the list of this nodes changes we

tell our stream in the note servers that

hey some element got added hey some

element got deleted or some element got

then the ui can then reactively listen

for these changes in the in the nodes

service and we do that through the um

so let's go as the caption indicates i'm

going to write it and notes actually

maybe i should yeah i'm going to write

it notes stream controller and the way

to create a stream controller is that

you just say stream controller and then

you specify the type of data that your

stream contains which is a list of

like that and i believe stream

excuse me um isn't imported in our notes

service so i'm gonna get help from

visual studio code and you can see it's

it says that well stream controller is

available in the dart async package so

um and yeah async meaning asynchronous

so in order to be able to use stream

controller you have to import that so

i'm going to get help from visual studio

all right so let's see what we did in

what is this the syntax looks really

really scary but it really isn't all

you're saying is that i want to be able

of a list of database notes basically

you're saying that i have a pipe this

every event that is inside this pipe is

a list of database nodes so let's say

you start with an empty list so this

list is empty inside this pipe then you

then what it does it says oh what was i

before i was on empty list add that new

item so now i'm an item now i'm an array

or a list with one item and then it puts

that array inside the stream so the

stream's value is now at the beginning

was empty list then it's a list of one

item so this stream controller is

basically in in control of as its name

indicates it's in control of the changes

list it isn't hooked to that yet but

that's its purpose and that's the reason

it has the exact same data type in its

now the broadcast part in here and as

you can see the documentation actually

spot on it says the controller where

stream can be listened to more than once

if you've done dark development or

flutter development from before you may

know that if you then um and i'm now

assuming as i said that your dart or

flutter developer from before if you

have created a stream controller and

then you go and listen to the changes to

that stream that the stream controller

is controlling and then you do a hot

reload then you get an error from your

flower application saying that oh this

stream's already been listened to so you

cannot listen to it again and that's the

problem that normal stream controllers

can cause and that you as soon as you've

listened to them you should close your

listening channel to that stream before

you can listen to them again so that's

what broadcast fixes if you're not a

developer from before what this

broadcast basically is saying is that

it's okay for you to create new

listeners that listen to the changes to

this stream controller so here's a pipe

of information at this point you start

and listen and then it's completely okay

that if you want to listen to changes to

the stream controller later in the

future as well so you're not going to

get any errors by doing this broadcast

that can read all the available notes

from our database and then cache them

inside both the notes cache right here

so you see what our our goal in this

make sure that this is the source of

list contains all the nodes for

for instance the current user

is our interface to the outside world

the ui is going to be listening to

changes that occur in this stream

so whenever you see this this is not

something that's going to be read from

everything's going to be read from the

outside through this all right so keep

that in mind so let's go ahead as a

caption in the case and we're going to

create a function in here called cache

notes and its purpose is just to read

all the notes from the database and

place it both in here internally and in

our node stream controller which is

going to be read externally all right

so let's go and do that so i'm going to

say future void and we're going to call

then if you remember we already have an

async function called get all notes so

i'm just going to say um final uh all

it's all notes okay so that's gonna get

and we're gonna assign that to our uh

as you remember get all notes returns on

iterable of all our notes and now we

have a little bit of a problem here

because we're saying list of all notes

and in here we're also saying list of

notes so we have to convert that

terrible to a list of all notes okay

either we could do that or we could have

this just sit there as an eye treble

it's completely up to you i have no

issue with any and we could just go with

so let's go in here and then we're gonna

is the private notes is all notes to

and we also are going to update our

stream controller with that with the

value of underscore nodes okay so we're

going to say notes stream controller

and then we're going to add

notes to the stream and remember a

the evolution of a value through time

the first point of this evolution was an

empty list and then the next one is

notes that are all the notes are in the

that we telling anyone listening to the

stream controller that hey here's a new

now that we're doing this you can see

we're getting an error and dart is very

actually this analyzes so clever because

you see it's telling us that the cache

notes function is not being used now

you may be asking yourself well none of

these functions are being used update

note for instance is not being used so

nodes could not update nodes so yeah you

can see that update node function in

itself is not being used at all so

analyzer is complaining about this

function particularly and the reason is

because we have a little prefix

the analyzer that this function is

private and private to this class now

dart analyzer is looking at it and it's

like okay it's a private class but

the reason that other functions aren't

marked with this warning is that dart

understands that they are not prefixed

with a with an underscore meaning that

they're going to be used publicly

somewhere else so it's not going to yet

give us any warning saying that you

haven't used those functions as soon as

you remove that you see that the warning

also goes away but we're going to keep

down the score okay i just want to

explain to you why you're seeing this a

okay now that we've done cash notes what

we're going to do is just to go to our

as a caption case we're going to go to

and upon opening our database so uh let

upon opening our database we are going

let's let me just have a look at my

notes yeah we're gonna basically go to

the open function that we have here

i'm a bit surprised that i actually

written any notes about that yeah i can

see actually i have so that's good okay

right after executing this command for

creating the notes table after we've

created the user table and note table

and now that we know that we could open

the database we also have to cache all

local variable so let's just go and call

that function so we're just going to say

so this means that when you call this

if after we made sure all the tables

if they didn't exist then we're gonna

read all the notes and place them inside

this notes variable and also in this

stream controller okay so that's how we

did the cache notes and i hope that you

and it wasn't hidden by the caption at

all right so that part is done now um

now what we need to do in here is to go

to the next part of the code and as you

can see it says cache note in create

node in create node function add the new

node to underscore nodes and the node

i'm going to go to my nodes here creates

and ensure that when we create the nodes

right here in this function in the

create node you see at the moment what

we're doing is that we're just creating

that's good but i mean it's not good

enough because as i said we need the ui

to be able to reactively listen to all

the notes that are right now in the

database for that current user okay

so in here after we create the note

we're actually going to add it to our

array of nodes and then we're also going

our stream controller so i'm just going

and add this new node in there and also

remember the stream controller's

responsibilities just reflect the values

inside the underscore nodes to the

outside world so all we have to do is

just to say notes stream controller add

notes just like that because notes is

the source of truth as i mentioned

now we need to take care of the other

function called delete note let's

what we need to do is to have a look at

this uh functionality here and you can

see it says if we couldn't delete

exception but now we're gonna add an

by us being able to delete that note

meaning that you can see the note id we

have which is this id so what we need to

do as a caption in the case we need to

actually remove that note also from our

local cache so we're going to say notes

and this is the note and then i'm going

after doing that we could just say note

notes and you could be try you could try

to be clever in here and you for

who says that that note actually exists

in our cache we can't 100 be sure about

that but if you look at the signature of

um removes all objects oh maybe we don't

have the ability to actually know

if that node was deleted but what you

could do you could just say count before

is notes count and then you could in

and here you could just say if notes

is not count before then you can update

your stream i don't plan to do that but

you can you can try to do that if you

want to it's just a safeguard for you to

say i'm gonna update my out outside

facing stream only if i actually could

delete this note from my cache

if you think it's worth it i don't think

so we're going to leave it like this as

now you see we also have a functionality

all right so let's go in our delete

all nodes in here find that function and

you can see right now what it what it's

doing is just returning the number of

now what we're going to do we're going

what should we call it number of

is equal to this and we're gonna return

that number of deletions okay because i

mean i'm doing that simply because we

do some work in in the middle here okay

so then what we're gonna do is gonna say

is an empty list all right so we're

resetting the notes and then after doing

that we're also going to update our

stream controller so we're going to say

add the underscore nodes to stream

control and then return the number of

deletions so let's make sure that our

local cache is updated and also that the

interface of our class which is the

updated with the latest information

okay next thing that we need to do as

you can see in the cache that says

update caching get node remove old node

with same id and add the new one on and

let's have a look at our get note in

and at the moment as you can see in here

oops that's not get note um here is get

and as you can see here uh we're

basically what we're doing is that we're

upon you trying to read a note from the

database we're literally just making a

query to the database and then if we

could find that item we are returning it

by creating a database node from

from a row that you can see right here

uh but what we're gonna do is that if

you try to get a note in there is a

possibility that we already had that

note cached locally in our notes array

uh outdated meaning that the copy that

we had in our cache is not really

updated with the latest changes that

have been applied to the database so it

makes good sense right here to now upon

creating a new instance of database node

actually to update our local cache as

well okay so i'm just going to say final

note is equal to that and we're going to

bill right here so this code is the

exact same as it was before except we're

now assigning the return value of from

row to a new local variable here okay

so let's go to our notes and say remove

and i'm going to say in here note and

i'm going to say i'm going to say note

this thing here okay so we first remove

that node existing node from the notes

and we add the new nodes in there and

then what we're going to do is right

after that update the stream controller

which is our outside facing um interface

so note stream controller add notes okay

so you can see this pattern so we first

always update our local cache and then

we reflect those changes to the outside

all right great stuff so um

that's for note stream controller and

now there's another function which is

let's go to update node actually before

we have a look at anything else and you

can see in here when we update that

first we make sure that that node exists

so let's put actually a comment in here

update db i'm going to expand this code

so you see better that's the update db

and if we couldn't update anything then

we throw it could not update note and

upon doing an update node what we want

to do is i mean it is quite clever what

we've done so far because it means that

we've updated the database but what we

do then in order to return the new

refresh node is that actually we call

that is that's pretty good so

but what we also need to do is just to

make sure our local and cache is also

let's go in here and say final

and what we're going to do as the

caption at the bottom of the screen

indicates we're going to remove that

notes from our local cache and add the

updated note in there and then

send the add message to our stream

controller as well so let's just say

so we're going to remove the old object

from our cache and i'm just going to say

as long as the notes id is equal to the

updated notes id so that's going to

remove the existing existing node

and i'm going to say notes add and we

notes and local cache then you need to

also update your stream so the stream

and then we return the updated notes in

here so what happening here is just that

we updated something in the database we

got the new object from uh the database

we removed that uh node from a local

cache and then we added it in there okay

added it back that's the updated node

all right great stuff that's for update

notes and then what we need is as the

captioning case is get or create user in

this is a function that we're going to

actually use in the next chapter

how is this function useful this is the

first time we're actually seeing the the

signature for this function as the name

in the case it says get or create user

when you at the moment go into our user

interface let's go to the login view for

i'm gonna remove the explorer so you see

the code in its entirety and right here

when we do auth service firebase login

then we get the current user if the

email is verified is that we're going to

nodes routes now let's then go to our

notes view you can see right now notes

view the only thing it's doing is that

it's creating an app bar with a um sorry

it's creating a scaffold with an app bar

that we have our logout button in

and let's go actually let me bring up

scr cpy so i'm gonna use my email

address in the login screen so um

i actually may need to go and

connect this device to wi-fi so boom

that login with my user so i'm to get

i'm going to login in here use oops uh

we've sent you an email verification

maybe i should actually log in with the

user who has already been verified

so let's log in with this user you see

in the main ui of the application um of

our application we have this hello world

um you can see the body of the

the body of our notes view right now it

just says hello world so you could

pretty much say that the notes view has

literally no contact at the moment with

but we're gonna fix this soon by first

making sure that the note service allows

create a new user upon going to the

screen so when we come to the screen we

need to make sure that there is a user

associated with the current firebase

so that's what we need this little uh

good function called get or create user

which returns a database user in our

notes service so we're gonna use that in

the next chapter so remember that okay

but we need to create the function at

all right let's go then and create this

function as the name indicates so future

and database user and we're going to say

get or create user and it has a required

parameter i can see required stream

and it's an async function right

we need to basically have a look at this

the goal in here is to first we try to

get this user from the database if that

user doesn't exist then we're going to

create that user and then in both cases

we're going to return either the

fetched or the created user back to

so let's go in here and just say

get user okay and you see the email just

fits in there perfectly but if you

remember from the implementation of get

user let's go in there and expand this

the user couldn't be found then it

throws an error says could not find user

that's rq so that if that function

throws that error then we're going to

create that user so if that user doesn't

exist in the database it needs to be

created so let's put a try statement in

here and then we're going to say on

the user so in this case in the try

statement it means that we could get the

user okay so if we get to this return

statement it means that get user

function didn't throw any exceptions

such as could not find user in the case

that we could not find user we're going

to actually create a user so let's just

with that email and then we're gonna say

return created user and if you look at

the create user function as well right

here it also i believe does it throw yes

so if it couldn't create that user it if

it's the result was empty it just says

user oh no that's that's where we get

we need to have a look at this insert so

yeah that's the only thing it's doing so

it's not basically throwing any other

the only thing it does is if you're

creating a user that already exists i'm

we have where and we've ended up with a

that could also throw an exception which

we haven't handled all right so what you

could do is just to do a whole catch in

here and then don't do anything with it

i like this pattern quite a lot in my

code at least because if i don't do this

then i don't actually have the

possibility to debug my application

later so i can't put like a breakpoint

in here and see did any other exception

arise if you don't do that because then

the exception will be thrown to

the caller and the caller will have to

handle that but in this case we're not

really handling the exception we're just

catching it and then we're throwing it

back to the call side this only allows

you basically to put a breakpoint in

here if you want to debug your

application later okay so it's just a

it's just in quite a cheap way of making

your code easier to debug all right for

those of you who are interested in this

all right fantastic and we've covered a

but we've come far so congratulations um

let's have a look here it says let's get

ready for the next chapter and upon

logging in we need to call our get or

create user function and have the user

and this is what i mentioned to you

before inside our notes view at the

we don't have any functionality that

a new user or gets the current user

based on their email if they already

that is going to be like the actual uh

first bit of logic which we're gonna do

in the next chapter which integrates our

notes view with the note server so the

of our course right now is gonna shift

towards more and more to the notes view

until we have a list of notes and allow

the user to create notes update notes so

it's exciting times we've come far we've

done quite a lot of work up up to this

point um and there's still a lot left

hopefully you're getting the attack at

of the course better and better and you

why we are doing things the way we are

get some refreshments if you want to

again coffee tea and i'll see you in the

hello everyone and welcome to chapter 29

of this flutter course in the previous

chapter as you saw we worked with our

note servers and we talked about streams

we have put uh you know a lot of effort

in our note service in order to talk

with the database and kind of read from

in our notes uh member variable so if

you haven't watched the previous chapter

i highly suggest that you do that

moving forward with this course without

chronologically makes it quite difficult

i'm gonna build on top of the previous

chapter as we've done with the other

chapters as well and in this chapter

we're gonna basically start putting in

place uh all the structure necessary in

us to be able to display all the user

so as you can see we have almost

everything in place um there are a few

functions left to do and we also in this

video in this chapter we're going to

talk about future builder and also a

and i don't think we've talked about

stream builder before we talked about

future builder so that's going to be an

new thing to talk about in this chapter

i've just i've talked about this in the

in the outro to the previous chapter

that what we need to do in this

chapter right now in chapter 29 is to

allow the user to to go to the notes

view and upon going to the note c we're

all always going to make sure that that

user exists in our database now you see

we have firebase right here and then our

user has upon coming to the notes view

that user must have logged in with a

verified email address so that user

exists we know that that user exists in

firebase and has a verified email

address but that user might not exist in

our database remember we're gonna store

the user generated notes in our database

and hook them to the user who created

um so upon going to the notes view we

always need to make sure that that user

and the way to do that if you remember

let me just bring the code you don't

have to try to remember that so let's go

into our notes service you can see

we have a function called get all notes

and but we don't have any functionality

at the moment to for instance give us

the notes for a a specific user so

if we want to do that if you want to for

instance get grab all the notes for a

specific user then we're going to go

with a user's email address because if

you look at the way our application is

the current user you can see we're

working always with officer so we're not

going through um firebase directly and

our auth service also has an off user so

let's have a look at our auth and have a

look at auth user and you'll see that

our auth user only has one flag that

so how do we go and call this function

which is called get or create user on

our note service where we don't actually

have an email address for our current

and that's what we need to do we need to

go ahead and add an email field to our

and so as the caption indicates here we

need to add this field to our off user

okay so i'm going to change the screen

layout a little bit so you see better

and let's go ahead and add a new field

in there i'm going to have a look at my

so and add a new field in here and we

just like that and get help from your

editor in order to add the email field

add final field here so this is also

going to be a required parameter like

this and i'm just going to make it

required like this and it come at the

end to get the formatting done

and here where we actually creating our

instance of auth user what we're going

to do is to say we return an auth user

and the email is already actually in the

firebase user let's go to the firebase

user and look for email you see there is

and the thing is that this email getter

is optional string so what we need to do

is just to make it optional maybe in our

off user as well okay so in here then

where we create the off user we're just

going to say the email field is equal to

user email and put a comma at the end

here and a comma here as well to get the

so all we did in here would say that our

r auth user has an optional string as

its email and that email string is read

from the firebase user that's all

okay what we need to do then is to as

the caption indicates go to our notes

view and grab the let's go notes view

here and we need to then read the

current user's email address okay so

what we're gonna do is saying that our

auth user has an optional email but we

we as an application developer are sure

that because we're using email and

password registration we are sure that

any user who ends up in the notes view

that's an assumption we're going to make

user which was let's see if we can find

off user here although the off user says

that i optionally have an email but

we're always going to say no that email

should exist because we're only at the

moment using email password sign in

in order for this notes view to be able

to make a call to the notes service and

or sorry to create or get the current

user it needs an email so let's go ahead

and expose a functionality in our notes

as the caption indicates that grabs the

user's email so let's go in here and i'm

going to go to my notes view as well in

and what we're going to do in there is

just to expose the user email so let's

and i'm going to say off service

all right off service i don't think it's

imported so let's actually see is it

off service yeah it is imported okay

and this can't be equal so that's why

it's going a little bit crazy firebase

and then we're going to say current user

and you see this current user is now

optional but since we are the

application developer and we're sure

that if you end up in the notes view

then you should have a current user

that's what we've already made sure in

the previous steps okay so if you look

login screen for instance in our login

view so i open the login view here we're

saying if the current user exists and is

email verified is true then go to the

then we can be sure that inside the

notes view we already have a user okay

this current user in firebase currently

says optional but we're gonna unwrap it

force on rapid okay and then we're gonna

say email and force unwrap that too

that's what we've done so now we get the

now if you remember inside our um

inside our note service we have two

really important functions which at the

moment are at the bottom of this

class which are called open and close

and what we need to make sure is that

upon going to notes view that

our database is actually open so we

cannot continue to read stuff from

various parts of our database if the

database handle hasn't actually be

let's then go to our uh notes view

in here as you can see this is the

reason we made this and notes view a

stateful widget in that we need to now

hook into the two life cycle events of

our notes you and to open our database

upon the creation of this node 2 and

then close the database upon it being

as the caption indicates let's go and

overwrite the init state function in

here okay and what we're going to do in

basically have a notes service in our

init state and we also need to make sure

so let's have a look uh let me have a

we need to open the database in there so

grab a hold of our notes service so we

don't have a note service right now but

we're going to create that so let's just

so this is our uh notes view uh

undefined class notes service

haven't we imported note service and we

haven't so let's just do it on import

right now so this is our notes view

grabbing hold of an instance of node

server so that it can work with it okay

let's go ahead and do that then so we're

service is equal to an instance of nodes

service like this and then we're going

and right now this function is a future

you may not really be able to do an

async in your init stating here but

we're just for now we're just saying

open all right so open the database

and that's all we have to do and then we

have to take care of closing the

database so let's go ahead and say

upon this uh notes views disposal we're

also going to close the database because

we're good citizens of the dart lab so

we're not just going to leave the

database open so node service and we're

going to say close all right and

that's that's pretty much it that's all

okay great stuff let's save this and um

i'm also going to maybe bring a crcpy

and what i'm gonna do then is to do a

and then i'm gonna log in with that user

if i can spell pick solitude

foo barb has horrible password i've

barbaz it could be because this uh phone

doesn't have wi-fi right now so let's go

in here turn wi-fi on and then i'm gonna

android phones usually initial

initialize their wi-fi site quite fast

so now we should be able to say login

and we end up in the main ui of the

application so this open function has

and i can see that we haven't had any

exceptions thrown in the debug console

so let's have a look in here um

as you can see in the caption uh right

now we are what we're doing is that

we're like issuing different functional

functions in our for instance let's have

a look at delete user what it does is

that it says get database or throw um

and at the moment this get database or

throw only thing it does is just make

sure that this db is available in there

but it doesn't make sure that that

database is open as such it just makes

sure that there is a database

instance in the the internet in the node

so what we need to make sure now is that

every function that works with our

database first ensures that the database

not only is instance is there but that

all right because if you look at the

excuse me um here we have the open

sets the instance to that database all

so what we need to do is to create a

little function that says ensure

database and what is it called ensure db

i'm just going to go ahead and have a

look at my notes for ensure dbs

open and um let's have a look at

putting that maybe above open in here

if you're following along with me you

just go to top of the open function and

we're just gonna say future void

and that's an async function all right

what then we're going to do is just to

we're going to put a try block in here

and let's go we see that our open

throws an exception that says database

already open exception so what we need

to make sure is that we cache that

our uh notes view gets hot reloaded then

it shouldn't try to open the database

over and over again and if it does then

this open function is going to throw an

and our ensure dbs open function is

going to catch that and it's just going

to let it go all right so all it does is

we just ensure that we're not opening

the database over and over again because

so what we're going to do then is we're

going to say awaits open in here

and in here we say we're catching

already open exception and we're just

going to let it go in this case so

sorry on all right so now we have this

intro db function is open uh it's your

and we need to start using that um

so let me bring up the right caption so

we need to start using ensure dbs open

function in various functionalities in

our application so let's first go to

and uh we're just going to say await

ensure db is open that's the first place

we have a function called create user

and we're gonna wait on ensure db is

that was create user now let's go to

this function get user right here

if i can go to it for some reason i'm

not able to go to it here and let's say

uh that that that's that part let's go

function get all notes and do the same

oh also i can see i didn't actually call

the function so let's make sure that

i've done it in the other places i'm

just going to copy that code and ensure

bb is open let's just make sure that i'm

actually calling the function and like

i'm not like placing it just there

and so you have to do it in get all

and we're going to go to create node and

do the same thing so let's just go and

actually paste that code in there wait

and we're we need to do it in um

so we not we've done it in create node

and let's go ahead to delete node delete

and paste the function right there as

as well delete all nodes right there

do the same thing and also we do it in

and also we have what else do we have um

and we do it as the first call

but and then uh where else do we have to

let's see we've done it now delete user

yeah i think now we place the ensure dbs

open all those calls all right

okay that was a lot of information um so

make sure basically that we work on our

notes view as we promised in the

the reason that we created the ensure db

is open is that before any of these

functions are called that our code is

actually going to open the database for

us that means in our notes view we don't

actually have to do this anymore because

we know that by issuing any database

related commands to our nodes service

that that function in itself is going to

open the database for us it's just a

nice little feature in our node servers

to make sure that we don't have to make

an extra call to open the database

start using our node service okay so

it's just like a convenient a little

all right as the captioning case now i'm

going to talk about future builder and

async snapshot well um we've talked

actually previously a little bit about

but uh what a future builder is maybe

actually you should write it here future

builder and then go to the code so you

see it a little bit better you can see

it is a stateful widget so and what it

does is that it subscribes to a future

that will return its value in the future

if you're familiar with javascript then

and uh if you're familiar with rx swift

or any rx related then you'll know

probably as like a single or an

observable kind of actually not an

observable because that's a stream

builder a future builder is kind of like

a single builder meaning that a value

that starts someplace and then

calculates something returns its value

and then it finishes that's it

so a future builder allows you to submit

and it will allow you to submit a

it takes that chunk of code that

produces a value as a future it says

okay now it's mine i will take it

subscribe to it as the value of this

future changes i will give you the

ability to return various widgets that

need to be displayed on the screen so it

your future logic with your ui logic so

so what we need to do now is to make

sure that upon going to our build

function right there in the body you see

in the body of our notes view here

creating a user or getting the current

user from the database if it already

exists and we're creating that user if

if you remember we have this function

already it is called gets or creates

something something a get or a create

user and it's a future so we're going to

create a future builder in our uh notes

view that subscribes itself to the value

that is returned by this and then it

will tell us about various updates and

these various updates are going to be

provided to us as something called an

async snapshot an async snapshot is

basically as its name indicates is a

wrapper as a snapshot around an

asynchronous functionality which is in

so that's what we're going to do in our

caption we're going to now return a

and actually that should say notes view

view so i'm going to fix the caption as

i don't confuse anybody including myself

so now it's better i apologize for that

right now we have this hello world but

we're gonna change that so it returns a

notes view so i'm gonna say sorry a

future builder so let's say we now

and now it says okay there are two

parameters that we have to provide one

is the future the other one is actually

the builder function so the builder

sorry the future in itself is going to

get or create the user and the email if

you remember is the current user's email

address which we created a getter for

called user email so let's go put that

in there user email and then you can see

it's still complaining saying that the

so let's go and say then that we have a

and right there and i talked about async

snapshot because that's the parameter

that you get in here is this is async

snap snapshot of object right now

but we're gonna fix that so um

let's then talk about actually

this functionality right here

after we get the current user or creates

a new user if that user hasn't existed

in our database we also need to grab all

have like a stream of all the nodes for

the current user we're going to add that

soon but as you can see in the caching

is we can achieve this with our stream

controller which we've already placed

like the groundwork for in our node

so let's go and create a little

functionality in here in our notes

allows you to retrieve all the notes so

we're just going to say stream

and we it's a getter and we call it all

notes okay and what it does is is in

itself is gonna subscribe to this note

stream controller and retrieve all the

notes from that controller because

remember this note stream controller in

in itself contains this guy all right

so and that's what we're going to do

we're going to say it returns the node

actually another stream get all not so

so that's our getter for getting all the

notes um now what we need to do now that

we've created our uh so back into back

in note2.dart now that we have

what we need to make sure of is that if

the user could be created then we are

going to work with something called a

stream builder that retrieves all the

nodes from the node service and then

renders them on the screen okay

but we can't yet render them we don't

have any user generated content and we

also don't know yet how to render them

so first let's take care of something in

here this snapshot in here what we need

connection state is connection

if that's the case then we're gonna do

some logic in here so let's just say

return a text of hello for now okay

actually we need to maybe switch this so

snapshot dots connection state and i

really like to get uh visual studio code

to complete the rest for me so i don't

like to write all the cases so i'm just

gonna say command dot or on mac or

control dot on linux and windows i say

add missing case clauses and in the case

of done i'm just going to say return

if the creation or the retrieval of the

current user was completed then just

and in any other case for instance in

a circular progress indicator just like

okay then i'm gonna put the case of done

let's then do a hot restart and i can

see my um scrcpy kind of just crashed so

yeah stuff like that happens sometimes

and that's okay let me go ahead and go

back to this shell and say hcr cpy

the application is working fine it's

just that scr cpy crest so i'm just

gonna say your notes will appear here

actually my debug process has crashed as

i'm going to run the application now

gradle task goes fast because we've

already compiled the application from

so what we need to do you see we are now

taking care of making sure that the user

is created in the database if it didn't

exist or we're getting the user if that

user exists in the database but what we

also need to do is to start listening to

changes to this stream which is in our

note service called all nodes and

depending on the state of that stream

then we're going to build our user

interface all right so in this in here

we're actually not going to return like

a text of hey your notes will appear

here but we're actually going to use a

stream builder which is very similar to

a future builder but it actually listens

oops did i just kill the application

so there we go your notes will appear

that seems to be working fine so let's

go in here and then say that we want to

our stream builder i'm going to put this

back and before we do that i want to

explain this little thing that i've

what are the waiting and dawn flags in

both a stream builder and a future

builder work with something called an

async snapshot which is this guy you see

async snapshot and this async snapshot

can have various connection states so if

you go to connection state in there and

you can see we have none waiting active

when you when you have you see in the

case of an active says for example a

stream that has returned at least one

so that's for a that's for a stream

uh but if you're waiting for a future or

a stream then you're gonna get this

waiting flag and it done is gonna happen

for your um a future so a future that

has completed its task as i said it does

something and it completes but a stream

usually it just keeps living so you

can't like hook into or you shouldn't

hook into the done event for a stream

but you should actually hook into your

connection state so that's what we're

going to do so connections stay done for

a future and a connection state of um

waiting for the stream so in here let's

is going to be our note services all

so that's the stream itself and then we

need a builder and let's get visual

studio to complete that for us um

okay and in the builder what we're gonna

like this get visual studio code to

i'm going to remove the break from here

and in any other case so in the case of

default we're just going to say

on circular progress indicator just like

so now you see if i command s to hot

reload then it just says waiting for all

nodes to appear on the screen so

this is now like the skeleton of our

application's notes view so that it

takes care of two things it gets the

current user using his or her email

address if that user already exists in

the database or creates it so that's the

the widget returned by the future

builder in itself is a stream builder

so the stream builder then calculates

all the nodes and returns them from the

node service and then it has a

connection state and waiting which in

turn right now is saying waiting for all

nodes and we're going to change this

it doesn't just return a text it

actually returns a list of notes all

now let's talk about something else

before we wrap up this chapter and you

see at the moment what we're doing is

that we're saying our note service um is

a new service right here so every time

go into init states if i command s in

here or if you did a hot reload or hot

restarting here actually hot restart

i can see maybe that is the reason we're

crashing the entire application because

we're creating a new node service so

that could be the reason i can see hot

restart is a little bit flaky right now

so um so that is pretty much the reason

we're going to create a single now if

you're not familiar with what a

singleton is a singleton essentially is

a pattern used in software development

service for instance or a class instance

where that class instance is only one

inside the entire application right now

any place in our app we can go and

create a new instance of node service

but if you think about it the node

service should only exist as one copy in

the entire application it shouldn't be

like made new copies of this note

service over and over again so that's

what a singleton is and that's what

we're going to do with our note service

so i see i have a little bit of problem

captions and i'm going to bring the next

so let's go ahead first and uh

before i run the application maybe we

should fix this problem with our

singleton so let's go to our note

and we're going to create a single now

singleton pattern in various languages

i mean it differs from language language

and dart is not as clean to be honest

with you in my opinion as it should be

such as it is in languages such as swift

um but it is what it is and we need to

kind of live with it the way uh it works

so the way that we do it uh that we make

class note service a singleton is to go

constructor for our class so we're going

and this is just a function name it's

just a private initializer to this class

and what we're going to do then is we're

service so we're creating a shared

instance and we're going to say notes

got shared instance so this creates that

shared instance for us but no one from

the outside world is going to be able to

then make a call to these two because

they are well private so now we're going

to create a factory constructor we're

like that and that is going to return a

shared instance for us so it's just a

hack to be honest with you in my opinion

at least it's it's a hacky way of

creating a singleton but that's the way

it works in dart at least for now

all right now we've created our

singleton so what we can do then is i

mean we don't have to make any changes

to this guy to the init state because

it's constructing node service and we

have changed that so that anyone who

calls node service like this is actually

coming to the factory constructor which

then in turns returns this shared

instance which in turn calls this

private factory and it causes private

initializer or constructor so it's like

deep in order to create a singleton

i mean we could also try to run the

application while all this is going on

and i can bring up scr cpy again and if

it's doing any better bring it up here

we've done quite a lot of work we've

laid the groundwork for the next chapter

so now we have the ability to hook into

all the notes available in our database

which is being controlled by a stream

and a stream controller and we're then

being able then we're able to display

those notes on the screen use using this

stream builder which i'm trying to find

right now which is right here okay so

we've done quite a lot of work and well

done to you for sticking with me

as is the tradition we are doing in

every other chapter by the end of

chapter we commit our work and also tag

them so let's go ahead and do that i'm

screen layout a little bit get rid of

the cr cpy it has been a little bit

angry with us today this scr cpy

and here's the screen layout and i'm

going to increase the font size of it

and a new shell all right so in the

previous chapter we uh committed and

step 11 i believe so if you say git tag

you can see we have up to step 11. let's

go ahead and say git status first

yep some files that have been modified

add all the files and then we say

step 12 this time and we push our

and then we're going to tag our work as

again uh what we do in the end of every

chapter is we talked a little bit about

what we're gonna talk about in the next

and as the caption indicates we're gonna

we're done with the basics of the notes

but we have no data and that's what

we're gonna fix a remedy in the next

chapter so we're gonna talk about how we

allow the user to press a button for

instance in order to create a new note

and for that note then to appear in our

stream builder and display to the user

maybe you want to take a little break

some refreshments do that please and

i'll see you in the next chapter

hello everyone and welcome to chapter 30

of this flutter course in the previous

chapters we've been working quite a lot

with our database layer and we've also

been working with the ui in order to

kind of make sure that we can

have a list of notes um but as you've

seen in the previous chapters we don't

the ability for the user to create these

notes so starting from this chapter

we're going to start working on creating

some sort of user interface in which the

their notes and those notes will be

saved then with our quad servers that

we've created in one of the previous

before we carry on let's take care of

one thing at the moment our notes view

doesn't really have like the proper

title i'm going to bring the code here

on the screen so you see it as well

and i'm going to bring scrcpy you may

have your simulator or emulator um or an

actual device on the screen so that's

let's do some rearrangement here and i'm

also going to rearrange the screen here

so you see the code better at the moment

the ui and the title of our main ui is

just saying main ui so let's take care

of that and that's inside notes view

let's find where we're creating the app

bar and here we're saying main ui so as

the caption indicates we're gonna change

like this and command s hot reload and

then we can see your notes appear there

let's now have a look at how we're gonna

enable a user to create new notes in our

there are different ways of going about

doing that there are like some

applications that will display

something called a floating action

button a floating action button is a

button that appears usually to the

bottom right of the screen if you have

languages which are left to right or if

you have arabic lang like arabic persian

language like that that you write from

right to left then that floating action

button should appear on bottom left so

it's kind of like a button that appears

um and usually it's like out of uh out

of your um out of the way for your main

uh however it can get sometimes in the

for instance if you have a list of notes

and these notes can like their titles

can go to a few lines of text and then

you have a floating button that sits

like at the bottom of the screen it

could just block some again parts of

some people don't like floating action

and floating bar action buttons are

they usually appear in android

applications is i think it's it's coming

from material design from google i could

be wrong about this but usually you

don't see them in ios applications and

since we're developing our application

to be user friendly for both ios and

android users we're not going to use

floating action buttons for now but

there's just to be clear there's really

nothing wrong with floating action

so what we could do is either we could

go in our menu here where we have log

out and create a new item in here that

says for instance a plus or add

add a new note or something like that

i'm sorry i'll just add this also

to uh do not disturb so we could either

add an item in here that says add note

something like that or we could go to

this bar that we have up here our app

and add a new item just like we have

dots we could add a new item in there

then it comes to kind of like preference

and some sort of reasoning of why we

the plus button the way we're gonna add

it and my reasoning behind um

wanting to put the plus button

these vertical three dots is that

adding a new note is pretty much like

one of the main tasks users would want

to do in your application's main user

interface so they either go in here to

and delete their notes update their

notes or add a new note so there are

three things they're going to do

deleting notes is usually not that

common so updating notes and adding new

notes should be like the main actions

that your users perform in your main uh

application ui so it should be very

instantaneous it should just be very

easy for users to do that so if you put

beside this these three vertical dots

then it takes the user just one click to

go to the new screen in order to create

a new node however if you put like add

menu in here then they have to first do

one tab to go here and then another tab

in order to create to go to the next

screen and that's just like one tab

and that's where we're gonna add a plus

button beside these three vertical dots

so before we get started with that let's

do some preparation for that so we need

a widget and which is going to be our

new notes view and as you can see we're

going to create a new file for it inside

lib views notes which is a new folder i

believe which we haven't had from before

let's go in here we have views as you

can see and we don't have a folder

in views what we're going to create now

is this dart file new node view so i'm

just going to right click on it and say

here i'm going to say a folder called

and i'm going to say new notes view dot

dart okay so that's that file already

we're not going to do anything in that

notes folder under views it just makes

sense to move our notes view here as

well which is at the moment sitting

under views you can see the breadcrumb

here says lib views notes view it makes

sense now to move this notes view which

is the list of our notes into this notes

folder as well so i'm going to need you

to just drag that file and place it

excuse me so we've done that now

now what you may have noticed if i bring

list a little bit higher now that we've

also let's just make sure we haven't

notes view oh i see that's that's really

great because by dragging the notes view

the notes folder visual studio was

intelligent enough to refactor also all

the imports that we're referring to

notes view so your editor of choice like

if you're using sublime or if you're

using some vim for instance it may not

be able to automatically take care of

that so by you moving your notes view

inside the notes folder depending on how

you do it you may need to fix your

if you search for nodesview. let's have

i can see the only place it was imported

it was the main.dart file so you will

you might need to go and fix that import

in there okay so if you're getting an

error for your imports then you know why

that's that's moving our notes you

now if you've noticed if you go back to

the editor here you'll you probably have

noticed that we have some red files in

an email field to our auth user so if

you go in here you can see that we added

this email field in our auth user in one

nodes for a specific auth user from our

so after adding that now we've broken

our tests and we haven't really had the

let's have a look at how we can fix our

test if we if you dr uh scroll down a

little bit in our tests file you will

notice where we've broken the test and

this is here we're in two places where

we're creating an off user okay here

and the way we're working with this off

user in our test is not really something

that we're writing tests for later like

we're not actually creating an off user

doing a test against the off users email

so it's at the moment it's pretty much

just decoration in that we need to just

make sure that our tests compile and

that we don't have a compilation error

here so let's go and see if visual

studio code can help us with that so i'm

just going to do command dot on mac or

control dot on windows and linux and say

add required argument eval and for email

you could just say fooatbar.com so that

doesn't matter so much and a comma at

the end to get dark formatter to format

and then excuse me gonna get help from

visual studio code again and say add

record argument email and again we're

so as you can see in the caption also we

just need to make sure that we're

running our tests and making sure that

we haven't broken anything so let's go

to our tests in here and see if i

if i can bring this up a little bit

change the screen layout so you see what

increase the size of the screen and i'm

going to search for flutter test and

that's the line the command that you

also have to type as the caption at the

bottom of the screen indicates as well

and let's just run our tests and see

what we get for results if we've done

everything correctly we shouldn't have

any problems with our tests at the

but you may have like diverged from the

course uh for a good reason and written

more tests and you may then have to fix

those tests as well and i highly

watchers whoever's watching this course

to actually do as many tests as possible

experiment with widget test integration

tests and unit tests as much as you can

all right so that's that now let's go

ahead and change the screen layout we've

taken care of our tests now and you can

tests have passed and also we don't have

any more red flags inside our

all right so what we need to do now you

when we then add a plus button to our

i believe we created it here new note

we need to define a round for it we've

all our other routes so if we have a

look at our um let's see if we can find

we have verified email routes we have

nodes route register route and all of

so i'm just going to have a look at my

notes and make sure that we define our

so let's go and call this new route and

note route and we're just going to say

and remember this doesn't really mean

except for you to handle like your route

if you had like notes with a z it would

also work as long as you're using the

so don't think that this is like bound

file finding a mechanism in flutter it

has nothing to do with that it's just

for you to define your route name so you

could literally just say fu in here and

as long as you use this route name

everywhere everything's just gonna work

that's our new note route created inside

as the notes indicate as the caption on

the screen indicates we have to go to

and we need to then go and define that

okay so we have login route register

route notes route verify email route and

then we have to define this new route

which is called new node route okay

so let's just let's just say new node

route it takes a build context in here

we could just ignore that with an

underscore if you want to i'm not doing

that and then we're going to create a

sorry a new node view um but we don't

have that yet so let's go and define the

but for now i'm just going to say const

new node view like this and this is not

because we don't have that view set up

yet we've just created the file for it

so i'm going to close some files which

we don't need and let's go into our new

and as the caption indicates we're going

to create a stateful widget called new

note view so i'm going to use a flutter

sorry visual studio codes and stateful

and i'm going to call it new notes view

and we're going to get some errors and

you know already that's because we have

an imported material dot dart so i'm

going to get help from visual studio

on mac or control dot on linux and

windows and say import material

and all those errors are going to go

so now we have our new node view

so let's then inside this new note view

go creates a simple scaffold so

i'm going to say we have a scaffold

and inside our scaffold we have an app

bar and we're going to say avbar

and an app bar has a title and in here

we're just going to say cons text

and for the body of this scaffold we're

const of text that says write your new

note here something like this okay

so this is a very simple stateful widget

at the moment i mean it's not even

stateful it and what it's doing right

now is it could pretty much be achieved

with a stateless widget but in the in

the next chapters we're going to add

more and more logic to this view so it

needs to be a stateful widget for it to

be able to work in the future as well

and for what we have planned for it okay

excuse me so now that we have this ma

new note view let's go ahead in here

back to our main dart and get help from

visual studio code to import that file

for us so i'm just gonna say import and

you'll see it will be a new import

right here on line five for me maybe

so let's import a new node view and it

allows us to basically define a route

i'm just to say command s and just to be

since actually not to be sure we are we

are 100 certain that the changes in our

into consideration when we do a hot

reload we have to do hot restart for

these changes to take effect so let's do

okay and for some reason i can actually

see my scr cpy has now crashed again

it's a bit flaky that's okay i i'm not

an open source project to be honest with

you and i can see i actually have lost

my connection from flutter as well to

let me run that code now in scrcpy on my

also going to ensure that my android

as well so turn wi-fi on on my phone and

i'm going to go back here to the main

interface so while this is all compiling

let's go to the next step that we have

to take care of which is actually

so which is actually displaying

um this new note view all right

as a caption indicates we need to go to

the notes view and on press of the icon

button show the new notes view so

i'm going to go to my notes as well go

uh notes view so let's go ahead and

go there we'll have a look at how our

note2 is structured at the moment as you

can see right now we have an array of

actions which just for now it has a

excuse me and we need to add a new icon

button in there so let's go ahead and

an icon button has to have an icon and

an on press so let's say unpressed so

remember this is going to be our plus

so that's our on press and for the icon

we're just going to say const icon

and then we're going to say icons add

and as you can see i believe that your

studio code was able to show your icons

right in line as well so you can see

here that's how the button is going to

look like which is a plus button all

and a comma here to get that working so

if i do command s in here now we should

see a plus button after hot reload all

right so but that button isn't doing

anything because it's unpressed it's

so what we need to do is just to say uh

of our context or build context and

we're just going to push a route called

so that's all you have to add a comma

here just to get the code formatting

so let's let's actually test this and

see if it works so i'm going to press

the plus button in here and you can see

our new node route is being displayed on

the screen with the little text that we

that says write your new node here right

and pressing the back button will then

send us back to the main ui of the

application and you may have noticed

that in the notes view i didn't say push

name and remove until and that's because

when you press the plus button in order

to create a new note you want the user

to be able to get back to the main ui of

the application whenever they need to

is facility facilitating this back

all right that was great stuff and that

is pretty much all we had to do for this

so a short chapter is kind of refreshing

to be honest with you if you ask me so

as is tradition let's commit our work so

that we can get ready for the next

chapter i'm gonna change the screen

oops um let's go in here change the

and let me bring up the terminal and

increase the size of the screen so i see

so we're going to have a look at our git

status and i can see there's a whole new

folder in here called lib views notes

files under there which is our notes

view and new notes view so let's just

and have a look at our status here you

mentioned there i'm going to get rid of

this make it a little bit bigger so you

so what we need to do is just to commit

this first and we're going to say step

i believe so at least so let's have a

look at our logs yeah step 12 was the

last chapter so we're going to say

and i'm gonna push now our commits to

and then we're going to say good tag

so that's for our tagging as well so if

i say tag now we can see all the tags

that we've created so far 13 of them all

so that's pretty much what we had to do

now as again is a tradition for every

chapter of this flood of course i

usually talk about what we need to do in

the next chapter so we can get right get

ready for that chapter as well in the

next chapter now that we have our new

we are going to work with adding the

logic to new note view so that we can

actually insert new notes into our

database so that we can start

those notes so next chapter is going to

be a bit of a heavy chapter code wise

if you want to grab some refreshments be

my guest please go ahead and do that and

i'll see you in the next chapter hello

everyone and welcome to chapter 31 of

this flutter course in the previous

chapter we did some preparation work in

order to create our new note view

and we've tagged everything everything

is ready it's just that we created our

new note view as a stateful widget which

has pretty much no logic it had a simple

scaffold with an app bar and a simple

text displayed on the screen so

make sure that the user is not only able

or sorry the new note view but also he

or she is able to create an actual note

we have quite a lot of work to do these

chapters as i mentioned in the previous

chapter at the end of the previous

chapter this chapter is kind of quite

uh but i'm gonna make sure to take you

through all the code that we're gonna

write step by step so you don't miss

um before we get started we need to fix

something in our um notes view and that

is to ensure that we're listening to

both the active state of our all nodes

stream plus the waiting and be i mean

without us having to actually without me

in abstract terms let me bring up the

code and have a look at what we've done

um and how we can make it better

let me change the screen layout

so you see the code better let's go to

our notes view in here and you can see

in in the actual body of our notes we

have the future builder where we get or

create a user with an email address

and which you'll soon actually see why

we're doing this and also we have this

this part which says switch connection

state waiting and then in here says

waiting for all notes the plan for us is

to in the future soon actually in the

near future to display all the notes

that the user has created in this user

interface however right now we're only

listening for the connection state

and if you look at the document

documentation for waiting it says

connected to an asynchronous computation

i'm waiting interaction however if you

look at the active it says connected to

an active asynchronous computation that

ha and that stream has returned at least

now we have if you look at our stream is

a stream of all notes so this all notes

can either be empty in the beginning or

it could contain some notes let's go

with the stream being empty

when the stream is empty meaning that

the user hasn't created any notes yet

that have been populated in a note

service then the connection state of

that stream will be waiting because dart

is now waiting for that stream to return

the first value so that's great and

we're saying okay if that's the case

then return this but as soon as the

stream contains one value or as soon as

the stream actually returns one value

then its connection state is going to be

active and what we've done is just we

waited for waiting state but as soon as

it goes to active then we're showing a

circular progress indicator and that's

not the not not the right logic so

we need to fix that so let's go to our

notes view and right after this waiting

writing two cases right after each other

it's an implicit fall through as i like

to call it some language is called a

follow-through for instance swift

meaning that a case has no logic and is

literally falling through to the next

case so you don't have any break

statements here in here okay

so this is a follow through implicit

meaning that in both waiting and active

states then we're showing this text and

if you command s then you're not going

to see any difference in the running of

your application it's just that we fixed

all right now to the exciting parts and

i'm gonna bring new notes view to

here just gonna reorganize it you don't

have to do that but you need to now go

new node view dart file because this is

where we're gonna work on for pretty

much the majority of this chapter now

so what we're going to do in this new

note view upon coming to the screen we

are actually going to create a new note

for you okay and we're going to keep

hold of that new note and creating a new

node if you remember from our node

utilities we have crowd here and we have

node service and then we have a lot of

functions in here at least let's see if

we can find the create node view sorry

the create node function here you can

see it's a future so we cannot

immediately get get a result from this

create new node so the goal for our new

node view here is to use future builder

inside the body of this function

so inside the body of this function

we're going to say as soon as this

new node view state has been created

then it also needs to create a new node

in the database however remember with

flutter we have hot reload meaning that

as you're on that view and you're

editing your text and blah blah you may

change your code a little bit and then

pressing command s is just going to call

your build function again so if you then

inside your build functions um scaffold

body and you have a future builder which

in turn creates a new note that function

is gonna go gonna get called again

meaning that every time you do hot

reload while you're on that view a new

and for that we as the caption indicates

we need to keep hold of a variable

called notes so that we don't recreate

it every time the build function gets

called alright so let's go ahead and do

let's go and define and say database

and we're just going to say notes like

also we just make it optional because it

okay and what also what we also need is

to keep hold of our note service um and

as you saw in the previous chapters we

created node server as a singleton but

also you'd be really good if you didn't

have to call this a factory uh function

for the singleton over and over again

whenever we're working with node servers

so we're gonna also keep hold of our

node service as a late final variable

so let's just say late final and we're

going to say this is endnote service

um you haven't seen maybe the ui of the

application but while we're working on

variables to keep hold of we also need

to keep hold of a text editing

controller now the way the ui of this

view is going to work here is that

instead of this text in here we're going

to create a text field which will

vertically increase the size as the user

information or their notes in that field

what we're going to do is to keep track

of the text that the user enters and

when the user is entering new text we

will automatically sync that information

with our database and in the future when

we go to firebase we're going to sync

that information with firebase

so we need a text editing controller to

keep track of the text changes all right

caption in here and let's then go ahead

and do as the caption says let's say

controller these documentation sometimes

and we call it text controller okay

so what we need to do now um is to

facilitate our uh i mean we haven't

really initialized any of these but

we're going to take care of that soon so

where we haven't forgotten about that

but what we need now as i mentioned in

the beginning of this chapter when we

come to this screen we're going to

create a new note and we need to have a

function for it as the caption in the

case it's going to be called create new

note and it's an asynchronous function

so let's go ahead and say future

because it creates a node with our

and we're going to call it create new

node and it's an asynchronous function

in this function what we're going to do

first is just to see have we created

this note before inside this node

variable if we have created this node

before then we don't have to create it

again we just return but if we haven't

created it then we go to the node

service and say create the node

and then get that node back to us all

so let's go ahead and do that let's just

then in here we say if existing note

so that's the return statement that

means we already have a note and if we

don't then we're going to create a new

note but remember when we create a new

note our um creates new note function on

the notes service if you look here

create note it requires an owner so now

all of a sudden we have to have an owner

and again remember the notes view upon

going to the main ui of the application

the notes view creates a new user in the

database meaning that you've logged in

with firebase then you go to the notes

view notes you took care of creating

that user all we have to do here is just

to retrieve that user so we can actually

count with that user already existing

so let's just then say final current

firebase and then we're gonna say

explicitly um unwrap it meaning that

we're expecting a user to be there if

you've ended up somehow in this new note

view you may be thinking but why that's

it is unsafe it is it is going to crash

the application if the current user

you should never end up in this

new node view if you don't have a

current user so ending up on this screen

and not having a current user is worth

the crash because you want your

application to crash if you're if what

you expect from your applications user

interface and logic has not been met by

the previous screen so you're now

creating an expectation and crashing the

application at this point is actually a

good thing in my eyes because if the

current user doesn't exist you should

never end up in this view if you've

ended up in this view and you have no

current user something is seriously

wrong so it's completely safe i would

say to explicitly unwrap the current

extract the email from the current user

so we're going to say current user.email

and we're going to unwrap that as well

because remember email was an optional

field but again since we know that

our authentication right now is going to

because all our users register with an

email addresses and the password then we

can be sure that the email address

so let's go ahead and get that owner

from the database so we're going to say

so we're gonna say await notes service

and then we're gonna get the user

and then we're gonna just return our

note service create node so we're going

to create a new node in here okay

so let's say note service creates notes

a future of database note which is

pretty much what we need to return in

here so let's just return a wait on that

all right fantastic that was for the

creation of the new notes and in here

you can see that we're not setting this

new notes that we just created

we're going to actually take care of

later so you don't have to worry about

all right that's for the creation of our

when this view is disposed of meaning

that for instance the user presses the

we need to ensure that the current node

in the database gets deleted if

there is no text entered for for that

the reason for that is let's say that

the user is on the main interface uh of

the application right here the user then

presses the plus button and then says

hmm i actually didn't want to do that so

if we allow the user to do that and

press press the plus button we create a

new empty node and go back then the view

may just be full of empty nodes so it

will just be like empty cells that the

user is not even able to see because

later as we'll see in the next chapters

we're going to populate this list with

the actual contents of your notes

because our notes don't have titles so

the actual text we're going to display

is the note itself in here inside

so what we're going to do is saying that

if you go and create a new node and you

don't enter any text meaning that the

text is empty work upon you going out of

out of the new note screen we're going

to delete that note if it's empty okay

so let's go ahead and create and find

here and let's just say void delete note

we go in here now we have to have a look

and and let's just say we get we get the

note so we say in here final note

note that should be populated inside of

our state and then we say if the

it's empty and the node is not null

then we go to our node service here

and then we ask it to delete the nodes

right there okay and then we say use

yeah that should that should be good to

go so that's the deletion of the note

from the database if the text inside our

text editing controller is empty

all right so that was for deleting the

note if it's empty how about actually

if there actually is text in it

and what we're gonna do in our as you'll

see soon inside this view where the user

can edit their notes or add new text to

the notes we're not going to have any

type of save button in modern mobile

applications if you're not a software

development from before you may not

notice but if you're a designer you

probably already noticed that in most

note-taking applications on mobile

devices at least there is no save button

all your contents will automatically be

saved so that's actually a good design

decision usually in most places you

don't need a save button usually in

mobile applications sorry especially in

so we're not going to have a save button

so we in order to facilitate not having

a save button we have to have a

functionality that automatically saves

the current node for instance if the

user then goes out of this view so it

will automatically be saved okay

so let's go ahead and create a function

in here as the as the name indicates

and it's called save node if text not

and i'm gonna bring the uh function

signature from my node so i don't have

to type it manually so you will need to

unfortunately type this manually

unfortunately unfortunately i don't know

but you will need to type in manually

and what we're going to do in here is

very similar to our the code that we

wrote for delete node if text empty so

first we're going to get the node

is node and then we get the text

um if the note is not null if note is

um our text is not empty then we're

and that's exactly what we're doing here

so it's very simple we're just saying

that if there is text which is is not

empty and we have a note then just

update that note in the database so very

all right two very important functions

now we have to put these functions in

use as you can see we're getting a

warning in here from the analyzer saying

that these are two private functions

which are not referenced and that's for

a good reason because we're going to

reference them inside the disposal of

when this new note view basically is

being killed by the system for instance

when the user presses the back button

so let's go into the dispose function

and we have to take care of uh

a dispose function in here and that's

going to be overwritten by default sorry

i'll bring it up here and i'll write it

from the beginning so you see this pose

okay and it does overwriting for us and

what we're going to do is first going to

say delete the notes if text is empty

then what we're going to do is we're

going to say otherwise save the notes if

and then we're going to get rid of the

text controllers and call the dispose on

it so as a good citizen of the dart land

when you create a new text editing

controller which we're soon going to do

we also need to make sure that we

dispose of it upon this pose all right

so that was a lot of code and i'm gonna

i can see i haven't actually provided

captions for us taking care of the init

so i basically what i'm doing right now

because i just noticed that i haven't

provided a caption for the init function

well we're gonna do it right now um

because that's a very very important uh

basically function that we need to

so uh i apologize for that as well i'm

gonna bring it here and then show you

the caption so you see what i'm doing

so we have this pose but we don't have

init state yet and i'm going to put init

uh let's see or do we have any state

and i can see that the visual studio

code isn't really helping me with that

so i'm just going to say overwrite void

and then we have to call super in its

states okay so you may have to type that

by hand as well individual studio code

was being a little bit angry at me

maybe because i just forgot to write the

and then in here what we need to do is

just to ensure that we're creating both

an instance of node service and also our

text editing controller okay so i'm just

and that is equal to node service and

that's just a singleton so it's not

going to create really a new instance if

it already existed from before

and our text controller is going to be a

editing controller just like that

so i'm going to save this and then i'm

going to do a hot restart um and

scrcpy is a little bit angry these days

with me when i do hot restart and i

but i have learned to live with it so

application without debugging and

bringing it bring it right there

while that is doing its job we need to

when the user is entering text in the

main ui of the application so when he or

she is entering the text typing on a

keyboard we need to make sure that we're

we're not gonna leave the updating uh

when the user presses the back button so

we're constantly gonna do that as the

for that we need some listeners so as

the caption indicate as a caption at the

bottom of the screen in any case we need

all this text controller listener is

going to do is it's going to be a body

of function it's going to be a function

that takes the current node if it exists

then it's going to take the current text

editing controllers text and update that

notes in the database all right so

let's go and create that function so

void and we're going to say text

is not yet being called it's it's for us

then to hook to the text editing

controller as a listener so we are soon

gonna write another function that

says hey text editing controller

whenever your text changes call this

function all right so don't worry about

that it's not being called yet

so in here we're basically going to get

the note um i'm going to get rid of this

as well i'm going to say final

notes is this note and then we're going

meaning that we don't have the note then

we just return we can't work with null

and then we're going to say get the text

which is from our text controller

like that and then we're just going to

await on our note service updates notes

with that text and then comma at the end

to get the formatting working

so that's easy that's very simple

explanation perhaps it's just a simple

as i mentioned now that we have this

text controller listener we also need to

have a function that is called setup

text controller listener which first

removes this listener from our text

editing controller if it has already

been added and then it adds it again all

right so let's go ahead and i'm just

going to copy that function name so i

um and then in here we go to our text

editing controller which we call text

controller and we say remove listener

and that listener at the moment for us

is called text controller listener okay

and then after removing it we're going

i'm going to add listener and

just add that listener back in case this

function is called multiple times all

so now we're going gonna get to the

juicy part of this chapter which is

because you see we've already added a

lot of coding here but no one's really

taking advantage of these so or

actually we can't say that because the

idiots sorry the disposes for instance

taking advantage of save node if not

empty and it's taking advantage of

delete note if text is empty but we're

not taking advantage of this create new

node and we're not taking advantage of

listener so that's what we're going to

at the moment the body it just says

context write your new node in here but

what we're going to do is we're going to

what is this future builder actually

going to do remember when you press the

plus button on the main ui of the

application no one is creating a new

note for you you need to do that

yourself in this new note view as its

name indicates so let's go and replace

the body of this function of this

parameter with the future builder

remember the future builder has to have

variables one is the future itself and

the other one is going to be its builder

for the future we need to call the

create new node which returns a future

the database note and we've already

so that's the future that is going to be

then we're going to write the builder

and i'm going to get help from visual

studio code to complete this and

remember in your builder you have to

what we're gonna do is since this is a

future we need to look for its done

state it's not gonna be where we don't

have to look for active and waiting we

or else we're going to show a progress

indicator okay so let's just say switch

snapshot state connection state

and help from visual studio code to add

these missing case clauses for me so

non-waiting so none of these are

so we're going to leave it like that and

default so we're just going to say

return cons circular progress indicator

when this create new node is finished so

a new node has been created in the

database we come to done but we're not

returning anything and that's the reason

you're seeing this little error here but

if the connection state is not done for

instance if it's waiting for the create

node to happen then we're going to show

a little circular progress indicator to

the user and remember this is going to

happen so fast that you're not even

going to see this however i'm completely

aware that the circular progress

indicator may not be the previous

solution but what we're going to do here

is we're not going to spend so much time

on predefining this code since it's

gonna probably be displayed to the user

on a modern hardware on a modern

telephone just for a few milliseconds so

it's probably not worth predefining this

code so much right now at least okay as

we're going on in this course but if you

have unlimited amount of time and you

and you really are attention and you

have a lot of attention to details then

you may want to fix this up a little bit

and maybe put it in some sort of center

or maybe change the color etc etc

but we're not gonna do that right now

our future builder at the moment is just

creating a future builder and it's and

it's understood that it is a database

the don connection state and say

snapshot data and though it says object

well we already know that this snapshot

database node as it was the future

itself so we're just going to say final

actually no we're going to assign that

to our nodes variable remember we have

and pretty much all those functions are

relying on that node variable to be

there and that's what we're doing we're

creating a future builder that creates

the node and then we assign it to our

so we're gonna then say snapshot

get our nodes from our snapshot

right after doing this we're going to

text controller listener because this is

it's at this point that we want to start

user text changes on our main ui

and right at this point we've done what

we had to do except for actually return

field to the user using which he or he

edit the text on the ui so let's let's

go ahead and do that so remove the break

statement in here because we don't need

it anymore we're just going to say

we're going to assign our text

our the controller parameter we're going

to assign a value of our text controller

in here so that's how a text field can

send messages to an object called a text

editing controller and say hey my text

that is our proxy to a text field in

flutter okay so that's setting up that

and what we need to also do is to allow

the user to enter multiple lines of text

in this text field because remember text

fields usually in flutter are like one

line so for instance you're writing an

email address or you're writing your

password so they're not like multi-line

text fields by default unless you make

them multi-line so that's what we're

going to do now so we're going to say

you can see it's of type text input type

alt-line all right so that's going to

allow you to have a little enter key at

the bottom uh right hand side of your

keyboard if you're left to right on like

english language or if you're right to

left language like arabic then that

little enter key is going to be at the

keyboard as you'll soon see actually and

you'll get that key on your keyboard to

in flutter as it is also in swift when

you're doing ios development there is a

creating text fields that are multi-line

unfortunately it has leaked to flutter

you you don't have like a parameter in

text field that says multiline so

if you want to create a text field that

is multi-line and it kind of like

expands as you enter more text into it

then unfortunately you have to call and

you have to assign null to the max

there are some discussions on github

about why that's the case but there's a

and what we're then gonna do is if we if

we do like this and i press command s

and we press the plus button in here

okay you'll see there's a text field in

here that's great okay however it's not

what what am i supposed to do what is

this line here am i gonna tap somewhere

here it's not so obvious so what we're

gonna do is to add something called a

hint to this text field if you're a

designer or a developer from before you

probably already know what a hint is but

if you don't know what a hint is a hint

um as this name indicates a little text

that usually gets displayed to the user

to be entered in this uh field so

let's go and add the hint and that is

through a property on our text field

inside our input decoration we're going

to add a parameter called hint text and

here we're just going to say start

a comma here to prefi the code a little

but there we go now we have hints in

here and as i bring up as i tap on this

text field you can see i can start

typing in here and press this little

button that i was talking about for

multi-line and as i start typing more

the text field is gonna increase in size

that is that is really what we have to

do in this chapter i hope i didn't scare

you by saying in the beginning of this

chapter that this chapter is gonna be

i mean there were there was quite a lot

of code but hopefully you could stick

with me throughout the chapter and get

as is the tradition in all the other

lose we don't want to lose the work that

we're doing on our code so we need to

make sure that we commit and also we

okay so let me change the screen layout

and we've tagged the previous chapter as

step 13 so as the caption indicates here

we're going to tag and commit this code

i'm going to say git status

two files change and then i'm gonna add

them all to the staging environment and

and then i'm gonna tag our code as step

14 as well and then push our tags

that was that for tagging um now again

as is tradition for other chapters as

well at the end of every chapter we're

going to talk about what we are going to

discuss in the chapter that follows

so we are now actually creating notes it

may not be immediately visible to you

but if you if you for instance have

created some notes then this screen

should be able to render those notes

because the new note view is doing

everything necessary to not only create

the note and let's see where it is here

but it also is updating that note for us

so here you can see update note so those

notes are in the database it's just that

the main ui of the application which is

this node c the dark is not able to

render them all it's doing is just

saying waiting for all nodes so

it's not so exciting but just know that

you are getting there and we are getting

there it's just there are a few steps

left to handle that and uh that's

exactly what we're gonna do in the next

chapter so get some tea and coffee if

you want to and i'll see you there

hello and welcome to chapter 32 of the

slotzer course in the previous chapters

we've been talking quite a lot about our

node service and creating stream

controller in order to populate the

stream control with the nodes and we

also have a buffer locally called

underscore nodes in our node service and

so we're kind of like working with our

notes in a really good and organic way

and we also work with the new node view

dark file where we created a stateful

widget that had a text editing

controller and i also allowed the user

we manage even to save that text as a

new note into the database so we've done

quite a lot however what wasn't so much

fun was that it was a little bit of an

anti-climax in that we we are able to

create notes but we're not able to

actually display them so we're

populating the database with new notes

but no one is able to show them on the

screen and that's what we're going to

so let me bring the code that we've

written so far to the screen here

i'm going to clear this get status just

to make sure everything's working fine

the visual studio code i'm going to

bring scrcpy to the right hand side

we have to now talk about a little

problem that we have with our nodes

service you see if you look at the code

here i'm going to increase the size so

and we have this uh shared instance that

we've created here okay so whenever

somebody says note service parenthesis

then they're actually not creating any

instance they're not creating a new

instance of node service but they're

going through this factory initializer

which in turn calls this shared

static final which in turn calls this

internal or private constructor that

means we've created a singleton so

creating a new node service over and

over again is not gonna um create a new

he's just gonna get the same shared

instance and then whoever then starts

reading or you see all notes in here

properly all notes is delegating its

responsibility to the node stream

controller or stream however our node

stream controller is a broadcast stream

controller and what that means is that a

doesn't really hold on to its current

value for new listeners so let's say you

have a stream controller that is sitting

here and you start listening to events

uh to that stream controller from one

place and then an event comes into the

stream controller and stream controller

says oh um i have one listener right

here i'm gonna delegate this information

all looks fine however however after the

propagation of this event into the

stream controller the stream controller

is not going to hold on to this value

when a new listener comes in from

any new listener to your broadcast

stream controller is not going to be

informed of the current information

which is populated in that stream

controller so if you're familiar with

for instance uh reactive programming

with rx you may know this as a published

subject and the same is true if you're

for instance versus using rx java or rx

rx swift even if you're doing like um

combined programming with a swift ui you

will know these as like published

a stream controller that is broadcast is

not gonna hold on in to its current uh

value for new listeners we need to we

need to remedy that and the way to do

move the initialization of node stream

initializer right here as we'll soon see

so i'm going to do a little bit of a

all right so as the caption indicates

what we need to do and we need to make

which is let's see where it is it's

right here we need to make it a late

final so grab the data type from where

it is and just say late final put the

data type in here and then remove the

equal all right so now it is our

responsibility to ensure that this node

stream controller is actually

initialized upon constructor upon

constructing a new instance of our node

so let's go ahead and do that inside

shared instance which is right here so

what we need to do now is to say node

stream controller is a stream controller

database nodes and then we do the exact

same thing as we did before using

broadcast however what we're going to do

use a property inside the broadcast

stream listener called on listen so this

callback is going to get called whenever

note stream controllers stream so

upon this happening we need to ensure

that our node stream controllers stream

is populated with all the values that

we've currently read from the database

so let's go ahead and do that

so we're just going to go ahead and say

add notes just like that all right so

this ensures anyone who starts listening

to this property all notes which in turn

uses the no stream controller if it's a

new subscriber then it's gonna the

unlisted um callback is gonna get called

and then we're gonna populate our stream

controllers a stream with those notes

that we've already read from the

let's now move to the next note before

we can actually get on with the rest of

this chapter as the caption indicates as

we shouldn't close the db upon hot

reload after opening db we shouldn't

close it otherwise upon every reload it

so the problem that i'm referring to is

in inside our notes view and it is right

here inside our dispose so upon doing

hot reload what we're doing is that

we're saying node service close which in

turn is going to actually close the

database but remember node service is

and is was and is supposed to be a

singleton where upon creation and upon

doing an open one time it should keep

we shouldn't play with closing of the

database inside any of our widgets

because that is going to interfere with

the internals and how the node service

is actually supposed to work so what

we're going to do as you can see since

this pose function in here the

overwriting overwriting of the dispose

function the only thing it was actually

doing was to close the node services

database we're just going to remove this

function for now because we have nothing

else to dispose of at the moment in our

so what we need to do is actually get to

the meat of this section which i'm so

excited about for this chapter

and that is to start working with

and what we need to do is to make sure

that we have a list that we can

we can grab the data that comes from our

stream here stream builder you can see

it reads all the notes and right now

we're just saying waiting for all nodes

so we're going to change that and

instead we're actually going to start

using something called a list view now

list view in flutter is an amazing

widget which i can actually show you

here so if you just type list view and

control click on linux and windows you

can see it's a box scroll view extends

box scroll view which in turn is a

scroll view which in turn is a stateless

a list view has uh some function some

really great functionality uh that it

exposes using is builder we can see here

it has a builder function and i believe

or it's actually constructor great okay

so it has a builder and inside your

builder you will be able to pass two

important parameters to this list view

we return a list view instead of that

little text that we had which right now

in here we're gonna say we have two

parameters first we are gonna tell it

how many items it has to render on the

screen so we're going to say item count

and for the item count we need to

actually listen for this snapshots data

so remember the stream builder at the

moment is listening for all notes

and so that means the data that comes

is going to be the all the notes that

we've read from the database so what we

need to do now is just to ensure that

i'm gonna actually remove this

snapshot has data so that's a property

on your snapshot that exposes whether

the snapshot has actually pro can

actually provide you with some data and

i'm going to put an else in here and

upon else we're also going to say return

con circular progress indicator okay

snapshot has any data then let's grab

that data so i'm just going to say final

all notes is snapshot that's data

and what we could do we could just say

got all the notes something like that

and we could actually print these notes

to the screen if you want to it's we

logs and change the screen layout

so you see it better and i'm just gonna

alright and i can see at the moment it's

just saying your notes so meaning that

we don't actually have any notes so if i

you can see all of a sudden we got a new

note populated into the database just

because i went here and i said i'm

see as i'm changing this our snapshot is

actually getting updated with new

information and it's constantly printing

and it's the note id is the same and you

can see his text is actually changing

and if i go out then you can see well

it's just at the moment says got all the

notes meaning that you have some notes

so if you're seeing a circular progress

indicator instead of like a text at the

moment that we're saying all the notes

it's probably because you were like me

and you didn't have any notes in the

okay now we have all the notes so how do

we then render these so what we need to

do in here we're going to say return

list view i'm going to change the screen

and you remember i mentioned before we

need to populate this listview with two

important parameters one is the item

count and at the moment the item count

and then we have our item builder get

some help from your editor to complete

build context as the first parameter of

type context and then you get an index

now inside your item builder your job is

signature of item builder it says it's a

that takes two parameters it build

context and an integer for the index and

it has to return a widget you see here

so you could return anything in here you

could just say return text item

it's not gonna look so pretty though

and actually i can see maybe did we lose

it is possible that there is something

wrong with our note 2 that it's like

deleting the notes it could be so i'm

hot reload here and my scr cpy may

actually die no but uh it's it worked

without a problem so we have an item so

if that's if that's what you're also

seeing maybe you could do a hot reload

because we've changed our nodes service

so it could be the problem that our uh

we just needed to do a hot reload for

this unlisten to actually get called all

right so that's what we're seeing at the

moment so i can see item in here and i'm

gonna press the plus button so and i'm

gonna say hello world in here

and i'm gonna go out and all of a sudden

you see two items appearing in here okay

but this is not so pretty because

displaying text on the screen

is not so nice and you won't have uh

you won't be able to easily add

interactions to these items because what

ideally is for these items to appear on

the list and then they have like their

own sizing so they have a good height so

that they are separated a little bit

from each other and as you'll see in the

next chapter we're going to work with um

deleting these items so we want the

ability for the user to see some sort of

an icon next to each item using which he

or she can click on that icon and delete

the item so text in itself is not going

to be able to provide us with all that

functionality that we need so

what we need is a little bit more

sophisticated widget and it is called

list tile so let's do that let's just

okay and our list tile is gonna have a

um a title so that's the only thing at

the moment we're gonna provide it with

and you can see it's a widget

and for the widget of this list and for

the title of this list style we're going

right there okay and i'm going to put

so for the text what we're going to say

we want to grab the text that is entered

in that note so you see we have all the

notes but we don't have the current note

so the current note that we're actually

reading its index is going to be

provided to us using this item builders

index so let's go and say final um notes

is all nodes at that index so that's the

current node that we're returning a list

its text is gonna be the note text as

uh i can see i've written tile here but

and in here we have to have a semicolon

all right so if i do command s in here

you can see now we have very

i mean a lot nicer and prettier versions

of those texts and you can see that

they're right here it says hello and

hello world and those are the texts that

we entered you can actually test that

and say my new my new notes is entered

and by pressing the back button you'll

see that your note is appearing on the

but what we want to do here is if you

in your notes so if i go and say here

long text that i've entered and i don't

want it all to be displayed in one tile

and then nodes view so we have now a

but this is in it in itself is going to

break a little bit our layout you see

in our notes list we don't want to

render the entire note we somehow want

the amount of information that we're

displaying to a size that is reasonable

since our notes don't have titles we

could infer the content of the note by

simply rendering just one line of text

and the user should be able to then say

oh that's what i've written kind of in

my notes and as you'll see in the latest

later chapters we are going to allow the

user to also click on or tap on these

existing notes in order to go and see

more information about them so

it's not the end of the world if you

don't display like the entire note to

the user and as you'll see when users

start to enter more and more information

in their notes it's actually not desired

render the entire note because imagine a

note is two pages long or you're gonna

have like two very small notes and then

two pages of long of one note it's it's

not feasible so actually it is feasible

but it's not a good user interface

so i'm going to put a comma here

and i'm just going to use a property in

our text called max lines and i'm just

then what we're going to do is to make

sure that the user kind of understands

that there is more information in here

than what we are rendering so we want to

put like ellipses at the end of the text

space to render themselves fully so

and as you can see the information is

whether the text should break at soft

line breaks so make sure that it's true

and then we're going to say overflow

and we're going to say text overflow

it says here's a very long text blah

blah blah and then dot dot so this is a

good indication then to all users to

know that well there's more information

to be rendered but there's not enough

space for that information to be

rendered on the screen right now

all right so i think i mean we've looked

at how that all works we've actually

demoed it so we don't have to do a

separate demo for this we've been

looking at it as we've been developing

and the application and that's one of

we don't have to do anything about this

you will probably be surprised that this

is all we have to do right now for the

notes view there's not much more to work

we were able to at the moment create new

notes and we're able to display those

notes and one at a time inside this list

view builder so you'll learn how to use

the list view builder as well

and what we can do as is a tradition

we're gonna go and commit and tag our

i'm gonna do some reshuffling on the

so you see what i'm doing a little bit

my built-in terminal here and we're

gonna have a look at the status

can see there are two files changed so

and let's commit this as step 15 and

before committing it you can see your

git lock from before the last commit was

so and you can also look at all the tags

so let's go ahead and say git commit

now i'm going to push that commit to

github or if you're using bitbucket or

any other provider that's fine too

and i'm going to tag this as step

and then we're going to push our tags

great that part is now done so we've

done what we promised to do in this

the next thing that we have to talk

about as a tradition in all the other

chapters is at the end of every chapter

we'll talk about what we're going to

talk about in the next chapter and you

can see that we are able to create notes

uh we're not able yet to update notes

we're going to get there soon but we

also need to allow the user to delete

that's exactly actually what we're gonna

take care of in the next chapter and the

next chapter is not gonna be a huge

chapter either just like this one so

it's gonna go very smooth but we're

gonna do some quite heavy refactoring on

our project as you'll soon see so

grab some refreshments if you want and

i'll see you in the next chapter

hello everyone and welcome to chapter 33

in the previous chapters we've been

talking about how to create new notes

and how also to display those notes on

um and now it would make sense for any

user of our application to be able to

delete the notes that they've created

and we are not right now giving that

functionality to the user and that's

exactly what we're gonna work on in this

and just a heads up we're gonna work

quite a bit with refactoring so things

are gonna get a little bit uncomfortable

where the code isn't gonna compile but

and right after breaking it so we're

going to work a little bit about on our

you see we have a few dialogues at the

moment that appear on the screen and for

or to the user where we for instance say

oh you couldn't log in or oh your

password was incorrect or we couldn't

register this user because it's a a weak

so that's like our error dialogues and

we also have a dialogue that we display

to the user when he or she's trying to

log out of the application so we have

and in this chapter what we're going to

do is we're going to consolidate how we

also display our dialogues to the user

functionality because you see the delete

part as well the way we're going to do

it is we're going to let me actually

how we're going to do it is that we're

going to put a little delete icon next

to every item on the list and we're

going to allow the user to tap on those

icons in order to display a dialogue

now this is going to be the third

dialogue and um a colleague of mine that

i work with which i really admire his

way of working he mentions that he makes

he gets to the third time of doing the

same thing again so now we've written

two dialogues to this point and we also

now need a third dialogue and that's the

point that maybe we should actually

consolidate all our dialogue displaying

function and then from other functions

we're just gonna reuse that okay

so that's what we're gonna do in this

so let's have a look at the code a

so these this is our application the way

we've listed left it at the moment

so like that visual studio code and we

have a cr cpy there as well okay

so let's then have a look at our as a

caption in case we're going to have a

our error dialog so let's go ahead in

let's see what we have constant services

crowd utilities we have and we have a

function here called show error dialog

which in turn says show dialog and then

then if you have a look at how this is

constructed the only thing it's doing is

saying like hey i have um hey i have a

title then i have just one action with a

and also and that action doesn't return

we i have some text to display all right

great now let's go to our notes view if

you look at our notes view at the end of

what does this do it's the same thing it

has show dialog it has an alert dialog

inside it it has a title and some text

but it has two actions and these actions

they do different things so one action

if it sends a value of false the other

one sends the value of true so

every dialogue that appears to the

screen so let's say this one for

our logout dialog that's the one we're

the cancel button sends a false value

and the log out button sends a true

the dialogs are all very similar they

have a title they have some contents and

they have some actions that the user can

take on those dialogues and these

actions then have their own values and

that's what we're going to do in our

application right now is that we're

going to consolidate all these into one

generic function that is going to kind

of allow us to customize it to our needs

let's have a look at how we can achieve

this so as the caption indicates here

we're first going to cut things from the

source and that's like the strategy that

i use a lot in software development so

if i'm gonna disrupt things and i'm

gonna like change the way things work

i'm not gonna be scared and i'm really

making things break and i in my opinion

you may think differently but in my

opinion it's really good to cut things

from the source break the code and then

start fixing things one at a time

instead of trying to make sure nothing

breaks while you're refactoring the code

so that's what we're going to do here as

the caption indicates we're going to go

let's see if you can find it i like to

use command p in visual studio code i'm

going to say the show error dialog in

and what we're going to do is just we're

going to remove all this code that is

and what we're also going to do is um as

the cache indicates remove the show log

out the dialog from notes view since

we're going to have a generic one so go

remove this show log out dialog all

we're gonna get errors that's okay and

you know this code that we removed also

here show error dialog is used quite a

by removing it if i like search for show

air dollar you can see we're actually

using in seven places so all of those

places are now gonna have an error

that's okay fine we're gonna fix that

soon so don't worry about that

all right so what we need to do in here

is before we fix all of that we're gonna

creating our notes list view all right

at the moment if you look at our notes

this beauty in here which is doing quite

a lot of work as you can see it's it has

a future builder inside the body of the

notes view and it has a stream builder

and a lot of code in here it would be

really great if you could separate this

code into its own place and we could

call this widget like a notes list view

and that's exactly what we're going to

do in this chapter so let's go ahead

views inside notes let's create a new

file and we're going to call it notes

and in in notes list view what we're

going to do is going to say the notes

list view is a stateless widget so we

create a stl which is a stateless widget

and we're going to call it notes list

as we've seen it before we need to

import material so i'm going to do that

right now so all those errors are going

what we need to do is we need to

a a list of notes to this notes list

view so that it can render them because

you see all the logic for retrieving the

notes can stay still in the notes view

but all notes list view is interested in

to display so let's go and expose that

as a parameter in our notes list view so

and you can see database node is not

imported right now but visual studio

code is going to be smart enough to

if your editor like if you're using vim

or something on linux or even mac and

windows if you're using that you may

have to import these things manually so

um but the import statements i believe i

mean if you've gotten to this point in

like savvy enough and you should know

all these things enough in order to be

able to solve that yourself so

um so i'm not going to repeat all that

information again just make sure that

your database note is in context in at

so that's going to be our notes

and also this notes view as i mentioned

in the previous chapter but maybe it's

actually worth mentioning in this

chapter because it's very relevant what

beside every note to the right hand side

as the trailing tile widget we're going

to display a little like a trashcan icon

that the user can tap on in order to

and what we're going to do then is to

call a little function to show a delete

dialog to the user so upon you pressing

the delete button we're going to display

a dialogue and the delete dialog is

going to be very similar to log out like

deleting this note are you sure

that dialog is going to have two buttons

yes or no or something like that

and upon pressing no we're just going to

dismiss the dialogue upon pressing yes

then we're going to delete that note

from the database all right

so what we need is you can see the notes

list view at the moment isn't like it

shouldn't have any connection with the

notes service it should be the notes

view that has that connection so this is

like do your components in flutter in

that you shouldn't leak your services

everywhere so if the notes list view

could somehow delegate the deletion task

to the notes view that would be ideal so

the notes list view could display the

dialogue it could just say hey

are you sure and if the user then says

yes the notes list view could then

delegate this information back to its

parent and say hey do something with

so let's then go and create a little

callback definition using typedef

and we're going to call it delete note

callback okay and this is a void

function that takes a database note

we're saying we're defining a function

that we're then going to use in our

nodes list view which we call we which

that will be called when the user

this hypothetical dialogue that we're

assuming gonna display that user okay so

let's go in here and define that let's

just say um delete node callback and

we're just going to say on delete nodes

so this is our callback and you're now

getting some errors from a flutter

saying that these parameters aren't

defined so i'm going to use visual

studio code and to say define these

i'm also going to make them require

so that's great we have still some

but we're going to continue building

until we can fix all these errors okay

all right that's fantastic so that's the

first part that we have to work on so

let's then go ahead and um take our

notes view the way it is right here and

you see we already have a list view

builder i'm just gonna go and grab this

and i'm i'm actually gonna cut that and

bring it into nodes list view inside the

build function alright so inside instead

of returning a container i'm just gonna

return that code that i've just pasted

it looks absolutely horrible at the

moment it's because i mean we have so

but i actually like that kind of stuff

to be honest with you some developers

get nervous when they have lots of

errors in their code and they just want

to patch them up as soon as they can

but we're gonna work just one step at a

time as we say in sweden we say

it means one step at a time

we're going to fix these errors and at

the end of this chapter everything's

so let's go in here you can see the

first error that we have is all notes

and what all notes is giving us an error

for is that it doesn't exist in this

context and that's because we have

something called notes all right so

and in here we don't have all notes

either so we're just going to say notes

is going to be extracted from notes at

and the exciting part now is that

we don't just use the title property of

our list tile anymore we're going to

start using something called trailing

and trailing is a as a property of list

tile that as its name indicates it's

specify a widget that needs to be

displayed at the end or the trail of

and this is where we're going to use an

to display our little trash can okay so

and in this icon button what we're going

to do then is we're going to define the

which looks like this and it's icon then

it's going to be icon of icons delete i

let's have a look at how delete looks

like and you can see it's a little trash

fantastic and make this cons to make the

analyzer happy as well all right

so what do we do i'm pressed so what we

need to do on press is as i mentioned

before we need to take care of the

displaying of a dialogue that says

let's just call the show delete dialogue

okay so this show delete dialogue we're

going to call it and we expect it to

remember we haven't implemented the show

we can put some constraints on the

interface of this function yet but it

doesn't yet exist so let's just say that

this function show delete dialog takes a

build context and it returns true or

false to us so if the user says yes i

want to delete some item then it it

if it's if the user says no then this

dialog should return false to us okay

so let's go ahead and say final should

and when you're using a weight you need

to make your own press function async

then we're going to say await show

delete dialog we don't have that

function remember but that's okay

okay if this is boolean then we say if

then what we're going to do is we say

and we call our on deletes notes with

just the implementation of this widget

but don't worry about these errors we're

and just save this file as well

now we need to move to the next item and

that's our own generic dialogue you can

which is so important because pretty

much this show generic dialogue and the

variations that we're going to create on

it is going to fix all these errors that

we have in our application right now so

i'm actually happy to start working on

so as the caption indicates we're going

to create a file in lib utilities

dialogues generic dialogue dart so we

have what folders do we have in here we

have lib consonants enums services

but inside utilities we don't have at

dialogues folder and remember that we

removed all the contents of this show

error dialog let's just delete the file

now we don't need that so i'm just gonna

delete it and move it to trash

so now inside utilities we have nothing

so let's go create this new file as the

caption indicates we're gonna say it's

gonna be inside a folder called dialogs

and we're going to call it generic

all right i'm going to get rid of the

sidebar and we now need to start

implementing our generic dialogue

show generic dialogue is going to be a

little bit complicated and um

and i'm saying it a little bit

complicated simply because it's going to

decided to make it generic is as the

generic dialogue i mean the file also

says generic dialect so you need to kind

of know already what you're getting

the reason it has to be generic is that

it needs to be able to produce

different sorts of values let's go to

our notes list view and you see here

we're going to say show delete dialog a

function we haven't implemented yet and

show delete dialogue all of a sudden

it's going to return true or false okay

that's one thing how about in the case

of login view so let's go to login view

how about this case show air dot log

remember show error dialog is a is also

a function we're soon gonna develop

which we have before we we killed it we

have to develop a new function called

show air dialog which in turn is gonna

use our generic dialog but in this case

it's not gonna return true or false so

we need to make sure our generic

dialogue as its name indicates is a

generic function that can based on what

you provide to it is able to return

and what i mean by what you provide to

every option or every button that is

displayed in our generic dialog is gonna

we're gonna assume that all the buttons

that you display in any given dialog is

values of the exact same type so a

dialogue that shows a yes or no button

two buttons each of which contains a

boolean value one true the other one

false or maybe you want to display 10

buttons and two of them have the value

of true and the other one had the others

8 have the value of false but what i

mean is that the buttons inside your

generic dialogue are going to have the

so we're going to call that data type t

let's go ahead and define this um show

generic dialogue so we're going to say

that this dialogue actually returns

and um what we're going to say we're

it's a function signature it kind of

all right so what does it actually mean

t optional and that's because remember

on android for instance when you display

a dialog to the user the user can

actually press the hardware down button

in order to dismiss a dialog without

actually responding to it and ios is

not so much like that in is when you

display a dialogue it's a modal that the

user has to reply to unless you create

your own dialogue or if you're

doing maybe something hacky on the side

to say that oh if the user taps outside

the dialogue then it should disappear

otherwise dialogues in ios are modal and

have to be responded to however in

android it's possible that a user

dismisses a dialogue without actually

responding to it and in this case the

show generic dialogue should actually

return nil or null depending what

language you're talking about if you're

a python developer you'd say none

define this saying we have a generic

dialog that returns some sort of a

and the first parameter that we need is

a build context so let's just say build

and we need a title and content so we're

also before we do that let's also have a

look at this thing that says build

context isn't defined and that's because

we have an important material so let's

and we have to have curly brackets in

these places because required actually

the next parameter that we have to

implement is the title and then the

content so both are going to be text or

so that's the title and now i'm going to

copy paste that i'm going to say content

it's exciting part now what we need is

some sort of way for the user to be able

a list of buttons to display the to the

to the user now every button if we say

every button by default should have for

we should we're representing every

button as a text button that every text

button needs a string to display all

right and then it will have an unpressed

so what we're telling what we're saying

is that okay we should be able to render

multiple buttons and every button should

and also we set from before every button

should also have some sort of a value

all right which is t optional so we need

a way for the user to specify a list of

buttons each of which has a title of

type string and also every one of those

buttons should optionally have a value

so that's best described with a map of

string as titles and a value of t like

so we're going to type def that we're

going to say we have a definition of a

and we have basically a type to finish

and we're going to call the dialog

and we're going to say it has it's a

okay and we're going to say that is

let's also see the map all right

key expected to find all right and

that's probably because i've misspelled

that am all right so now we have an

option builder so we're gonna then use

that option builder in our function so

you're you'll see soon how we're going

so i'm going to say that we have a

dialog option builder and let's just

okay so we have all those bits and

pieces in place now what we need to do

is inside this function actually use the

build context to display a dialogue to

the user so before we do that let's

grab all the options that the caller

wants us to display so we're going to

we call that function and now you'll see

it smart enough to understand that yeah

it's a map of string dynamic okay it

doesn't understand yet what it is

so let's go ahead and say in here in

this function we return a show dialog

and in here we have two parameters that

we have to pass one is the context

the other one is the actual builder

some help from your favorite editor to

complete the builder function which is

very simple it just takes to build

context all right and in your builder we

are going to return an alert dialogue

this you should already know from before

we've worked with alert dialogues and

show dialogue from before so this is

so for the title we're going to say we

which contains the title string

for the content we're going to say also

and then we're gonna go into our actions

and this is this is the exciting part

for me because for the actions what we

need to do you see our actions are

defined in here every key inside this

which is defined by string of the

of our dialogue so we need to start

mapping them so we're going to say

keys and then we map them all right and

and we're not going to use a shorthand

signature in here and we're just going

to do it like this all right

so now in here in the option title we're

actually gonna return a text button so

let's let's get the value first of this

right and now it's saying that yeah

you're not using it that's fine we're

gonna we're gonna fix that soon

and this huge error that we're seeing

here is because you see actions it

requires an iterable i believe no it's

actually a list of widget but

when you do a map on your keys it's

going to return an iterable so to fix

that we're just going to go at the end

here and say this is to list all right

all right so let's now fix the rest of

the problems i understand i mean this is

quite a lot of errors and you may be a

little bit overwhelmed by this but

that's okay we're gonna fix them one at

a time so a semi column at the end so to

get rid of that huge er at the end

and then what we're going to do in here

where we get the value we're going to

create a text button so let's just say

and what the text button needs as we've

seen before is two parameters unpressed

and it also needs the i believe it's

and we're going to say the child is

you may be a little bit confused by all

of this that's okay what we're doing is

very simple we have like a list of

titles to display for every button so

every button has one title and that

title is inside this map of string and

the reason it's inside a map of string

is simply because we don't want to have

we don't want to manage two separate

lists a list of titles and a list of

values and then we're going to match the

titles with the values and map is

already doing that for us furthermore

what a map of string with a t does is

ensures that every string or every key

in this case of type string is unique so

you can't have two buttons with the same

the map is perfect for this case all

right and what we're doing in here for

the actions of our alert dialog we're

every key inside our map is an option

title is a title of a button all right

so we're mapping that what are we

mapping it to every one of those titles

of type string is going to be mapped to

whose child is a text of the actual

title which is inside this key all right

i understand it could be confusing but

please just pause the video have a look

at the code and i'm sure you'll

understand it better after we actually

the values then are going to be

and what we're going to do is we're

and in here if you look at value it's

going to be dynamic and what we need to

do is just to make sure that say if

and we're going to say navigator

it was written already then i'm going to

otherwise we're just going to pop

just pop all right so this that is now

you see why we're defining the value as

in as an optional because you see some

some buttons on our dialogs may not

actually have any values just like we

login view if we go back in here this

login view is going to have an error

dialog and this error dialog is going to

use our generic dialog but this air

dialog is just going to have an ok

button it has no value the okay is just

an ok just dismiss the dialog and that's

exactly what this is going to do so as

you'll soon see the way we'll implement

our new show error dialog is going to

use our generic dialog however it's

going to place a little um option in

there that says ok and that ok has a

perfect a lot of talking a lot of logic

but that's fine we sometimes need to do

we've now written our generic dialogue

what we need to do is we need to start

using it and that is inside our error

dialogue that we're going to implement

let's go ahead and create an error

so i'm going to bring up my notes

let's as the caption indicates inside

let's see where it is inside dialogues

we're going to create a new file called

now inside error dialog what we need to

do is we need to use our generic dialog

we need to have an import in here which

we're going to get visual studio code to

remember error dialog is going to just

show an ok button it has no value so

it the short error dialog is going to

have the signature exactly as it had

before which is a future void so let's

and we're going to call it show error

and the only thing i mean the two things

that the shower dialog needs is a build

context and a text so we're saying build

and we're also going to say a string of

okay and let's import material to get

so that's that and then in here we're

actually going to return an instance of

and i believe it now should be imported

is it not imported automatically in here

it's not yet but somehow it's finding it

and i can see we have a show generic

in here so this is not the one that

we're actually gonna use so we're gonna

and then we're gonna say our air

dialogue avoid so let's import our own

so was it a show general dialogue i'm

actually curious general dialogue that's

interesting so there's a function called

but that's not what we've created we've

called show generic dialects so be

careful a little bit with that because i

actually tripped on that right now so

let's go back to our error dialog and

dialog and it's going to also import

that form you know so that's that's the

so put a comma at the end to get

formatting also working fine

and now add a comma in here to get the

formatting finding there as well

the title we're going to hard code that

and the content is just going to be the

text and our options builder now is

going to be i remember an options

builder if you go back in here

to our generic dialog is a function all

right that returns that so let's go and

define an inline function in here and we

to remove this and we say it's a

function that returns a map

and the key in here is just going to be

all right see how see how generic that

is now so we're actually defining saying

that this is a show air dial again it

just doesn't return anything it's just a

and to make it cleaner you could

actually specify here that this is a

all right that's that part so now we've

worked on our error dialogue um and now

what we need to do in order to make our

code a little bit less scary with so

many errors at the moment that we have

let's go and clean up some of these

errors and let's go ahead and use this

show error dialogue everywhere okay so

let's go to our views and have a look at

you can see now we have show air dialog

implementation of uh show air dialog so

let's get help from visual studio code

and all of a sudden you see all the

errors in the login view and disappeared

you can see we're in loginview.

and we have an error in here from our

previous import which was show air

dialog dart so let's remove that as well

your login view should now look quite

clean i'm going to close that and let's

then i'm going to save all of these

things that we have in here because we

have so many windows so many tabs open

that it's kind of scary so let's then go

and clean up this import so let's remove

the old import from utilities show error

to these errors that we're getting here

for show air dialing and get visual

studio code or your favorite editor or

id to auto import our new function

called short error dialogue which

this utilities dialogues error dialog

which at the moment uh let's see

yeah we've broken notes view simply

because we're not returning anything in

migrated or moved all the code to the

so what we need to do now is to go and

show delete dialogue okay so that's not

the one that we we need we need to work

log out functionality which is here show

so we need to create a new logout dialog

as well and this this log out dialog is

going to be very similar to how we

created our um error dialog so it's

so let's i'm actually gonna i don't know

if it's worth copying this code i

usually don't like copying even if it's

my own code sometimes i do but in this

case i think it's actually better that

so let's go ahead as the caption

indicates inside dialogues folder create

a new file called log out dialog

so in here i'm going to say new file log

and in the log out dialog so i'm going

to go to my notes as well and log out

that one all right so let's go and say

and then we need a function called show

logout dialog all right as we have it

here okay so i'm going to just copy that

name so we're going to say it's a future

and the only thing it needs is a build

we're going to get an error for build

content simply because we don't have it

and you see now the only error that

we're getting is saying that the body

which means yeah it's not returning any

value at the moment and we're going to

so what we need in here we're actually

going to return our show generic dialog

a comma at the end and a semicolon just

the context is there and we're in this

case we're actually going to say that

show generic dialogue is going to return

so the context is there the title we

need to specify kind of we're just going

to say log out and for the content we're

going to say are you sure you want to

the optional remember it's a function

we're going to make an anonymous

function in here and returns a map

and for the option of cancel we're going

to say false and for the option of

logout we're going to say true all right

we're getting a huge error in here

saying that there is a future of boolean

you're returning a boolean optional

for a function that is supposed to

return a future of bull again remember

on some platforms you're able to dismiss

your dialogues without actually

responding to any of the options

presented in the dialogue in those

platforms you actually need to guard

yourself against that case by returning

a default value so let's go in here and

so if we get this value which as you can

see is an optional bool then we say

either return that or just return false

and that's it we can put a comma at the

end as well just to get the formatting

perfect um now what we need to do is now

that we've written our show logout

dialog we have to put it to use so let's

get help from your favorite editor to

import your new logout dialog in here so

we've actually worked on that so what i

edit my caption a little bit and i'm

sorry about and i'm sorry about this

because this caption wasn't completely

that's fine now let's now now that we've

worked on the notes list view let's go

and bring notes list view inside notes

view all right so you can see here we

and but we also have our notes list view

which we have to import in here

i'm going to go to my notes and just to

make sure i have everything in place

all right so in this case that we have

all notes let's go ahead and say we

return an instance of our notes list

view and this is gonna auto import it

so like that and for the notes i'm going

to say here are all the notes and

the user wanting to delete a note i'm

just going to get visual studio code to

complete that for me you can see here

and we get the note that the user wants

then in here we're going to make this

function asynchronous and just a wait on

all right i'm going to save now if you

code in here you can see we have one

error here in our notes list view and

let's go ahead and fix that and we can

say it says show delete dialog

and we haven't yet actually written the

what we need to do is need to go and fix

that actually so it creates a delete

so let's go and right click on it and

create a new file called delete dialog

and delete dialog is going to be very

very similar to the log out dialog so

let's just go ahead kind of maybe we

could use the log out dialog so copy the

and bring it into your new file called

delete dialog and just paste it in there

and we're going to call this function

and it's going to create a generic

dialogue in here and in here we're going

and we're just going to say are you sure

the option builder is going to be cancel

we're going to have an option that just

so now you see how easy it is now that

we have a generic dialog just we're

so then let's go back to our notes list

view and fix this function fix the

calling of this function and get help

from visual studio code to import our

delete dialogue and that error also goes

so now i save my project and all of a

sudden you see we have delete icons

we should now be ready to actually put

this into test so i'm going to tap on

the hello world item here and now you

see it says are you sure you want to

delete delete this item pressing cancel

doesn't do anything but if i press on it

and say yes then the hello world note is

deleted and our notes view is getting

notified of that information from its

stream builder because remember

as we have it here let's go to our

upon deleting a node let's have a look

at the leaks node function here you see

what it does is that if it could delete

a node it actually removes it from its

array of nodes and it notifies the

actually no that's the delete node

oh yeah basically it removes the node

and then puts the entire array of nodes

in the node stream controller okay so

that's how the notes view is getting

notified of a deletion of an item we can

delete another one if you want and

so well done great job for sticking with

me throughout this chapter this was

probably one of like the most

challenging chapters in that we

had a lot of errors from the beginning

one of my goals for for this course is

not for you just to learn how to write

flutter application but actually get in

the mindset of a software developer so

and every software developer they have

their own preferences i included and one

of my preferences when i'm doing

refactoring is like to cut things from

the source as i mentioned in the

beginning of this chapter so that's why

we got so many errors in the beginning

but you stuck with me and we fixed all

those errors and now we came out of this

chapter actually quite victorious

so now we have the delete functionality

what we need to do now is just to go and

we because we've done a lot of work what

we need to make sure now is to

commit and tag our work so that we don't

lose this work so um i'm gonna do some

reorganization on the windows here so

you see things a little bit better

i'm going to increase the size okay

if we look at the previous tags we've

come to tag 15 from the previous chapter

and now we need to do a tag 16 okay so

let's go and look at the status

we have quite a lot of things that we've

modified we've deleted the show error

dialogue from before we've also

excuse me we've also added a whole new

folder here on under lib utilities

so let's do get at all and let's look at

and what we're going to do is we're

okay and push your changes into your

we're also going to tag as step 16 so

and we're gonna push our tags

if you look at your tags right now you

have one two three four five six seven

blah blah blah so we have all our tags

up and including step 16. all right

so that was for committing and also

as it's tradition we're going to talk

about what we what we need to discuss in

you can see we have the ability to

create new notes and we also have the

ability to delete notes and also

something that we didn't test is this

thing that when we create a new note and

if we back out of it you see that that

note actually is deleted from the

database so that's also working so we

have the ability to delete notes and the

ability to create notes but we don't

have the ability to update notes and

that's exactly what we're going to talk

about in the next chapter so i'll see

hello everyone and welcome to chapter 34

of the slaughter course in the previous

chapters we've been talking quite a bit

and notes and how we can delete them so

we've been working quite a bit with some

generic dialogues that we've also

developed in order to be able to handle

error dialogues and also the log out

dialogue for instance and also the

there's been quite a lot of work done on

that side but we haven't really talked

at all about how the user can tap on or

click on their existing notes in order

update that for instance and update

that's a particular node so that's what

we're gonna take care of in um

if we now start looking at the code that

we've written you you will see that

the view that actually creates a note um

we're not going to go and create a whole

new view that looks exactly the same as

this new note view just so that we can

update existing notes so the goal of

this chapter is to reuse this view so

that we can just use the exact same view

when we when the user taps on a note in

the note list we're going to pass the

existing view all right so that's what

we're gonna take care of in this chapter

let me do a little bit of a shuffling

you'll see the screen better i'm gonna

bring up visual studio code as usual

is taking care of this android screen

and we can then have a look at the first

task that we have to do as you can see

in the cache it says we have to rename

the new node to your dart to create

update node view alright so let's take

care of that i'm going to close all the

and let's go and say command p visual

studio code or maybe an android studio

is another command that you have to

execute in order in order to bring up

the list of files i don't really know

the command in android studio but if

you're not comfortable with any of those

you can just go to this new note view

right here and we are going to rename it

let's just do that now so i'm just going

to call as a cache in the case create

create updates notes view like that

if the updating i mean if if your editor

is intelligent enough and it has some

like um refactoring features built in

you don't have to do anything special

for this command to work but um you can

see in here for instance now we've

changed this file name to create updates

nodes view but we haven't really changed

for instance the class name so if i go

here this thing is still called new node

so let's go in there and perhaps change

that as well let me go to my notes

uh let's see create update note view

and we're going to go actually and

rename this new note view as well so

let's go ahead and do some refactoring

in here so i'm just going to say

refactor and let's see do we have any

refactoring features here um

we have rename symbol so maybe let's use

that and i'm going to call it create

let's see if it's successfully going to

be able to rename this for me so i can

see it renamed the class for me and it

also renamed the state class which is

exactly what i needed so if i now save

this we should have some problems

but i can see visual studio code was

intelligent enough actually to rename

dart reference to this route as well

or what we call it actually before it

that note view was a new note view was

actually being used inside our routes in

the main function of our of our

application inside main.dart now that

we've renamed that to create update note

view both the class name the stateful

then that new name should be used in

main.dart so if you're using vim or any

code editor like if you're using sublime

supply may not have this refactoring

feature that can actually go and rename

where you've used that symbol so you may

need to do that by hand so you may

actually get some errors in your

but if you get those errors don't worry

about it at least you know what the

problem is okay so you can go and fix it

all right so we've done that and now

what we need to do is i'm actually going

to press command s here and command s in

here just to make sure everything's

saved and as the caption indicates

remember we also have our routes inside

so you can see our route is still called

so i'm gonna rename this now and i

suggest that you do the same thing too

let's just say rename and let's rename

that to as the caching indicates create

or update node route okay so create or

update snow throughout just like that

and as you can see again visual studio

code helped us quite a lot now it went

and something also happened in the notes

view as well i can see and that's

press the plus button in here to create

a new node that was also using the uh

new node route but now it's updated to

create or update node routes so all i'm

trying to say in here you need to rename

that route so that it becomes create or

update new node route and depending on

your editor it may be smart enough to

have some refactoring features if it's

like visual studio code then you're good

to go just rename it but if it's not you

may have to do that by hand so just go

refactor in your code where you're using

that route to use the new name okay

let's have a look at this dilemma now

when we create a new note we just say

navigator of context push name all right

now the goal here is when we create this

nodes list view we're going to allow the

users you see at the moment we have on

delete node but we're also going to have

a parameter called untap we're going to

but the dilemma here is that when you

we need to also go to this view into

this route that we have create or update

node route but we have to pass an

argument to that route an argument just

as it is for a parameter of a function

or an argument to a function is like

route and you say hey i'm initializing

this route but i'm passing some data to

it so then that route can then in turn

reactively sorry that ralph can then

react to that and go and read that

argument and say oh was i pass an

argument yes then i'm going to do this

was i not pass an argument then i'm

going to do something else in this case

if you pass a note to our create or

update note route then it's going to say

oh i have an existing node i'm just

going to populate myself and my contents

with that note and i'm not going to

at the moment our create update note

we have this function set up in here

that says create a new node we're gonna

fix that soon okay but remember that

at the moment when you go into that view

by default it's creating a new node and

we're gonna change that so that we're

saying we're going to rename that and

saying like create or get note or

something like that soon you'll see um

but in that function then we're going to

where we passed an argument where we

pass an existing note if yes we don't

have to create a new node if no we have

so the way arguments work then is if you

have a look at our notes view where

we're using push name there is a

parameter in here called arguments and

as you can see at the moment it is just

an optional object meaning that well it

we're not we're not leveraging that at

the moment but we are going to soon so

at the call side where you're creating a

where you're creating a route and

navigation stack you can pass your

argument using that arguments parameter

and at the receiving side in this case

are let's see create or update node view

you can read then your argument

let's see let's go to some place that

does make sense let's say in here

okay you can read that argument calling

now you don't have to type as i'm typing

i'm just demonstrating something to you

okay and we can use model uh route

is context and then you can say settings

dot arguments then that's where you

basically get access to your arguments

through your modal route so now you know

how to pass arguments and you know also

how to receive them all right

let's go to the next point um

we may need to somewhere also in the

future receive an argument inside our

and that argument can be any type that

you specify for instance you can pass an

integer from one screen to the other or

you can pass a string or you can pass an

array or in our case you can pass a

as you could see in in this code let's

what's this optional yes settings

you see at the moment this guy is an

object so it doesn't really know what it

but it'd be really good if you could

somehow that allows us just to say for

of type t something like that so we

we want to extract an argument of any

type from it if that argument exists

and then we're going to use it in our

code in here and to and we get our build

context and then grab our notes out of

it so it's what we're going to do is

like create a generic way of extracting

arguments from our build context and

that's exactly what we're going to do

to do that we're going to create an

extension on build context and that

extension is going to be called guest

argument and as i've indicated in the um

as i've indicated here in the

caption at the bottom of the screen you

can see that we are going to create a

under lib utilities generics and a file

call gets arguments so you can see we

have utilities at the moment here

and that utilities follow me just fold

everything in here so it's not so

scary to look at you can see utilities

a folder called dialogues under it but

what we want to create is a folder

called generics and then a file under

that called get arguments okay

uh let's go ahead and do that right now

utilities where where to go utilities

dialogues okay so i'm just gonna right

right click on utilities and say new

file and i'm gonna say generics

now in here what we need is um

to just start writing our extensions so

i'm just going to say extension

get argument on build context okay

if i typed build context visual studio

code was smart enough to import material

if you're using sublime or any other

text editor it may not be intelligent

enough to do that for you may not have

like the extension to work with dart and

kind of so you may have to import

material yourself but remember we also

build context and modal route from

entire material uh packaging here so it

would be it would make a lot more sense

right so we're not going to use more

all right so let's go ahead and create

that we are going to optionally return a

value of type t that means any type that

you ask us to and we're going to call

and get argument itself takes t all

right so in here what we're going to say

is going to say modal route is model

we are creating an extension on build

context and this identifier in here

refers to the current build context on

which the get argument function is

actually invoked so if you're not

extensions i've talked about them before

and so it i think it was part of also

the dart introduction in the beginning

absolute beginning of this course so you

may want to go back to that in order to

understand how extensions actually work

okay so remember model route in here if

it can be an optional in here you see so

what we need to do is to guard ourselves

against that so we just say if modal

and otherwise we're just going to return

null we're saying that if we can't get

the model route then we can't extract

any argument from it okay so let's get

let's get all the arguments from our

model route now so we're gonna say args

dot arguments okay and then remember

args is also now an object as it was

on the call site the call site may skip

over passing an argument to us and we in

that case we're not going to get any

arguments which means args is going to

so let's just guard ourselves against

that so we say if args is not null and

is of this given type then we're going

so what we're saying in here is that if

we could grab any arguments from um our

modal route settings arguments and if

that argument is of the type that you

are asking this function to extract then

we're going to give it back to otherwise

we're just going to fall through to line

number 12 in here and just return and

now i'm going to save this file

now what we need is let me bring up the

caption so you see what we have to do

view which we call create actually it's

easy now now that we have a lot of files

in our project it's actually easier to

navigate if we just do command p in

visual studio code for instance to jump

files so in that file it is now called

create update node view so let's go

and as the caption indicates our creates

note in here let's have a look and see

so what we need to do is we just need to

ask them captions to get create or get

i'm gonna do that i'm gonna say create

and again we just do the code smart

enough to rename where i'm actually

using that function as well you can see

so you may otherwise if you're not using

visual code or if you're not using the

refactoring features of your favorite

editor you may have to rename that

so i don't think i have to mention this

again i think i've now mentioned it

three times so just so you know if

you're renaming something just make sure

that all the call sites are also updated

all right so now that we've done that we

actually need to grab the existing nodes

so let's do that you can see it says in

create or get existing no gets note

so let's then in here say if we if our

widgets like the widget that actually

has passed us an argument of type

database note then we're going to get

that okay so let's just call it widget

we need now a build context because

remember our extension was created on

build context however this function at

the moment has no build context so let's

go ahead and pass a build context in

so let's then go into the call site and

pass the build context in here call

context which is passed to us in the

so trusting that you've done that

we're now going to go and say context

and you see now we need our get argument

function in here but as i type nothing

appears here and that's because we don't

i can see if i just type get the

argument and ask visual studio code to

see if it can solve that problem for me

it's saying that oh there is again

arguments.dart file which has a function

do you want me to import it so i'm just

otherwise if you're not doing this you

arguments.dart file by hand all right so

now i'm just saying get arguments and

remember get arguments function in

itself has no parameters so how do you

call this function okay how do you tell

of like database node well that's very

less than sign and and grade it inside

like that and then you type the type of

object that you want to extract so if we

and now that we did that remember get

arguments returns an optional object of

that type and in this case our database

node is then an optional database node

all right meaning that you either have a

so that the user has tapped on an

existing node and came here or you don't

meaning that a user tapped on the plus

so then we say if the widget node

is not null meaning that we are updating

an existing node so that the user has

tapped on an existing node and ended up

then what we're going to do we're going

i think we set it up somewhere around

so we're going to say our node is the

and in this case what we also need to do

we need to make sure that the text field

i can show you here so if you go here

pre-populated with that existing notes

text and the way we can do that i mean

we don't have direct access to our text

field but what we do have is this text

controller which we set up in here text

controller okay so let's go and set that

text controller's text so i'm just gonna

say text controller the text is equal to

and then we're just going to return the

what we're doing in here we're saying

existing note notes so the logic

is going to stay the same the rest so if

we could extract the node from the

passing widget or the color widget then

we set that as our node set the text and

then just return the widget note

otherwise we continue exactly as we did

so let's see in here what we're also

doing existing note we're just returning

in but i can also see that upon doing a

creates note in here we're not setting

that note so what we need to do in here

let's just say final new note

and and then we store that note we say

and then we just say return you know so

in here we're also saving our notes okay

so that's really good so we actually

working with an existing notes all right

so i'm actually not sure how this has

worked before this may have been a bug

in the previous um sections in that we

didn't actually store the node in this

maybe we had that bug from before i

can't be completely sure about that so

i'm just gonna press back in here but if

you had that bug as well if you were

like returning just on a weight of node

service create node and you weren't

saving that i'm not sure how these

these functions were actually working

oh i can see that we were setting it in

here so we may not have to do that

anymore so let's then go ahead and i

mean this was quite smart but it wasn't

that good idea that the widget's build

a core part of this widget so let's

how it was working so that's the reason

it was working but it shouldn't work

okay let's move to the next section now

this part in here if i press the delete

do you remember this we developed this

in one of the previous chapters of this

course we made sure that we have a

callback and that callback was defined

notes list view i'm actually going to do

do you remember this callback it's

it was just a function that returned

nothing and accepted the notes and this

way we could tell the notes view that

the user wants to delete a note do it

and that was being called upon the user

pressing the yes button remember it's

view that is actually showing the delete

but if you look at this delete node

what is it actually a call backup is a

callback of a note all right so it has

nothing really to do with delete it's

just called delete node callback all

somehow when the any of these notes is

tapped can we utilize the exact same

function to tell the notes list view

sorry to tell the notes view that hey

you the user tapped on a note well of

course we could do that because

it has no return value and it just

accepts a note so we have a little

problem with the naming of this right

now it's just called delete note call

back but it shouldn't be all right so

we're going to utilize that both for

let me bring up the caption let's rename

that delete node callback to just node

callback so i'm going to right click on

it i'm just going to say rename

rename symbol and let's just call it

node callback okay and now you can see

it's actually renamed it here for me as

and everything should be working the way

it was before so we don't have to do

anything special it's just called node

let's move on to the next section now

which is very related so what we need to

do now is you see at the moment the

nodes list view it's not handling at all

the user tapping on any of these list

tiles and we're going to fix that so i'm

just going to go to my notes

and make sure that i have all the

so what we need now is just to make sure

on those uh on the on tap all right

so sorry that the user can tap on these

list tiles and then um we're then going

to call a function just like the node

widget that hey the user tapped on one

of these just do whatever you want so

let's go ahead and add a field here and

say on tap sorry note callback

and we'll just call it ontap

the constructor is not happy now saying

that yeah you have a final field that

you haven't initialized so let's just

add that here right after undelete and

i'm just going to make this required

parameter and a comma at the end just to

make sure that you get the formatting

we're not using on tap right now and if

you've noticed we've also broken the

notes here that's okay we'll get there

we'll fix that soon the reason we've

broken note2 is because we're not

passing on tap since it's a required

parameter okay we're gonna fix this

luckily in order to handle tabs on a

list tile we don't have to work with

gesture recognition or anything like

that but what we could do is just to say

untapped you see it's already there so

there is a function that has no

and what we need to do in here just to

call our own ontap in here and you can

see we have to pass a database node and

luckily we already have i believe a note

okay so we're just gonna say untap and

okay um so we're doing that now

now what we need to do is to go back to

notes view and handle that case you see

so i'm going to go back to our note 2

and and scroll to the part where we're

getting an error and we have on delete

but we don't have the on tap so

i'm going to go to my notes as well all

now in here right after on delete note

add this untapped functionality in here

and you can see visuals helping me and

saying oh this function actually accepts

a node so if i move my mouse over it it

already tells me it's a database node

and remember that's just what the nodes

list view is giving us all right

and then here let's make this function

an asynchronous function the reason for

that is because we're going to actually

let me actually see if we have to make

it asynchronous i don't think it needs

to be async first let's just not make it

asynchronous i had it as asynchronous in

my notes and i thought that we have to

maybe there is a reason behind it i

don't know yet but uh let's just go

ahead and not add asynchronous at the

so what we need to do in this case is

also do something very similar to what

we're doing in here navigator of blah

blah push no not that one sorry this one

navigator of context push name create or

update note route so it may actually

make sense to copy that code and let's

in on tab and paste that i'm going to

put a comma here so it breaks it down

and in here what we're going to do is

just to say arguments and we're going to

we're just saying that here's a note and

go to that screen and pass that argument

this function gets called create or get

tries to grab that argument of type

database node from our context using our

generic function which then goes to the

modal route of that context and then

grabs that argument so it's like three

layers of extraction but that's that's

quite fine now at least you have a

generic function to grab your arguments

okay so i'm going to press command s

it might be good to do a hot reload

just because we've done quite a bit of

changing so i'm going to delete these

two nodes like that and then i'm gonna

press the plus button let's just in here

i'm gonna go back and then i'm gonna

press press and i'm just gonna say my

now i have my note number one and two in

here then i'm now gonna test that to see

that we can actually go and edit an

existing note all right so i'm gonna go

to my note number one and tap on it and

now i can see i actually went to

our notes and it says it still says new

and maybe that's okay we could just

leave it like that we could update the

text maybe later that's that's fine

but at least i can see the text so i'm

now going to change actually this my new

note sorry my note 1 to my note 3 and go

back and i can see now i have my note 2

and 3. so this is a really good sign

because that means that updating an

existing note is actually working and

we're not creating a new note because

otherwise that note would have appeared

in this list so i'm going to go to this

new note 3 and then change it to

one as well so now you see it gets

perfect we got updating working and it

was quite a breeze to be honest with you

what we need now is to make sure we

don't lose our code so let's go as we

usually do at the end of every chapter

and we're gonna go commit and tag our

code okay i'm gonna change the screen

increase the size of the screen so you

see what i'm doing a little bit better

let's go to our terminal and if you look

um i think it's was it command k yeah

let's look at our git log and you see

the last uh commit that we did was step

16 and also your tags the last tag was

also step 16 okay let's go and commit

maybe before that let's have a look at

and a bit has changed modified modified

it thinks that this file was deleted

that's unfortunate that it marked it as

deleted that's okay though but a little

bit unfortunate there there are ways of

doing that so that git actually

understands that you rename the file but

i can see that visual studio code wasn't

able to actually mark that as rename and

it also it just marked it basically was

but that's okay we can live with that so

let's just say git add all and let's

and then we just say git push so we push

all our changes and let's do a git

status to make sure we didn't leave any

files behind and we haven't

so in here we're then going to say get

tag step 17 as well and push our tags

existing notes and that's fantastic so

as is tradition for every chapter in

this course we always talk about what we

when we need to work on in the coming

we have a little bit of a problem in our

source code at the moment and that is

inside our node service so i'm going to

get rid of this bottom bar here and go

and you can see in our node service

we're exposing a functionality here

called gets all nodes actually i don't

think we're using this get all notes

let's see where that is here all notes

stream and that is just reading the

notes stream controllers stream

that is coming from here you can see

being populated inside let's see

get all nodes remove we have here

so you see we are at the moment reading

all notes and we're just exposing them

to the outside world but wait a minute

our application has the concept of users

so if we if we now log out of the

application and log back in with another

that new user is going to see my notes

because there is nowhere inside this

node service that we have a concept of a

user like we're not actually filtering

these things out and exposing only

relevant data to the user okay so

we need to fix that it's very serious uh

it's not a bug it's actually something

that i've intentionally left until this

point because yeah we didn't have to

handle that it was just more fun to work

with the ui of the application but we

have to be very conscious about these

little things that we haven't

implemented and that's exactly what

we're gonna do and fix in the next

hello everyone and welcome to chapter 35

in the previous chapter as you saw we

started talking about how we can update

an existing node in the node list and we

refactored our new node view as it was

called before to become i believe create

update node view and this node view is

do two things either create a new node

or update an existing one so we didn't

create a whole new view just to be able

to update an existing node so that went

at the end of the previous chapter we

have a little bit of a problem with our

node service in that right now

node service doesn't really take into

consideration which users logged into

the application and hence it cannot

return relevant nodes for that

particular user so what the node service

at the moment is doing is just fetching

all the nodes from the database and

returning it to the current user this is

going to cause an issue in that when we

log in with one user we're going to see

all the nodes in the system and when we

log out with a user and log in with a

completely new user we're again going to

see all the notes that are stored in the

note server so we have to fix that in

before we get started with that we have

a little bit of a problem with our

and this is a bug that's been inside the

application for a while since we

basically created our cloud service and

we have to fix that so let's have a look

at what this bug actually is before i

before we go on so i'm going to put

and i'm going to put visual studio code

all right so i hope you can see the

screen so here right now we have um

maybe i don't have to hope for it i

could just bring the screen to be a

little bit bigger so if you look in scr

cpy right now we have two my note number

two and that is exactly the box so let's

go in here and to the first one and i'm

just gonna say my note number one

and go out and everything looks fine

right now it's just because we are

updating our local cache as well so

things are looking good however if you

do a hot restart of the application

and my scr cpy just died so that's okay

i can live with that it's a free

software so as your cpy and and i can

see now i've lost actually my debug

so i'm gonna restart the application

but what is going to happen now is as

you'll soon see is we have a little bit

of a problem with our updates note

functionality so you can see now that i

now that i restarted the application all

of a sudden both notes were changed to

my notes number one and that's not

that's not correct that's because

there's a bug inside the application so

how it's manifest manifesting itself is

locally it looks fine but if you do a

hot restart excuse me then it's gonna be

tripping like it is tripping right now

and the bug is right here i don't know

i don't know if you can notice that but

the update function however we are not

actually telling and this is also by the

way this is inside node services dart

inside the update node function

in here you can see we're issuing a

query to sqlite and we're saying update

the nodes table and set the text to this

text all right and that's exactly what

sqlite is doing it's going through all

the rows inside the note table and

updating their text column with the

so what we missed in there is a where

argument so we're not telling sqlite

which row to update so it's updating all

so we need to fix that as a matter of

urgency so let's go in here and say we

let's see this is our update

and right after the creation of this

dictionary we're going to say a were

and we're going to say the id field of

that column that we want to update or

sorry the id field of the row or note

that we want to update is going to be

equal to something and where args

are going to be equal to our nodes id

so i need you to also write this code

the way i've written it here so now if

you say my note number one and i go in

here and i say minor number two then

it's going to do the right thing so if

you do a hot restart then you can see

that the notes are actually populated

i'm not going to do a hot restart just

because i know scr cpy may crash again

and i have to restart the whole process

i don't want to waste your time with

and that's why i'm not gonna do a hot

restart but this should work okay

now back to what we were working on um

or back to what the main goal of this

let's have a look at how we can fix the

problem with our user server with our

not being able to return relevant nodes

except it's returning all the nodes so i

believe it's inside node service right

here oh we were there already sorry

about that so we have our node service

here notes this is happening inside uh

cache all cache notes which is you can

see it's reading all the notes from the

database using get all notes putting it

inside putting it sorry you couldn't see

that cache notes is reading all the

notes and then putting them inside the

local local variable and also populating

the stream controller with that okay

but what we need to do is need is that

we need to make sure that the current

user is saved somewhere inside this note

service so that note service knows that

okay here's the current user whenever i

return all my notes to the call site

using this all nodes functionality in

i need to actually filter out the notes

inside that list to make sure only

relevant notes that were created by that

current user are returned from this

what we need then is to kind of keep

hold of some sort of a current user in

in our service inside this uh node

service so let's go ahead and do that

our um database user in here

and we say this is optional and it's

however we always want to make sure that

that user is set before you actually

a list of notes okay so this is the

expectation of this note server so the

note server says that if you want to be

the way you're doing it as clean as

you're doing it you also make sure that

you've set this current user okay

so if that if that expectation is not

met we're going to throw an exception

and we're going to call that exception

user should be set before reading all

nodes as the caption indicates we're

going to go to our crowd exceptions

which we have from before so let's find

that crowd exceptions in the given

folder is sorry yes in the given path

that i've mentioned in the bottom of the

screen lib services cross crowd

and we're going to define a new

exception called user should be set

all right so please go ahead and define

that as one of the exceptions in your

application as well under crowd

what we need now is a way for us to be

all the given nodes based on the current

let's have a look at our all nodes at

what we need is to ensure that this all

uh the given nodes inside this stream

using some sort of filter functionality

what we have you can see a stream here

what it does is that as you can see it

to grab the current content of that

stream and then you can pass a test on

that so you can say if this object is

equal to this then do that and return

this value otherwise return something

else so it's kind of like a filtering

mechanism on a string on a stream's

value however our stream includes a list

excuse me in here you can see

we return a stream of a list of database

so what we want is a where clause that's

filter out and change the contents of

this stream based on the current user

and we need to then filter the list

based on the current user's id and only

return the database notes that are

this is a bit of a special case

so for that we need to create our own

manual like filter function on our

on our stream okay so let's go ahead and

do that so what we need to do in here

and is to create a new file as you can

see under lib extensions list filter so

i'm going to go ahead and do that let's

see if we already have some extensions

so i can see under lib right now we have

constants enum services utilities views

but we don't have any extensions so the

best way then to do that to create that

filter the dart file is just right click

and then i'm going to say extensions

so then what we're going to do in here

is to create an extension on our

so let's go ahead and just say extension

the reason i'm doing it like this is

that so we can grab hold of the contents

of that stream inside our extension okay

like if you did something like this

that would still work but in here what

we're saying is that we're extending any

and in our filter function then we can

access that t as you'll soon see okay so

and we're going to call our function

and in our filter function we want to

grab another function that does a

testing of the items so let's then say

function that grabs an item of that type

so you can see now we're basically

broken down the requirements of our

that is what's supposed to be two levels

deep is now one level leap because our

which is our database node to this where

so this doesn't exist at the moment but

so in here what we're going to say then

what we are going to do is we need to

and that will you can see it gives us

the values so in here we get the items

and in here then we say items where

we pass that word clause in here

and i can see in here actually we have a

filter of t but our stream needs to have

a list of t so then that's gonna fix the

problem for us so in this case we're

actually drilling down two levels deep

so this is the function that we just

created so it allows us to filter a

stream of lists of something and then

our where clause is going to get that

something and should that something pass

the test then it will be included in the

look i know this is complicated stuff

but please pause the video think a

little bit about it we have a stream

now we want to stream of the list of the

same thing as long as those things

any individual thing passes a specific

which is specified using this work loss

this is difficult i know it may be some

it may be like so difficult for some

users that you'll be like i don't get

any of this i don't understand but

you will just need to practice you need

to just grab a hold of this code go go

ahead and implement this on some other

functionalities like a list of list of

things and see okay if i have a list of

lists of things how do i filter out that

thing inside and it will finally click

i know it's it's a bit complicated so

is to set the current user in the node

as you can see right now we have get or

create user functionality in our node

so let's go back to our node service and

find that function get or create user

and at the moment it just takes an email

as the caption indicates we need a

parameter inside this function that also

says set as current user so when you get

which we're at the moment doing i

believe in our notes view so let's go in

uh you see get or create a user so this

is like the bare bone this is the actual

very important part of our application

where a user either is retrieved from

the database the way he or she was or

it's created and it just makes sense to

make that user the current user at this

point okay so let's go in our node

and let's change that functionality so

i'm going to bring up my notes as well

and let's add a parameter called set as

current user right here going to put a

and let's just say um that this

parameter is a boolean set as current

user and we're going to set it to true

by default all right so i need to do the

so after doing that when we retrieve the

user we're going to look at this

parameter we're going to say if set as

as current user then we're going to set

our own user to this user that we just

and also don't forget when you create

and you also have to set the current

user if that boolean flag is true so

set as current user here as well then

we're going to say user is created user

so what we did here is we just said

if we could retrieve that user from the

database we and this boolean parameter

is true then we set our own user to this

otherwise if we had to create that user

and this parameter is true then we do

the same thing we set this current user

to the created user and if you're

getting some errors in here saying that

this underscore user cannot be found

it's probably because you missed adding

a database user to your node service

which is something i mentioned just

before we moved on to creating that

filter function okay or sorry before we

all right that part is now done as well

now what we need to do is to do the

filtering and and that is something that

we need to do is uh you can see as a

cache index change all nodes stream to

and that's something we need to do in

what we're going to say is i'm actually

i think i'm going to change them

yeah just let's leave it like this so

i'm just going to say no stream

stream and right here we can use our

filter function you see now visual

studio code is like confused like oh

there is no filter function on a stream

but remember we actually added that

ourselves so i'm going to get help from

visual studio code and say command dot

on mac or control dot on linux and

windows and visual studio code and then

it's gonna understand oh there is a

filter function that you've defined on

stream do you want me to import that and

filter remember filter then gets a note

right and if i move my mouse over it now

you can see that says oh you have a

database note however our stream

actually contains a list of database

nodes and all of a sudden our filter

gets one note at a time so this is the

beauty of creating your own extensions

so that you can drill down inside

existing objects and grab what you need

inside your application all right

so in here what we need is to create a

function then you remember this function

has to return a boolean we haven't

returned anything from here yet that's

so at the end of this function we need

to return a volume so let's just say

final current user is this user

is not null which is like the condition

that we actually expect then we're going

otherwise we need to throw our exception

should be said before okay so this is

our expectation from the caller if

you're reading all notes from this

interface you need to make sure that the

current user was set when you call this

function so this needs to be true okay

sorry this yeah you may not have seen

you could also argue that oh wait a

minute if this is like the expectation

of this interface that the current user

should always be said before you read

why don't you make that the default why

don't you just do that and remove this

function and always set the user as a

the current user has to be sent only

when you're working with all nodes now

this node service should be able to work

like to update existing nodes or remove

it in those functionalities should still

work if the current user is not set

right because those functionalities are

pure cross functions that say update a

node with this id get a user with this

id delete a node with this id etc etc

they are not dependent on a current user

however all nodes is dependent on the

current user and it just makes sense to

have this functionality in here that

says set as current user that is

defaulted to true so if you're using all

nodes then it throws an exception if the

current user is not set okay so that's

my reasoning for having this as a

parameter and not making it the default

all right so if current user was not

null that's like the happy path so then

it's not as long as its um user id

current user id so we say note

a user id should be equal to current

dot id okay and remember we're not

returning a note we're returning a

boolean remember our filter function it

has a where statement that has to return

a boolean so we're not returning any

nodes in here we're just checking is

this node's use ready the same as that

that should now be good to go so what we

could do i know this may actually

and break things now because i have some

problems with scr cpy but you have to

excuse me for that it's it's nothing

that i have control over but since we've

changed quite a lot of code uh i'm gonna

now close all these screens at these

tabs and i'm going to do a hot reload

but this most probably is going to crash

oh it didn't great thank god for that

so we have our notes now how do we put

what we need to do is to log out and log

in so i'm going to go to console

and let's go to our application which is

we have two authenticated users

these two emails at the moment so right

now i'm logged in with one of them i

don't really know which one so i'm going

so i'm then going to log in with

pixeltab gmail.com foobarbas

and i can see those email those um

notes were under pixel tab so then i'm

going to log out again and i'm going to

toolbarbad and i'm going to then press

the login button and i haven't yet

verified my email so i will have to do

that so let me just see if i can take

i'm going to then bring my email

and see if i can find this um

verification email and i can't so i'm

just gonna send send email verification

and it's gonna send a new email

all right i got the email verification

so i'm just gonna click on that and i

can see now it says your email has been

let me go to restart then and now that

i've verified my email i'm going to try

oops this is register i want to go to

and now i can see for my user i'm not

seeing any notes but just to make sure

i'm just going to create a new user and

say this no sorry create a new node i'm

going to say this node was created

or just put my email in here like this

i'm going to go back and i can see that

then what i'm going to do is just to

and log in with the other user

just to make sure that that

oh that was created by the other user is

not displayed to this user okay

and now we can log in and i can only see

notes that were for this user so

congratulations that was a lot of work

that we did and that we did and uh the

application seems to be working the way

what we need to do now is just ensure

that we we won't lose our code as is a

tradition and so we need to commit our

code and also tag our code okay

shuffling around here on the screens and

i'm gonna increase the size of visual

studio code so you see it better

let's do git status and see what the

status is we've modified two files and

we've also added a whole new folder so

i'm just gonna say git add all

and if you look at our logs the previous

now we have to commit our work and tag

it as step 18 and if you look at our are

your tags as well you should have step

let's say git commit and i'm going to

here i'm gonna push these changes to

remotes which in my case is github you

may be using bitbucket or some other

and less than tag as step 18 as well

alright so that part is done now we have

tagged and committed or code so if you

say git status you should have nothing

handling here to be committed all right

again as tradition is we always talk

about what we need to mention in the

next chapter what we're going to go

through in the next chapter at the end

up until this point we've been using our

that's been working really good

everything's been saved on the on the

however if you really think about it

you've now learned how to work with

crowd and that was my that was like one

of my intentions at the beginning of

this course i wanted to teach you about

crud because it's one of the absolute

most important things that any back-end

front-end developer such as flutter

so i hope that you've learned that now

however we have a big problem here and

that is all our notes are saved locally

should anything go wrong for instance if

if the users something happens to the

user's telephone all that data is going

so the user's notes may disappear and

what's so wrong about that well if

i use my notes like my the default notes

application in macintosh and also on

linux quite a lot so i store very very

important information sometimes in my

notes and you'd be surprised that the

outline for this course i actually

managed it all i managed all of that

inside the notes application on my

macintosh so i wrote the entire outline

took many many hours and i would have

if those notes disappeared for some

reason or if my kids got a hold of my

telephone and just removed the notes and

there was no reason and then there was

no way for me to grab those notes back

what we need to do now is just ensure

that we can store these nodes in some

back end so that it's sitting in the

cloud so we don't have to manage them

locally and that's what we're going to

use firebase for and we're going to

start talking more and more about

the beginning of next chapter so i hope

you enjoyed this chapter and grab your

refreshments coffee or tea or whatever

you want some chocolates and i'll see

hello and welcome to chapter 36 of this

flutter course in previous chapters

we've been working with our quad service

quite a lot and also we've been working

so far we've stored the user generated

notes inside the crotch store which

we're backing with a sqlite database and

also made that cloud service kind of um

aware of the currently logged in user so

a user logs in he or she can only see

their own notes and when that user logs

out and another user logs and then

the previously created notes in the

database aren't exposed to the new user

so we've taken care of all those but we

still have our notes only stored in a

and from this chapter on we're going to

be working with actually moving away

from storing the user data in a local

and instead going towards storing that

when i was designing this course i was

thinking about how i can introduce more

and more concepts to to become a better

software developer and a flutter

developer and one of those absolutely

crucial things was crud create read

update and delete and um though firebase

is a good way of doing that but firebase

removes quite a lot of the logic that

you otherwise need to understand

to become a better developer so firebase

has abstracted away the concept of crowd

quite a lot and that you work with data

in the cloud and you don't really know

how that is being populated and where

when i started designing the course i

thought maybe okay we could have a look

at storing data locally first to get a

and then after that we now we understand

how crop works and how those operations

are performed at a low level on a

database level then we can move away

from it and go to a more abstract layer

so this was a choice that i met early on

when designing this course and it is

definitely not like wasted time you now

know how to work with sql light in your

applications and you will probably be

using sqlite more and more as you go on

in your flutter development um

i am i hope that you understand that we

we still have good use of uh sqlite and

we've understood that but now it's time

that we move away from our local storage

and move to using um firebase instead

so i want to bring up the caption for

the next section of this chapter and

that's uh that we're going to talk about

cloud firestore so if i bring up my

notes and go to that url that i provided

and you can see here in in here it says

firestore is a flexible scalable a nosql

cloud database to store and sync data

the way the way it works i mean you can

go actually to this link that i've

provided for you here and it tells you

about how you can actually add cloud

firestore to your application but i

believe we've already done that so if i

application also to the screen

increase the size and we go to our pop

and we'll look at our dependencies we're

at the moment using firebase core

firebase auth and um in here also tells

you you have to use cloud firestore so

let's go in here and we can see we've

already dragged in cloud firestore from

one of the absolute absolute earliest

added this dependency to our application

so you don't have to do this but if you

don't have cloud firestore added to your

application you may need to do that now

by following the instructions in this

link and if you've if you don't have it

it's probably because you've missed one

of the early chapters in this um

we're going to be using the cloud

firestore in order to store user

generated data and in this case our

you may be familiar with sql and nosql

i can explain cloud fire stories is that

two concepts that you need to understand

um which are called um collections and

the other ones are documents so

whereas in traditional sql storage you

will have hard dependencies and every uh

table for instance when we design our

sqlite database we actually have to

design our tables with specific

so we have different fields we have

foreign keys etc so that's like a

typical sql relation relational database

but when you go to node sql for instance

firestore then things are more document

based so for those of you who are doing

backend development you already know

if you're using sequel light then things

aren't document based as you would think

but when we go to firestore then you

will have like a lot more looser data

definition for your tables and for your

documents basically so one document

inside the same collection can contain

two fields and the next document can

the way it is created with firestar

so for the entirety of this course from

this point on we're going to be

dependent on firestore in order to use

it to store user generated content which

so let's now talk a little bit about

production versus test mode um firebase

as use firestore as you'll soon see it

of allowing you as a developer to

interact with your database so

and there is a thing called a test mode

and another caller production mode and

in test mode and what it means is that

as you're developing your application

which we are for instance at the moment

then you may need to for instance open

um so that you can actually interact

with it with your from your application

without even authenticating a user for

instance so even if a user is not

authenticated you can actually issue

some commands toward firestore in order

so that's that's as you're developing

your application while you're still

working with your authentication but

remember we've already nailed down the

authentication so you cannot actually

or the notes list view which is embedded

inside notes view if you forgot about

you cannot end up in there if you

haven't authenticated and if you haven't

verified your email address so we know

that in our case we don't actually

really need to use the test mode of our

database with firestore we're kind of

gonna immediately switch to production

mode and what production mode is is for

instance when you develop your firestore

database as you'll soon see in this

you will be able to add some more rules

unauthenticated access to the database

is going to be denied and this is the

kind of like model that we're going to

be using in the rest of the this course

and also almost at the end of this

course we're also going to add some more

sorry firestore database so that we make

it even more explicit who has access to

just know that there is a test mode and

a production mode test mode is a bit

in terms of security but production mode

in that case that it it just tries to

make sure that on authenticated access

uh for instance a document so the user

doesn't have access to are going to be

all right we've i've just noticed that i

mentioned a few things about rules and

you may be wondering about what these

rules actually are and what they

so i've prepared the link here so i'm

gonna see if i can actually open it on

my computer as well so i can bring it to

so these are the rules that i was

if you're for instance a back-end

developer like i am you will also be

very familiar with deploying your

application so if you're for instance

django developer or node.js with express

or whatever or flask developer then you

deploying your application to

responsible for specifying how users can

interact with your backend and what

rules are applied on what cases

uh firebase since it is not like this

traditional backend that you have to

deploy yourself since it is a product

that's already there and it's deployed

it needs your help in order to

understand its security rules so as you

can see this is a typical firebase

firestore configuration of a back-end

and you can see in here it says the

service is the firestore service and

match these documents at these paths and

only allow read and write if the user is

authenticated so if you're a django

developer you already know about like

requests you also get that you're in

django so a request user will contain

the currently logged in an authenticated

user there so that this is very similar

and i'm sorry if i'm talking a little

bit about back-end development that's

just because i'm trying to like make

this connection for those of you who are

back-end developers and trying to learn

if you're not a back-end developer just

these security rules are there to help

they're there to help you secure your

the way we've actually generated our

application let's go to the source code

and have a look at it a little bit

and when we set up our uh firebase with

the firebase cli and firestore cli there

were some files that were generated for

us automatically and they were inside

i'm going to open that for us here

and you can see some information in here

as you can see for android application

there is an api key app id messaging

sender id project id and storage bucket

if anybody gets hold of this information

as you now are going to get hold of this

information by watching this course

you will actually be able to replicate

this firebase options. in your own

application with my api key app id and

sender id and interact with the database

that i'm in control of even though you

personally don't have access to that

because that database is stored under my

using this api key and app id you can

interact with the database and it is

only the security information it's only

um authentication information or the

authentication rules that i specify in

config that will then decide who has

so don't worry also about this i'm going

to delete this firebase project actually

by the time this course is released so

i'm completely happy with this

information being public and shown to

you just so you see what i actually mean

just know that with various roles that

we can define on our firebase firestore

project we can specify who has access to

what and based on what rules for

instance if the user is authenticated or

if that user id is actually present in

that document's id field for instance so

now what we're gonna do is actually

firestore database for our project so

uh what i'm gonna do in here is i'm

going to bring up safari and i'm gonna

go to console firebase.com so i suggest

change the screen layout a little bit

and then i'm gonna go to our minus

flower project so i suggest that you do

the same thing for your application all

so when we end up here then on the left

hand side you'll see something called

firestore database and i want you to

click there and just ensure that you've

selected the correct application in here

as well you may have quite a few just

then what we'll need to do in here and

it's just to say create database okay

and as you can see this is now the

screen that may look a little bit

scary but it's completely fine

and you can see there are two different

modes specified here as we talked about

production mode and then the other one

in production mode the rules by

excuse me the rules by default are quite

um bad as you can see in here it says

any document inside the database is

unaccessible so or inaccessible

it says don't allow read or write

because the condition is just false

so and you can see it says all third

party reads and rights will be denied

this is not how we are going to set up

firestore database we as i mentioned

before we are going to tighten this up

quite a lot in in the future but not

just right now so i need you go into

start in test mode and you'll get this

message saying in um the default

security rules for test mode allows

anyone with your database reference to

view and remember database reference i

mentioned that that's inside this

firebase options so that's the reference

that we're talking about okay so it may

sound a little bit abstract but it's

really not that difficult to understand

and it says edit and delete all your

all the data in your database for the

and you can see the rule that has been

set up in here says allow read write if

request time is less than blah blah blah

so it's opening up your database

basically for 30 days it's actually

quite intelligent pretty nice okay so i

need you to do that and remember we're

gonna tighten this up soon okay

and then you can see in here it says

allow basically set up a location for

where your data is going to be stored

now there may be some sort of like um

between like the legal portions of your

business and also where you want to

store your data and where you actually

feel comfortable doing that but and gdpr

definitely makes this even more

complicated if you're living in europe

i mean even if you're living abroad gdpr

makes things complicated some websites

that are hosted in the us are still not

accessible by users in the eu

and this makes things a little bit

complicated i'm i'm basically

sweden right now so i i prefer to use

has something to do with europe and uh

i can see europe west while sweden is

kind of like in the middle so i'm just

going to use europe west right now but

again this isn't so so significant right

some speed implications for application

depending on where the server actually

is so it's really good that firebase is

giving you the option to choose the

location of your firestore database

so you may want to read more about this

and you can press learn more in order to

read more about this but i'm just going

to pick europe west just because i

believe it it could make more sense for

me since i am located in sweden

choose a location that makes sense for

you and then press the enable button

wow that is a an absolutely horrific

what that is i mean it's not even

centered so that's okay firebase

remember we're using firebase as a free

service so i just want to make sure that

everybody understands i'm very very

thankful for having firebase because

it's made life a lot easier for me

even though i can create my own backends

but i sometimes still prefer to use

it's so easy to use so uh thank you so

much any anybody who's working

on firebase and providing us with free

so let's have a look in here um about in

our rules so let me increase the size of

increase it like this so you see it

close the section to the left a little

i probably could actually have done that

so i'm going to go back in here and

press this button to close that section

all right so what we need to do now is

to as the caption indicates we're going

the security rules in our database

we allow read and write if the user is

um so we make sure you as you can see it

says request off is not null so let's go

ahead and change that so i'm gonna

remove everything after request

dot like this and you can see it gives

you access to off path resource time

so i'm just going to say off is not null

so you can actually bring it to the same

so after you've done that you can say

allow read write if request auth is not

all and that literally just means that

people who are authenticated with our

and they have a valid firebase user when

they interact with the database are

read from and write to the database

this is database wide at the moment it

says any document and we still haven't

talked about documents so much but i'll

tell you soon about that but any just

imagine anything in your database can be

read from and written to if the user is

logged in and that's not so secure

that literally means that i as user one

and you as user two have access to each

other's documents okay even if the

application itself is like segregating

these two documents saying that oh

you're user one i'm gonna just give you

user ones documents but internally as a

given our current security um

you will have access to my documents

even if the application's limiting your

access just remember that okay

after you've done that i need you to

please press the publish button

so as you can see it says publish

changes can take up to a minute to take

effect and that's all right because

we're going to actually take more than a

minute before we jump into using these

new rules in our application so

let's talk about collections here

and i've prepared a doc and a link there

so let me see if i can find that

so as you can see in here there is a

good documentation that will talk a

little bit about collections and

documents and you could go through this

um but i'm not gonna do that right now

but just so you know here's the link at

the bottom of the screen if you want to

i'm going to talk about collections

personally so you will understand it in

at this point what we need is just to go

okay and what you'll see is a screen

that kind of looks like this so it has

your project name in here and then there

is a button called start collection okay

just imagine collection as its name

indicates is a group of related objects

objects could be you could interpret

them as tables as you traditionally have

relational databases such as sqlite um

a collection just imagine for instance

if we say what does our application do

our application stores nodes for

all its users so user a has nodes user b

has nodes but user c may not have nodes

so the only thing our application is

in database right now is notes so that

could be its own collection okay so we

just create a collection called notes

and in that collection we're gonna store

every user is going to have their own

that's how we are going to do it in this

however you as a developer may just

i'm going to do it differently what i'm

going to do is i'm going to create a new

collection of notes for every user so

user a is going to have a collection

user b is going to have user b notes

assign create a collection with every

user id so you remember we get a user

identifier from firebase you may decide

to you create a collection for every

user based on their user id okay that's

fine but if you're following along with

this course i strongly suggest actually

do it the way i'm doing especially if

you if you if it's the first time you're

doing this if it's if you've done this

before you may just be comfortable with

another type of collection then be my

guest please go ahead but it might then

be difficult for you later on to follow

tap the start collection button in here

um as you can see in here it says okay

this collection is being created in the

root path and just give me an id and

here's a collection set of documents

and in here it's storing a collection of

but remember we don't have to actually

store users in our database firebase is

already taking care of this i actually

believe this is a bad example that they

provided to ask people to say example

collection of users because this kind of

gives id idea to developers oh now i

have to store my users here but those

users are already stored at the firebase

so let's go and go ahead in here and

just say we're storing nodes okay and

and you can see in here now we're

getting something called a document

notes and then it says a document id a

collection must contain at least one

document cloud firestore's unit of

storage documents store your data as

fields auto generate a document or the

id or customize one if needed okay

that that brings us to what documents

if you're if you know about uh

sql from before if you followed along

with what being and what we've been

creating like when we looked at db

then we had these tables like user and

these are like the schemas of a document

so as you can see here and here says

is created this way it has an id it has

a user id it has a text is synced with

cloud remember all those fields and it

in far in the firestore world those are

documents so that entire notes

schema is one document and every field

in it then it can have a data type so

those fields you may know them as

when we created our own tables okay so

if we go back into db browser

you may not have this db browser for sql

light open and that's completely fine

we're not gonna actually work with it

right now you may have you may even have

like is toss that database in the trash

and that's completely fine i just want

that when we created this node table or

the node documents then we had different

fields remember id user id text and

those were the exact same things in here

so if i if i go ahead and create a new

and have a look at for instance my

other uh firebase projects i can see i

have a notes app and you can here see

that um the way i had designed this uh

in the beginning of this course is i had

a collection and then every collection

had documents in it that had text and

then user id okay so that's what we're

gonna do in here we're just gonna say a

and it's typed string and it has no

value okay and then we're gonna add a

new field in here and just call it use

okay and then in here it has no value

either and then a document id that we're

just gonna auto generate okay so we just

pretty much just created a new note okay

with a random document id and it has a

field of text and another field called

great then i need you to press the save

button and now you'll see here we have

our notes collection and inside there we

have a document that has these two

so what you could do also is to delete

either a collection or delete a a

document so i'm just going to say delete

document and start delete and as you can

see now we have an empty collection

i still find this a little bit peculiar

that when we create a collection

forces us to create a document inside it

like if i go and say start collection

and then press the next button in here i

can't actually save my empty collection

let's see here a collection must contain

i'm not sure if that's actually true

because you can see now we have a

collection with no document so

i'm not sure why that was created why

rule was set when you create a new

collection but just know that it's not

completely true so you can have a

collection with no documents all right

so now let's talk a little about

streams of data if you remember from our

application in if we go to our

you remember that we have this stream of

database nodes as a stream of list of

database nodes and we call it all nodes

in our application up to this point

we've had to manage these streams

manually in that we have to like go

create a stream controller do this whole

unlisten populate the stream controller

you'd be really really happy perhaps to

hear that when we go to firebase and

firestore we don't have to do any of

already has all of this built in in that

when you for instance read all the

documents inside this notes collection

that will actually be a stream of those

stream controller and no more streams

that you have to manage manually okay

those will be exposed to your

application using firestore

so as you saw and when i created this

collection to begin with i created it

a note document that had a text and it

our goal in this chapter and going

forward is to make sure that every node

has a text and it is actually linked to

a firebase user using that user's user

application to our auth service so let's

go to off and then auth service in here

and remember we're using firebase auth

provider so let's go in there and you

when we say create user with email and

password for instance then this function

returned something called user

credential to us and user credential

actually has quite a few properties you

can see it has a credential and it has a

user inside it of type user so if you go

into that user you can see it has

different properties like display name

email email verified metadata phone

number etc but this user also has

something called a user's unique id

which we actually need in order to store

notes into our collect notes collection

and this is what i mean every document

that we create is for instance going to

random id or something which we haven't

decided yet and one of the fields let me

actually see if i can resize uh this

safari window so you see it better so

it's going to have a text and the text

is going to be generated by the user but

it's going to also have a field called

user id okay so in this user id field we

actually need to store that user's

firebase generated id in there okay

what we are doing with that user do you

remember we're not actually um exposing

the firebase user to our application and

that's a great level of abstraction

however we have a little bit of a

problem in that right now our user has

email and is email verified it doesn't

actually have a unique id so our

application is not going to be able to

it's not going to be able to associate a

new note with a user id okay

so we need to fix that so i'm just going

to go to my notes a little bit in here

update our auth user as you can see in

auth user.dart file as i've opened in

and what we need is to add a new field

which is a required field and we need to

so let's go ahead and do that now so i'm

just going to go ahead and say final

and id so this field is not optional

here you see every user that comes into

our application should have an id and

that's like the expectation that we have

on our off users okay so i need you to

go ahead and add that please here of

let's then go in here and i'm going to

the required fields i can see visual

studio code wasn't able to actually meet

i'm going to help visual studio code and

do that i'm just going to say required

this id and i need you to do the same

so now we have a problem in here in that

our auth user in here doesn't have an

id where we created from firebase user

let's go and remedy that let's just say

the id in here is the user uid remember

this uh parameter that i uh talked to

so that is now created and let me

actually go to scrcpy i can see that

visual studio code has a little bit of

problem hot reloading right now so

that's because probably the application

wasn't in the foreground so that's fixed

talking about scr cpy it's perhaps a

good idea for me to bring in crcpy here

just to make sure that we're not

bringing and breaking anything okay

so that's one change that we have to

make to our auto user the other change

that we have to make is to make sure

that the email parameter of our user is

you see the way we are creating at the

our application is that we've created

the login process of a use email and

password authentication so we don't have

like facebook authentication or google

authentication we only have username and

given that condition we can be sure that

every authenticated user in our

application actually has an email

let's go ahead and just say that email

is not an optional field anymore and in

here we're going to explicitly unwrap

that email all right so that's another

change that we made to our application

so now that we've done that you can see

flutter is not so happy with those

changes saying that well yeah you broke

something and it's our tests that have

so as you can see uh we need to make

sure that id is actually included in our

and since we're not actually creating a

specific test for that user id

we can just add a random id in here

let's just say my id okay and i'm going

bring it down here as well so we have an

id field in both cases of auth user

we have another problem as you can see

in the captions in our create update

we are unwrapping the user's email and

that's what this little orange views um

well yeah it's not an error but it's a

warning so let's go to this create

field in here as you can see we're in

inside the get a create or get existing

and we are unwrapping this email but

right now the warning is saying what is

asterisk will have no effect because the

receiver can't be not try removing the

asterisk operator and i need you to do

we have another problem also we have

another warning inside the notes of you

and i believe we're doing something

similar in the notes view so let's see

i actually don't oh here we have the

user email in here as well so i'm just

going to remove the asterisk after that

so i need you to do the same thing

now we're gonna get to the juicy parts

of the uh cloud storage integration so

i'm clean i'm basically removing all the

file all the dart um tabs from here i'm

actually not deleting the files i'm

removing like that tab so it's a clean

all our cloud storage exceptions you see

if you remember from when we worked with

our quad service which is a node service

then we also had a file under the croth

folder called crowd exceptions and in

here we define all the different things

that could go wrong when the user is

working with our node service now that

we're moving away from crud we need to

have our new exceptions defined

as you can see in the cache just like we

had the crowd exceptions we're also

going to have some exceptions thrown by

firestore service which we haven't

developed yet but we need to define

those exceptions at least okay

what we need now is to go and create

that file so i need you to please create

cloud and then create that file as cloud

i'm going to do that as well so let's

see i'm going to fold all the folders in

so we have lib services and then cloud

you can see we don't have cloud at the

moment so we do have services and we

have off in there and crowd so i'm gonna

right click on services and say new file

and then in here i'm just gonna say

and then slash cloud storage

after the creation of that file

i'm going to remove the project explorer

there as well what we need then is to

a super class for all our cl cloud

if you remember from the crowd

exceptions that we created in here

all those exceptions were actually of

type exception and that's one way of

handle them quite smoothly or better

at the call site and so that basically

is going to use inheritance and then you

and we are going to create a new

here called cloud storage exception and

all our cloud exceptions are going to be

of that type so makes grouping and

catching these exceptions in the future

create our first exception it is called

i can see it's called cloud storage

so let's go ahead and say clouds and

class cloud storage exception

and we're also going to create a

constant constructor for it so it makes

creating instance of this a lot easier

basically say that this is um an

immutable class meaning that this class

and all its subclasses need to be

immutable you could do that all right

that's fine as well but usually

exceptions aren't marked with this it's

usually data classes that are marked

with immutable so i'm not gonna do that

now so that's the parent exception we

should try not to throw that exception

as it is we have to throw subclass

subclasses of that exception okay

the first exception that we're going to

define is could not create node

exception i believe it's called yes and

we're going to throw this in our

to be written a class soon uh upon you

trying to create a new note if firebase

firestore is not able to actually create

that note then we're gonna throw this

so i'm gonna then define that exception

and you will need to type this then um i

just brought it from my notes

now also in this screen where we have

all the notes displayed for a given user

we may also not be able to retrieve all

the notes for that user for instance if

there is a network connection issue or

whatever whatever other issues that may

so we need to have an exception for that

as well and that exception is called

could not get all nodes exception okay

and it's written just like could not get

all notes exceptions exception

the next exception that we have to

define is called a could not update

nodes so we have create node exception

get node exception and now we're on the

create part is a c in crud gets is

r and now we're looking at you okay

could not update node exception so

and create a c in crud okay and so we

have c r u and then we have to define

and that's exactly what we're going to

do now so let's go define could not

delete node exception all right so

be in crop okay so now we have

um three four uh exceptions defined and

all of those exceptions are uh

inheriting from cloud storage exception

now that we've talked about the

exceptions we also have to talk about

the actual cloud storage service you see

we have our quad service at the moment

which we've been working quite a lot

with and we're very proud of it actually

it's a lot of code in my implementation

at least in here we have about

i mean it's not all code there there's

i think there are some annotations like

immutable etc but there's quite a lot of

code okay and there's a print statement

in here which i actually have to remove

there's quite a lot of code and this is

working with sql lite but we also need a

service that works with firebase

so we need to create that service soon

so just know that we are going to have

crud in here which is going to talk with

but we're moving actually away from it

so let's go in here and have a look at

and if you look at our node servicing

constants in here we have routes and at

the end of node service we have some

constants defined right in this class

and some people may like this but i

personally prefer to have my constants

defined in separate files even though

very related only to this file but just

making them putting them in separate

places just makes it easier to look at

because these constants at the moment

like hidden at the bottom very bottom of

so let's go ahead and define our

constants so let's have a look at the

path it's going to be in services cloud

and then cloud storage constants

on the services now we have cloud

and under cloud we have cloud storage

exceptions i think exceptions yep now we

have to define cloud storage constants

i'm going to go to my notes

now if you remember from our note series

we define like the tables and

and we defined the tables the columns

and and even the format of creating new

tables we don't really need these all we

need are these two fields as you

text and also we need a field for user

so let's define these let's just say

owner user id so let's go in here and

increase the size owner user

id is just user id like this and then

we're gonna say const text field name

excuse me so i need you to define these

two fields as well for your application

so let's go back to the original font

now that we've defined that if you

remember from our note service we had

these beautiful classes in here a call

called a database node and a database

given that we're moving away from

things and notes inside the sqlite

database and we're moving to towards a

we actually don't need a database user

but we do need some sort of a class that

represents these documents that we're

going to create in here okay and

what we are going to call that is called

so let's go ahead you see here is called

a database node so then you kind of know

that it is a local database maybe you

could rename this local database node if

you want to but i'm not going to do that

simply because we're moving away from

this so what's the point of refactoring

i'm going to close node service so then

let's go ahead and create a new file

called cloud note dart under services

in here now what we need to do is

actually implement cloud nodes

what a cloud node actually is going to

contain there are three properties that

the cloud node has to contain

actual identifier of that node and i

apologize i actually have to put myself

there are three things a cloud node has

one is the actual like primary key of

that note in our database every document

that is generated by firebase

is going to have a unique id if you're

coming from like backend development

then you're already familiar with this

for instance django has this idea of a

pk which is primary key you can also

read it as id so everything that's

stored in the database has some sort of

firestore is no different so every

document that is created inside a

firestore database is also going to have

so that's the first property that our

cloud node is going to contain

the other two are very familiar because

you saw here in the documents we're

gonna have a text field and the other

one is like the owner user id so there

are three fields that we have to add to

our class so let's go ahead and do that

so class sorry i have a microphone right

in front of my face like it's blocking

my keyboard so that's sometimes that's

why i have to like look like this just

and inside our cloud node let's define

these three properties so let's just say

and i'm going to copy the string here as

well and say owner user id and then

we're going to say text okay

help from visual studio code to

and um in here then i'm going to say

this is a constant constructor okay as i

said you could actually go and define

this as immutable which i actually

prefer in this case to be honest with

you i hadn't i hadn't planned to make

this immutable but i think actually

makes sense if it's a cloud node then

let's just say it's immutable okay

so that's that's the first part and i

also know that we need to make these

required parameters so let's go ahead

and do that let's just say required

before all of these parameters okay so

that they're actually required named

that are not optional basically

if you look at how our database nodes

let's see if we can find database node

so let's have a look at database node do

you remember that we had these fields

but we're pretty much never calling this

database nodes a constructor we're

always using this thing database node

and this is basically the object you

just see this map is the object that

we're reading from our sqlite database

and crew and then we're internally

creating instances of our database node

this kind of map is what you will also

however it's going to be wrapped inside

something called a query document

snapshot so it's just a wrapper

let's go ahead in here and and what

we're going to say is if you just type

visual studio code is going to import

this automatically for you okay so

then it should be imported in here so

cloud storage constants so let's go and

import those as well so let's just say

package and my nodes and we have uh what

where is this stored inside services

you need cloud firestore dart and then

let's go ahead and create kind of like a

constructor that we are going to call

from snapshot and this constructor is

going to allow firestore to give us a

snapshot of it and cloud nodes and then

we're going to create an instance of our

cloud node from that okay so let's just

and parameter is going to be query

document snapshot that has that map that

like this and we're going to call it

now you can see that we're getting some

from dart saying all final variables

need to be initialized and a function

body must be provided okay we're going

to fix it soon so this is this is the um

signature of your function then in here

your job now is to make sure that all

your fields are initialized so let's

let's just say if i can type again

it comes from our snapshot id

that's a property that is stored on this

at the snapshot level so you can get

and what we're going to say is that we

have an owner user id that we also have

to fill in so that comes from the

and in there then we have to say the

user id field name let's see owner user

under user id let's call this field name

so sorry about that let's go back to the

cloud storage constants and fix this to

say owner user id field name actually

so we missed that but that's okay it's

then we're gonna say owner user id field

id and we're going to get the text which

okay so what we have is a beautiful

cloud node immutable class with a

constant constructor and also we get

this snapshot um query document snapshot

from firestore soon and we can create

instances of our cloud nodes as you'll

all right now what we need um

is to create our new cloud firestore

so this is like the beginning of moving

away from cloud storage into firestore

so this is actually very exciting and a

a little bit intimidating maybe at first

because well we kind of have to like

but given that firestore provides you

with pretty much all the tools that you

need as you'll soon see the

implementations of the functions that

we're gonna that we're gonna do are so

minimal because the base is there fire

stores already provided the base we just

have to hook into it and grab the data

so let's close all these tabs that we

excuse me and let's go to this um

services cloud and create our new

firebase cloud storage dart file

i'm actually going to do that as well so

so let's go ahead and say we have a new

class called firebase cloud storage

at the moment it doesn't do really

anything but what we need to do uh is to

i'm gonna bring the caption for that and

if you remember we've already made our

a singleton so let's go back to our node

command p on macintosh and visual studio

windows and linux to bring up this

search files by name field and i'm just

if you remember inside note service i

at the top we had this pattern

for creating a singleton do you remember

so we kind of need or sorry this part we

not kind of actually pretty much exactly

the same thing except for this part

because this talks with a stream

controller so i find this pattern of

creating singletons in dart still quite

hacky i think i've mentioned this before

when we created the node service

but it's something that we have to do so

make sure our firebase cloud storage is

actually a singleton okay so i'm gonna

bring that code from my notes because i

don't think it's actually worth writing

this and it's not worth your time or my

but this is what you need to create so

what is happening in here is that we

then we're going to create a factory

constructor which is the default

constructor of our of our class firebase

and that is going to talk with a static

final field which in turn calls this

in um in other languages like swift and

rust it's it's a lot easier to create a

singleton but this is a pattern you have

first create a private constructor then

create a factory constructor that talks

with a static final which in turn talks

with the private constructor okay

okay after you've taken care of that

what we need to do is to grab all our

so let's just go ahead after this

factory constructor we're gonna expose a

field as the note as the caption at the

bottom of the screen in the case call

so i'm just going to say notes equal to

we're just going to say firebase and

firestore and it's going to auto import

it for me so this is not a strange thing

and then i'm just going to say our own

excuse me a collection called notes

so this is how you actually talk with a

firestore so you can see that the

signature of this collection is actually

returning use something called a

and you will soon see how we can extract

our actual notes from this collection

this isn't gonna work if you haven't

actually created your notes collection

so if you haven't done that if you

forgot to do that please go ahead

excuse me to go ahead and do that right

so the first thing we need to do is to

create a function for creating new nodes

so let's go ahead um into our project

and create a function as the

caption indicates i'm going to say void

and then we're going to say we need a

so required string owner user id i

believe we call it and then it's an

and then in here since you have

like a stream or a read write stream uh

of all your notes and that's what this

collection reference means it's it's not

only a stream that you can read from but

also it's a stream you can write to

that's why that's why it's not called a

because the stream is like you try to

and in here what we're gonna do is going

and you can see it literally says give

me a map or a dictionary or however you

an object that has keys and values

what do you want me to store in a

database and that's what nosql kind of

means in here is document based it's it

has no real structure of what you're

adding everything that you add in here

is going to be packaged into a document

that is going to be stored in here with

the fields and the values that you

so let's go ahead and say we provide you

with a document in here and the first

field is owner user id field name and

that's gonna auto import it from our

constants from before remember

and in here the value of this is going

name is just going to be an empty note

for now okay and remember this is an

async asynchronous function which

returns a future of a document reference

just like we have our collection

reference in here but we actually don't

want its results right now at least so

we're just gonna wait on it so don't

forget that weight because without doing

the weight this function is not actually

what we need to do now then is to go to

getting notes by user id so the

signature is going to be it's going to

every node we store in our database uh

is gonna have these two fields an owner

and a text field so now what we want is

to grab all the nodes for a specific

so let's go ahead and do that so it's

um get notes and it's quite a meaty

function actually i can see in here

so let's go ahead and do that right now

let's say future of iterable um of cloud

nodes and i think we have to import

cloud node as well so pressing this

button imports this for me if you're

getting some errors it's probably

because your editor hasn't been able to

and then we're going to say get notes

and a required parameter in here

under user id okay and it's an

asynchronous function so like that

so what we're going to do then is to um

on our notes in here you see we can

actually retrieve notes from our notes

collection in here by saying notes where

so we're gonna do a search inside the

collection reference and that and you do

that using the where clause okay

and these things could actually increa

like create an exception i believe the

word clause could actually throw an

exception whether it was this one

it's not documenting here but i do

believe that it could actually create an

so let's go ahead and catch this so

let's just say try we're gonna try and

then should anything happen in here

not get all nodes exception and this is

going to auto import that from our

previous code so i i shouldn't explain

this over and over again you know

so now that we have that we have a try

and catch statement in there so let's

just say we await on the notes

and we say uh where clause and the word

what is the field that you want to do

your work search on and we want to

search for all notes that are for this

owner user id so let's just say owner

should be equal to you see that's the

parameter is equal to owner user id like

waiting on it you see sorry after doing

a word this gives you a query but then

you need to actually execute this query

and you do that using its get function

let me see gets if i move my mouse over

you see it returns a future of a query

snapshot with all the objects that

firestore could retrieve from the

that's that's how we work with future so

event clause of the future allows you to

return it what it does is it returns the

value of that future to you and it

allows you to return either a

synchronous value inside the then

function or you could actually return

those who are familiar with node.js or

or even swift they're familiar with how

promises and how futures work so this is

your chance of actually returning a

future that is returned to you okay

so we're going to call this basically

value at the moment and if i move my

mouse over this you can see it says a

so in here what we're going to do is say

docs which is all the documents that

and we're going to map all those and you

if i move my mouse over it so it creates

document snapshot whereas this one was a

query snapshot this one is a query

document snapshot of those fields okay

so let's go in here and what we're going

inside this return a cloud node

and we have these three fields okay we

have the document id owner user id and

so it's our chance basically to create

an instance of our cloud node right now

columns here so we get the formatting a

and what we need to do is to get the

document id and the way to do that is

this dock has an id in here you can see

and let's just say owner user id field

and in here we're gonna say then a doc

as a string now remember this looks very

familiar where have we done this before

yeah we've done this in cloud notes from

and don't worry we're actually gonna use

that function as soon we're gonna remove

this return statement the way it's

written but let's just write it like

this right now okay so it's easier to

i think i think that should be it

yeah i believe i believe this is going

to cover it for us right now so not much

more to explain about this to be honest

we could also put a comma here

make the code a little bit more readable

and what we don't have to be honest with

you here is this return statement in

like this so yeah it's an arrow function

so we don't have to have a special

return statement but if you don't like

this kind of an arrow function you can

grab your code that you've written up to

curly brackets in here and instead use

it kind of depends on what you prefer um

i don't have a preference and i could

use an error function the way it is so

i'm just going to leave it like this

and remember we're at the moment

awaiting on this but we're not returning

it so let's just return so this is all

basically just a fancy way of us

excuse me communicating with firebase

firestore and reading documents and

there's so much to explain that i can't

go through all of these but i really

suggest that you play with these

functions yourself read the

documentations and see why is it that

so uh for that you need to read all the

that come with these functions so you

so that's getting notes by user id

us to be able to provide our notes list

in here with a stream of notes for that

um as you as you know now in our note

service the way we have it is we are

exposing this stream of list of database

node and that's what we kind of also

need to do with our firebase cloud

storage like have a function that our

excuse me can't subscribe to and read

all the available nodes for that given

user so let's go ahead and do that let's

just call it a stream iterable

and i have that function signature so i

don't think i should actually write it

manually but you may need to write it so

so that's a function signature okay

and in here what we're going to say is

that we're going to go to our notes

collection in here and get all the

let's see we have our notes and then we

and we're gonna map that and

gonna get our documents inside that

like that and let's just call it doc

and in here we're gonna create a cloud

and then we're going to say the notes

owner user id i'm gonna actually write

this and then i'm gonna tell you what

i'm basically doing because there's

quite a lot of code in here and like

pausing to describe every little bit of

this code could actually make it look

more complicated than it is so

and i'm just gonna then say owner user

semicolon there wait a minute

this ends there and then a semicolon

there yeah so let's see what is

happening in here so this looks actually

quite intimidating to look at but it's a

what we're doing in here is if you want

to grab a stream of data as it is

evolving you want to be able to

subscribe to all the changes happening

to it then you need to use something

called the snapshots as you can see this

is a stream of query snapshot whereas

where is a query itself okay and then

is a future so it just the get one

literally takes a snapshot at that point

in time and returns it to you but if you

like if you want to be updated about all

the changes live as they're happening to

your data in the notes collection then

you need to subscribe to the snapshots

that's what we're doing okay so that's

that first part with snapshots so we're

literally saying that we want to see all

the changes as they're happening live

then it says okay i will give you all

the changes that are happening live and

that comes inside the query snapshot

remember query snapshot from here

after this point is it's literally what

we did in the get notes it's saying that

okay here is a query snapshot and then

we're saying okay there are documents in

there and that's exactly what we're

doing in here there's documents in the

query snapshot and then we're mapping

every document to a cloud note all right

and then we're putting and where clause

that says we're only interested in notes

whose u owner user id is the owner user

id provided in here so without this word

clause we're literally exposing all the

to the current user for all users in the

system so that word clause is very

so and this work clause as you can as

you can see it is actually inside

flutter bin lip core iterable so that's

nothing that is it's not a function that

firestore has provided for us okay

that was a lot of information

okay let's go ahead and talk about

updating you notes sorry updating

existing notes so as we talked about it

before if you have a note and you tap on

it the way it works in our application

right now is i can tap on this node and

go and change its text like 22 and come

back out and now it's changed to 22 okay

so we need to also expose this

in inside our firebase cloud storage um

as well so the function is going to be

update node and it's going to take two

parameters document id and a text so

it's going to be a future of void and

we're going to call it update node

two parameters in here which are

required i'm going to say required

and let's make this an async function

all right then what we're going to do is

we're going to put a try and catch in

here in case we can't update the

notes and then here we're just going to

say throw could not update note

exception okay and you may actually

ignore this e if you want to as well so

or you could just yeah i think actually

we can't do an empty cache catch so you

may do like this if you prefer but i

all right and i can see that the

formatting is a little bit messed up in

and inside the try statement in here now

go to our collections again in here and

let's just say we get a doc you can see

it says okay what is the path of that

and we're going to say the document id

and then let's then go ahead and say

and it says okay what is the actual

update and inside the update what we're

so this may look a little bit crypt now

also we have to wait on it may look a

little bit cryptic in the what is doc

remember inside this function in here it

says give me the path you see this

and what we said is that inside the

notes collection every document is going

to have an identifier so we actually are

going to go with the document id which

we instantiated in here do you remember

doc id is going to go into our cloud

node document id so that's the path is

notes slash that document id so that's

how far firebase firestore it called and

basically keeps hold of its paths it's

the the path is in this case if i create

a collection you see it says oh the

collection is being created in the root

folder and it has a collection id which

in our case is called notes and we refer

to it here so we've already constructed

the notes path and every document inside

it has its own id so it's going to be

slash notes slash document id all right

so i hope and i'd explain it for you

let's now talk about deleting notes um

deleting notes actually very easy as

well so we don't have to do so much with

it's very similar to updating nodes and

we're just going to go ahead and use

document id for deleting notes so

as the caption indicates create a new

feature of void in here and we're going

to say delete node and we're going to go

ahead and use a required string

it sync and let's just do a try cache in

here in case we can't delete the

document and then we're going to say

notes exception i believe it's called

and then we're just going to say delete

i remember i believe this is actually

future void so let's just wait on it all

that's really all you have to do for

delete so there's no magic in that it's

very similar to update note except that

it's not taking care of any like fields

wow huge huge chapter we've talked a lot

about now uh about firestore and

thank you so much for for sticking with

me throughout this chapter and but if

you remember i mean if you look at what

we've done is not so much code it's 68

lines of code for me it may be less for

done all these extra commas in here so

but there's a lot of new concepts so

i took the liberty of maybe even over

but i think in the beginning it's very

important just to understand how

so great job we've done what we promised

to do in this chapter we have actually

tested to make sure that this is this is

working we're gonna do this in the next

chapter but as it's tradition we're

gonna make sure that our work is

github repository or bitbucket wherever

you're using your uh or wherever you're

hosting your git project so let's go

i want to change the screen um

layout a little bit i'm going to get rid

and i'm going to close the screen

bigger in this uh view and then i'm

excuse me let's have a look at our

status there's quite a bit modified in

here and also we've added a whole new

folder so i'm just going to say git add

and let's have a look at our log the

previous commit was step 18 and let's

have a look at our tags i can see step

let's commit now let's say let's say

and we've committed and let's push those

let's also tag and say step 19 in here

and let's push our tags as well

as again is tradition at the end of

every chapter we'll talk about what we

have to discuss in the next chapter

and as you can see it says uh we need to

start using our new service instead of

sqlite database so that's a little bit

um like a turning point in our whole uh

course in that we're gonna like toss our

local storage and go away from that and

start using our firebase cloud storage

uh it's it's i think the next chapter is

actually one of the most exciting

excuse me in this whole course so

grab some refreshments if you want to

hello everyone and welcome to chapter 37

of this flutter course as you've seen in

previous chapters we've started to move

away from our local database storage and

that was on sqlite and we started going

more and more towards using firestore

databases that are hosted by firebase so

that was a very exciting point in our um

in this course basically and for me as

well as the as your instructor to go

a cloud storage rather than using local

uh storage and you see we used crud and

as i mentioned in the previous chapter i

introduce you to crowd because it's such

an important part of software

development that you will sooner or

later need to use crowd storage locally

on your computer on your applications so

on purpose so we first talked about

local storage and then we move away from

and simply because uh even firebase in

itself is some sort of a crud storage

not some sort of it is crud but it is

stored on the cloud and concepts of crop

would have been a lot bit more difficult

for me to explain to you had me not

first implemented implemented them

in the previous chapter we prepared our

service which we i will bring the code

here so we can have a look we we

it's inside our services cloud we call

we also talked about how we can

basically start integrating in

this firebase cloud search in our

application and this is the chapter that

make those plans concrete okay

from the beginning chronologically in

this course you'll know that what i like

to do when i try to refactor things is

to cut things from the source and by

that i mean now we want to get rid of

our local crud storage and what i like

to do as a strategy is to go to

uh the application and like either

comment out that entire piece of code

which has to do with our note service

either we cut it out completely or we

so let's go ahead and deal with that now

so i'm gonna change the screen layout a

little bit here and i'm then gonna go

into our notes service so please go to

the note service and select the entire

code in here and comment it out

so that's for note service and then

we're also going to go to our i'm going

to save this file and then we're going

to go to crowd exceptions select the

entire content and comment it out please

um another thing that we need to take

care of is um inside our new firebase

cloud storage inside uh get's notes what

we forgot to do is where i actually

didn't forget to do i intentionally left

it like this so that we could get the

basic idea is as you can see here we we

are inside this uh get notes function as

the caption indicates at the bottom of

the screen we are returning an instance

of our cloud node use using its

constructor its default constructor

however if you remember from this cloud

a convenient constructor that can create

an instance of our cloud node using a

document snapshot and that's exactly

what we're getting in here you see query

document snapshot but we're not using

that convenient constructor and that's

exactly what we're going to fix

let's go in here where we have the dock

and i'm going to change this code to go

from a normal function to an error

function and then in here i'm gonna say

we return a cloud node from snapshot of

that dock okay just like that

i press s to save this file command

sorry and you can also remove that comma

at the end so you either leave it like

this with a comma at the end so it

becomes multi-line or you remove the

comma like i do in here and it just

now what we need to do um is to

firebase cloud storage and you can see

inside the functionality uh sorry inside

the create new node at the moment we're

saying void so we're not returning the

node that we're actually creating and we

we need to actually create the new new

node and return it so let's go in here

and i'm just going to say final

make the code a little bit bigger

document is equal to a weight

and if you look at your document now

you can see it is a document actually

you may not be able to see it now you

can see it probably it is a document

reference okay so it's a reference as

its name indicates is not the snapshot

in order to get the snapshot we need to

just issue the get function on it

so let's just say final fetched note is

and you'll see now fetch note is the

actual snapshot that will contain the

data of that document all right

so in here we will just return a cloud

let's see cloud node with these

the document id is going to be the

the owner user user id is provided to

our function already and the text is

just going to be empty like this and

also make sure that uh in here we don't

return void except we return a future of

save your file after that and this

we need to make sure just i'm just gonna

close uh all these tabs and as the

caption indicates we're gonna go to our

create update notes view and fix that up

talk with our new service which is the

cloud firebase storage i think we call

it firebase cloud storage sorry about

so i'm going to press command p in

visual studio code on mac or control p

and linux and windows and then just say

and here as the caption indicates we

need to import three things our

the cloud storage exceptions dark file

and the firebase cloud storage dart

files so those are at the moment inside

let's see they're inside services cloud

so i'm going to go in here i'm just

going to say import package my nodes and

so we have first cloud node so let's

i'm going to copy this path and then use

it again to import cloud storage

like that and then we also need cloud

what's it called firebase cloud storage

you will need to also do these three

imports if you haven't called your

application my notes then this package

is going to be different it's going to

be packaged the name of your application

and then services etc etc okay

the next thing that we have to do as you

we need to make sure that our create

update node views state which is right

here which at the moment contains our

node service as its node service it has

to move towards using the firebase cloud

so i'm going to go to my notes as well

in here just to make sure i'm giving you

all the information that you need so

let's change our node service in here

and call it now firebase cloud storage

and in your init function then you need

to also make sure that we get the

singleton instance of our firebase cloud

storage in the init state function all

also remember this note now is not a

database note anymore but it's actually

a cloud node so let's call that cloud

and and now we can see we have an unused

import in here so i'm just going to

remove that since we don't need that

then the next thing we need to do is as

a caption in the case we have to go to

create or get existing node and we have

to make sure that it works with the

cloud storage so let's go in here

we're not going to return a database

node anymore and we're going to say it

and here we expect a parameter of type

cloud nodes optionally that can be

and here we're not going to be working

you see here we were working with

database users before because our

application was actually creating new

users in the local database and

associating notes with those users

thankfully that now that we're going to

now that we're using firestore um

database we don't have to play with

users anymore because remember users are

what we can do is just remove that owner

and now we await on our node service and

we just say create new node and then we

need an owner user id and remember this

owner user id is going to be the actual

current user's user id so let's just say

final user id is current user

and then in here we just say user id

okay and we're storing that note in here

as we were doing before so we didn't

change that code at all and then we're

seeing new notes also need to be

so now we need to fix the creation of

our new node and that's something that

we've already done so that there

shouldn't be a separate point really in

the caption so we've already done that

nothing to take care of right now

we also need to take care of now our

deleting a notes you remember when we go

node creation view if the node's text

was empty we actually delete that node

from the database okay right now and now

we need to go towards our node service

and also delete it by using the new

function which is called delete node

and let's see what it takes as a

parameter it takes a document id

and that's our node's document id okay

so that's for delete note and

now we have another function very useful

function that saves the notes and when

we go out of the screen if the if that

if the text for that note is not empty

very similar to delete node but it kind

of does the opposite make sure that the

node is present and also that the text

to the text editing controller is set if

not empty meaning that the text is set

then we update the current node so let's

then await on it and in here we just say

the document id is going to be our notes

and the text in here let's see

oh we have to just put a comma in there

so that's updating the save node if text

now we need to go to our note list view

and i'm going to do the same thing in my

do we have any errors in here yes i can

see i'm getting an error for update note

and i don't really know what the problem

document id is required okay and i can

see that this is something also we need

to update so let's go to your text

controller listener function as well and

the note there as well you can see it's

now we now have to say update note

and we have a note document id and then

we've got text so please ensure that

you're you've taken care of the text

controller listeners functionality as

and i'm just making sure that that's

exactly what we've done in my notes as

so that that was one step back um now

let's go and do what the caption at the

bottom screen says let's go to our notes

notes list view and as you can see at

the moment we're working with a list of

database notes and we don't want to do

this anymore we actually want to work

with iterables because that's like the

default way that firebase actually works

it works with eye troubles it doesn't

and iterables are actually better

because they're like lazy lists so let's

change this to an iterable of a cloud

node like this and also we change our

node callback to be a cloud node

if i can spell and also we have to also

import this so i'm just going to import

cloud node so that error is going to go

away i'm going to remove this uh import

now when you're using eye troubles you

can't do a subscript like we're doing in

here you have to say object element at

and then you have your index and that's

pretty much what we're doing in here so

now if you've made this change in your

node callback you made this change from

list to iterable and you change this

from database node to cloud node and

also change this function from a

subscript to element add then you

shouldn't have any errors in your notes

now we're going to go to a little bit

juicier changes that we have to make to

ensure that our application works as

notes view like here and you'll see now

actually i can see my notes here uh

we have to do a few updates in here

because we're not going to work with

node service anymore since it doesn't

but one bigger change that we have to

is as you can see in the cash offset

why is that here is the future builder

you can see the future builders actual

future is to get or create a user but do

and the answer is obviously no because

previously we were using this feature

builder to create a user in our database

so that we can associate notes with that

however since now we're going towards

cloud storage the users like users in

your application are managed by firebase

itself so you don't have to

create them in that sense when a user

has logged in and landed on the main

interface of your application that

firebase user already exists so you

don't have to do anything so we need to

remove this future builder so i'm just

going to press command dot on it and

sometimes visual studio code can

actually help with that to remove it but

it's not helping at the moment

so what i'm going to do in this case as

you can see i want to just grab this

just grab the stream builder without the

and find the end of that stream builder

visual studio code is helping me very

nicely with this line in here and saying

this is the end of stream builder so i'm

gonna do that and cut it okay so now

what you should be ending up with is

your future builder like that looks like

this and then i'm gonna basically kill

that future builder like this okay so

then paste your stream builder

in the place that your future builder

of your scaffold should just be the

stream builder okay so basically we just

got rid of the future builder all right

so that was that what we need to do then

is to make sure also in here that we're

not using that that we're not exposing a

user email you see from now on when we

create and notes read notes et cetera

we're going to use a user id the user's

identifier so we're not going to work

with our um with the email so

i'm also going to go to my note sorry

as the caption at the bottom of the

screen indicates let's go and change

and we're just gonna go off service

firebase current user and then we're

gonna get the id okay so that's our user

and the rest now is kind of history we

new node service so let's remove this

and now let's say this note service it

is a firebase cloud storage so we're

going to say firebase cloud storage

and in here we just add that and

initialize that we say firebase cloud

if you remember correctly um it is now a

singleton so we're not creating new

instances basically by doing this

although it looks like we're doing that

so inside our stream builder now what

we're gonna do is not gonna say all

notes anymore like that we're going to

but we're going to pass the owner user

id and that owner user id remember we're

storing it as a getter call user id

and for all our notes in here remember

this all notes is going to give us an

eye trouble if i move my mouse over

there you can see it's an eye trouble of

cloud node so it's not a list anymore so

i can i can see it's complaining that

cloud node can't be found so i'm going

to import cloud node like that

upon deleting in here we also need to

make sure that we call the new one that

says delete node and in this case we

so that is that seems to be working fine

but what we got here is a subtype of

type firebase cloud storage node service

where are we getting that error let's

in here node 2 and that's okay and

that's because we probably don't have to

do a hot restart and doing a hot restart

could kill my scr cpy and i can see that

it did that but that's fine too i'm

do this and i'm gonna run the

application now from scratch and this is

simply because i mean this is a state

management in your application because

we had a node service from before and we

do a hot hot reload but hot reload all

this node service that used to be node

service is not node service anymore it's

a firebase cloud storage so what should

state residue that is kind of like

staying in your application and you

can't clean it until you do a hot

restart and when i did a hot restart i

so i can't i can't do anything about

that problem but let's just run the

application from scratch and just make

sure everything is working as expected

all right now i can see that i've logged

into the application and i have no notes

let me bring up the caption for the next

topic to talk about so what we need now

you can see notes have disappeared and

this is a good sign because that kind of

means that we have moved away from our

crotch storage and now we're not reading

those notes that were in the crotch

so let's go and create some notes so i

want to press the plus button in here

and i'm just going to say note

number one so if i press the back button

in here i can see that node number one

is appearing here and let's go create

another one and let's say note number

great note number one and number two if

i press this number two and then change

it to note number three you can see that

those changes are immediately taking

so let me log out from this user and

let's log in with i don't know really

which user i was logged in with before

i'll log in with this user i can see

that user has no notes i'm just going to

and go out so now if i log out from this

one.user in here and if i say i want to

i can see my note one and three are

displayed here so i can just say note

and if i log out from this user

and log in again with vanbot i should be

great so that seems to be working now

what we could do i mean if you're just

like me and you're curious how this data

is actually stored in firebase we could

do that so let me open up a window in

and let's go ahead into our project on

firebase console and let's go in

and let's have a look in here as you can

see there are four documents two

documents per person per user and you

can see these two have the same user id

and that's the that's the van load user

you can see it it starts with a and c

and the other two nodes they have

another user id which is for pixelity av

remember this a and c user what we can

do now is actually go in here to the

authentication section and have a look

at this vendor user and you can see the

and the other user actually has erd so

if we go back to firestore and look at

notes created by pixelity you can see

that their user id is erd you can see

so very well done congratulations in two

chapters we've been able to go away from

local uh crud storage to firebase huge

what we need to do now is i was we as we

usually do in other chapters is we're

gonna commit our work and also tag it so

i'm gonna do some reshuffling on the

and grab visual studio code here

make the size a little bit bigger kind

of ginormous but that's okay

and let's have a look at our log and we

can see the last step was step 19.

let's do a git status and there were a

lot of files modified nothing new

so i'm just going to say git add all git

let's have a look at our logs we have

step 19 and step 20 now and if you look

at our tags we have up to step 19

up to and including step 19. so let's

as is tradition again at the end of

every chapter i talk about what we have

to discuss in the chapter that follows

we've talked quite a lot about now uh

allowing the user to store their own

notes in the application but

it would be a lot more fun if he allowed

the user to also share those notes with

somebody that they know about

somebody that they know like a friend or

a family member so that's what we're

gonna talk about in the next chapter

sharing notes so i'll see you there

hello and welcome to chapter 38 of this

flutter course in previous chapters

we've been talking quite a bit about how

firestore database and how we can read

those notes back and update them

it'd be really fun also to be able to

share our notes and that's exactly what

we're going to take care of in this

in order to do that we need to use a

plugin called share plus and share plus

mentioned now so it is not a package

where a package extends the existing

capabilities of flutter into new heights

a plugin takes a completely new route

well beyond beyond what flutter

internally can deliver and a packet a

plug-in will need to be developed by

excuse me a developer or a set of

and it needs to be written specifically

various platforms that that plugin wants

to support for instance ios android so a

developer has to go and write some code

for ios for android web etc etc in order

for that plugin to work on those

now here we're going to use the share

plus plugin and the share plus plugin is

developed by the flutter community so

what we're going to have a look at here

so i'm gonna do that right now

excuse me for my throat and in pub dev

we're gonna search for uh share plus

after you've done that you'll see that

you'll end up here and it is by a

fluttercommunity.dev so you can tap on

that and you can get some more

information about the developer here

and you can see that it supports android

ios linux mac os web and windows so what

um so it's a free package that you can

use in your application and you can see

that all you need to do is just to let's

and you see you have to say flutter pop

and that's exactly what we're gonna do

now in our application so i'm gonna

in our terminal and i'm gonna rearrange

actually perhaps i could do the same

thing that we've done before so

let me increase the size of this

terminal so you see it better

so let's just do the same thing that was

mentioned in the documentation so

flutter pub ad share plus so flutter

and this share plus since it's it's a

plugin that you're adding to your

application it's very important that you

basically rebuild your application

because otherwise it won't be available

all right so what you could do is to do

a clean and then rebuilds this is

cleaning is especially important

for ios because sometimes when you add a

flutter uses cocoa pods in order to

dependencies then your build may not

actually be able to pick up on that new

dependency so it is important to do a

clean but for android it's usually not a

excuse me i'm just gonna uh rebuild the

application and see if everything is

working as expected so i'm gonna stop

and i'm just gonna make sure that

flutter select device is using my

android telephone and then i'm gonna go

and it's it says we have some errors so

let's see if we can fix those errors in

okay share plus plugin as you can as i

can see we already have the problem now

in our application so maybe that's why

you have to do a clean so let's go ahead

i'm going to go to terminal and i'm

that's going to clean the xcode

workspace and hopefully it's going to

clean the android as well so i'm just

going to say flutter clean android

do you mean any of these did i not write

oh it's doing the same thing okay

so that's gonna rebuild all our

so there we go now that those errors

have disappeared okay so you may have to

have flutter clean and i was trying to

get away without using that but i was

so in main dart i'm just going to say

run without debugging and that's just

going to take its time and go to

and i'm just going to bring scr cpy to

the screen as well soon i'll just make

sure that i have wi-fi access on this

because i play quite a lot with wi-fi

and hotspots on this android phone so it

could be that sometimes i don't actually

okay so that seems to be running and

here is uh that android phone and i can

see that the flutter application is

trying to run great able to run this and

so we've done that we've done the clean

and rebuild so that's great

the first thing that we're going to take

care of is to disallow sharing mt notes

you see if if you're on a note screen

and you haven't even for instance

written anything in your note you

shouldn't be able to share that note

with anybody because well it's just

empty text in there so let's go ahead

and we need to take care of that

scenario by having a dialogue

and we're going to create this dialogue

excuse me again i've been talking quite

a lot today and that's why my throat is

so let's go to lib utilities under

dialogues we're going to create this

cannot share empty node dialog okay

uh let me change the screen layout a

views we have there and we have

so let's see what we have constant

utilities and views but we don't have so

yeah we have utilities and we have

dialogue so we have to create a new one

let's just say new file and i'm going to

share empty node dialog the dart

and you will remember from before that

generic dialogue so what i'm going to do

so the function signature is going to

look like this as i'm showing you at the

bottom of the screen so let's say show

notes dialogue it's quite a long name

and then it return it requires a build

context so build context context like

okay then what we're going to do in this

our generic dialog and this is something

that i'm actually quite proud of that we

could create and we are using it so many

times now it's unbelievable so we

literally have one dialog implementation

in the entire application and we're just

reusing it and it's truly generic and

so let's in here let's say that we

and it's going to also import that for

me it's inside utilities dialog generic

dialog so you may have to import that

editor doesn't allow you to auto import

so the context is already there for the

title we're just going to say sharing

for the content i'm going to say you

and it's options builder remember it's a

function that should return

a map and in the map we're just gonna

say it has one button that has literally

so this is going to make it a

a dialogue that returns a void or a

future of void when we call it here

okay so that file is now created

now what we're going to do is to go and

add that button as you can see it says

in create update note view add an icon

button to actions of app bar so i'm

going to go to my notes as well and

and let's go ahead and just add that

i can see that we're using a share icon

so i'm going to decrease the size of

this of the font is is very big at the

one more step i i think you can still

see the way it is i mean i can see in

the video output video it should be

visible still even though i've decreased

so let me go here bring scr cpy i'm

let's go to create update note view and

we already have this button at the at

let's see do we have any buttons at the

in our app bar so let's go and create

something called actions in here and you

can see it's a list of widgets and in

here we're just going to say icon button

unpressed we're just going to leave it

empty and for its icon we're just going

and we're going to use icons share

remove this parenthesis from there

like that okay so now now that we have

this icon icon button there if i press

on any of these existing notes then we

should be able to see a little share

button up here at the moment it doesn't

do anything because it's on press is

empty but we're going to program that

so let's grab the current text of our

current node so let's just say that this

is equal to our text controller's text

and we're going to say if note

um actually let's just check for null

or this text is empty then we're gonna

display our new dialogue that we just

implemented so let's just say we await

what's that function called the show

we did it inside the cannot share empty

notes so i'm just going to copy its name

now i'm going to use visual studio code

to do the auto importing for me

so it needs a build context and in here

i'm just going to pass the context and

you can see it's complaining that i'm

using a weight inside an unpressed

function that isn't async so i'm just

gonna make this function async okay

otherwise what we're gonna do is we're

and share it is coming from share plus

and it can be auto imported okay so i'm

gonna just also import that and in here

i'm just gonna say share that text it's

really just as simple as that

so let's go in here and i'm gonna create

you can see it has no text i'm going to

press the share button and now we see

now we're seeing our beautiful little

dialogue that says you cannot share an

empty note fantastic and if i go out

but then if i go to a note that does

have text for instance van dot's second

note or vandal's first note in in here

i'm going to go to van.firstnode and

then if i press the share button then

i'm going to be presented with

in this case android's default share

sheet or how you want to call it and on

ios you're going to be presented with

the default ios sharing activity so

this is pretty much it so we didn't have

to do much more than this it's literally

the call is share.share so you can see

it's so simple when you drag in a

plug-in especially a plug-in that is

from a verified developer especially

from flutter community or flutter team

all right perfect so that was for

sharing there's not much more to sharing

than that and we don't have to drag on

so let's go ahead as this tradition

we're gonna go and uh commit our work so

i'm gonna do some shuffling around here

gonna get rid of scrcpy increase the

and the font so you see better

and i'm gonna have a look at our git's

log the previous chapter we committed at

step 20 and we also tagged as a step 20.

let's just do step 21 in this case

so get status we have quite a lot of new

stuff so if i say get status in here you

can see a new file in here as well

and i'm gonna go and tag it and say step

and then we push our tags as well okay

perfect so that's it so if you say git

status right now we shouldn't have any

what we're going to do in the next

chapter is very very exciting we're

going to delve into a block and

flutter developer from before you'll

know what block is maybe or maybe you've

heard of it and you want to learn about

it so that next chapter is perfect for

you if you're not a flutter developer

from before you may not know what block

is and i'll explain it more however

i'll just at the end of the chapter i'm

not going to go into the details of the

next chapter but what we have to talk

about is how at the moment our ui which

is our different views are actually

working directly with our services so we

have some services that for instance can

in the firestore database and we also

have some services that are like

for our authentication the uis upon

pressing the login button we're going to

the off service and the off service is

coming back with results directly to our

this is working it's fine however

there's better way of doing this and

separating the logic of our ui

from our business logic ensuring that

our ui is doing what is best what it

knows best and that's drawing things on

the screen but when it comes to handling

making api calls and etc the ui

shouldn't really know much about that

the ui should just convey its purpose to

some sort of a layer that we're going to

create in our application with the block

library and that that layer will decide

okay upon this button being pressed i

actually have to do this business logic

i'm very excited actually about the next

grab some refreshments if you want to

and i'll see you there hello and welcome

to chapter 39 of this flutter course

uh in the previous chapter at the end of

the previous chapter we talked about

that in this chapter we're going to talk

this is quite a hot topic for flutter

a flutter developer and you've just been

in your application you may have already

block library and qubits before if

you're not a flutter developer from

before which i actually think the

majority of you taking this course

probably have not been fluttered

involvers from before so you may have

may have not heard about block

uh before so i'm just going to

start this chapter by explaining what

the block library is and why do we need

you see the way that we've created our

application at the moment is that we

have direct calls from our ui code into

our different services in order to

the ui is very well aware of the

business logic so for instance the

create or get existing nodes function

that we have when we actually go and

create a new node that is already a word

of the fact that well if you end up in

here i expect a user to be present

inside the application so a user should

an example of a ui component being aware

of the logic the business logic of our

application so they're very they should

be very separate from each other

so what is block block is a um is a

library that we're going to drag into

our application soon as you'll also see

is a third-party library call i believe

it is created by a company called

and there are various flutter developers

and software engineers that are

constantly working in order to

improve the quality of the block library

which is a dependency that will bring

into our application and using the block

library i mean internally is using

streams and streams stream controllers

and futures the stuff that's already

built into flutter but it's like going

to a next level to make things more

abstract so that our application isn't

directly dependent on its business logic

with the ui inter intermixed

the reason we need the block library is

just to ensure that our ui is only

taking care of the presentation

of the ui and it's leaving the rest of

the stuff to a business business logic

so that's why we need block and we're

gonna use it soon in our application

so if that is blocked then what is

flutter block you see block in its in

its internals is a very simple library

that works with streams and stream

controllers so it allows you to for

instance pass data from here to there

and have listeners that listen to

changes that are happening in a stream

so it's only working with like very low

however when you come to your ui layer

as you remember i mentioned that block

allows you then to separate your

it's taking care of the business logic

using streams and stream controllers and

futures but when it comes to the ui part

in order to glue this business logic

it needs to be able to work with flutter

the part that works with streams and

stream controllers using dart okay and

dart asynchronous components but the

part that it wants to glue that with

your ui needs to come to the flutter

and that is that library in itself is

called flutter block so fl block is

divided into two separate libraries one

is block which takes care of the

business logic etc and the other one is

called flutter block all right

but don't worry about it i'll go through

these with you one step at a time so

what we're going to do in this chapter

it literally has nothing to do with our

application we've been working with the

notes app and in this chapter we're

actually going to break our application

a little bit by just like literally

the home page of our application with a

completely new application is nothing

scary i i promise you the changes we're

going to make is is probably only going

to be limited to the main.dark file

what we're going to do is to create a

counter application if you if you've

worked with flutter before and you've

started thinking about maybe moving over

block you may have actually gone to the

block library's documentation page and

you've seen a counter application in

there where you have a plus and a minus

button and you can increase and decrease

the value that's shown on the screen so

that's like the basic counter

but in this example i'm going to show

you we're going to take that example to

the next level and use the block library

and i'm going to introduce all the

basics of the block library to you in

this chapter but we're gonna take it to

the next level and allow the user to

enter some value on the screen and that

value will then be able to be

added or subtracted from the current

value that the application stores so

it's kind of like a counter application

where the user can actually enter the

value that needs to be added to the

previous account or it needs to be

subtracted from the previous account so

that's the difference between our

simple counter application and what

block libraries counter application in

let me bring up this caption in here and

we're going to talk a little bit about

various components of a block

and i'm fully aware that pretty much

everything i'm saying in this chapter up

to where we get to the example is

very much abstract in that it is

literally just theory i'm like teaching

i personally am horrible at theory like

i didn't excel at school when it came to

theory so i'm very aware that a lot of

you may also have the same um situation

or maybe in the same boat that i am that

are not good with theory and that's okay

i'll just explain these fast and then

we'll go to the implementation so you

can put that to practice so for those of

you who are interested in the theory of

it i'm going to explain different parts

of the block library to you now

component of the block library is a

now block really it is a container just

imagine a class a class that you add

events to it and every event that you

add to it can produce a state so the way

block works is that it it is a class

that begins with a state so its output

is always a state for instance a state

can be logged in a state could be logged

error screen so just imagine different

so that's the input sorry the output the

input to it are your events so

in your block that will develop

inputs that you for instance say log in

with this username and password

register with this username or this

email and password register oh i forgot

my password and here's my email so these

produce and give to your block and then

in turn your block then looks at its own

internals and say oh what was this state

before what is the current event then i

will produce a new state okay so that's

the internal of the block class

now when you have a block class when

subclass from that block class then you

will actually need to create an instance

of that block class and you will do that

using something called a block provider

so that's as its name indicates it is a

it creates a block instance for you and

then it will allow you to do something

a window in here and i'm just gonna

you cannot see my screen right now but i

promise you i will show you soon so

page for the block library so i'll

increase the font size so you can see it

so let's go ahead and you can see it's

sponsored by very good ventures and

medo i'm not sure i i may have butchered

this name right now i apologize for that

parts of block then you'll see let's see

if i can find block provider for you

it could be inside the documentation so

i'm going to go to get started and then

i'm going to have a look at block

package block and let's see provider if

you can find the provider in here

uh architecture naming convention

is there is something uh inside i have a

little bit of a problem right now

provider so let's search for it block

documentation right now to be honest

with you we don't want to look for a

blog provider right here but

as you can see it says it is a flutter

widget which provides a block to its

children so this is how you would work

with a block provider so it creates the

block instance for you and then it will

allow you to return a child all right so

kind of like a builder but not really

so that's block provider and as i

mentioned you can always go to the block

website in order to get more information

about block and read its documentation

so the next component you need to know

what is a block listener as its name

indicates a block listener simply allows

a um i'll actually see if we have a

block listener i can see that we have a

blog listener in this application that

we're going to develop so you're going

to learn about it soon but a block

listener as its name indicates it listen

to changes to the states of a block

that's it so you can do some side

effects so displaying a new screen for

instance or displaying an error message

those are all side effects okay so you

can do that with block listener

now let's have a look at what a block

builder is uses your block state changes

to provide you with a widget so

as we have a block provider um sorry

we talked about block provider before it

gives you uh the chance basically to

a child now inside this child you can

then provide a create a block builder

that listens for changes inside your

block then it allows you to build new

widgets based on those changes so

it's very much like a future builder or

like a stream builder i would say and

we've already used stream builder so you

should know how they work but again this

i'm gonna talk more about these as we

actually build our application okay

after all this we also have a block

consumer and what a block consumer is

that it combine as i've actually written

here it combines block listener and

block builder so a block consumer

listens to changes that happen inside a

block and then it will allow you to do

both a side effect and it will also

allow you to create a widget to display

to the user based on those changes all

and again i don't want to go too much

into details in uh for a theory because

depending on how you learn new things

theory may not be your strongest point

just like it is not for me so it could

so let's go ahead and start adding our

dependencies in our project so i'm going

notes application to the screen

resize it a little bit so we have place

and we have scr cpy right here as i can

see and this is our application

and the application is running currently

then what we're going to do is going to

go ahead and say flutter pop add block

and then flutter pop add flutter block

let's go ahead and increase the size in

here then i'm going to go to terminal

so that's going to do its work

and it added one dependency i'm just

going to say flutter hub at flutter

and this is a package so it's not really

a plugin and i don't believe it's a

plugin i think it's a package so it

could be sufficient for us just to stop

our application in here and just say

that cleans the application that we're

then we're gonna go to our main dart

file and just say run run without

debugging and that's gonna just do the

greater build if you're running on

android or it's gonna use xcode build in

order to build your ios application so

and i'm just gonna let that do its thing

okay now the build is done and i can see

the application running on the screen

what we need to do as the next step is

to do something dramatic and that is to

comment out our home page because we're

gonna replace our home page with another

home page which is gonna use block so it

may sound scary but it's not that scary

so let's go into your main dart in here

select home page as it stands right

there and just comment it out

and we're going to create a new stateful

widget again and we call it home page so

stf and home page the reason this is a

stateful widget is because we need a

text editing controller as i mentioned

how we're going to do this example right

now to learn block is to create an

application that gives you a text field

that you can enter a number into we

in our block so the block holds on to a

number and then when you and then we

will create two events one an increment

event and a decrement event and

give the increment event to our block

then we want to grab the current value

inside the text field so if we start

with zero and then i type five in this

text field and i press increment button

added to the current state which is 0.

so the result will be 5. the next time i

will type 10 then press decrement so

decrement will be 10 and then it will be

5 minus 10 so we end up with minus -5

so that's the ui that we're going to

and for that we need this home page and

the reason it's stateful is because we

need to grab that text from our text

that's our new home page and if i now

press command s in here our screen is

going to be black because well this this

information no scaffold nothing all

so and now let's talk about this

absolute beauty that we're going to call

as i mentioned every block has two very

important properties one is its state

and the other one is an event an event

goes in the block and state is something

that comes out the block and so the

state as its name indicates describes

if you think about it what we expect

a simple integer okay so we could either

say our block's output is integer or we

could define a state that wraps around

that integer so that's exactly what

so let's go ahead and say we have an

and then here we have a final integer

called value and then we're gonna create

an initializer here like that

you could also mark this as immutable if

you want to all right so let's do that

and let me also change the screen layout

a little bit here so you see the code

better so that's like the basic state of

our block okay we're not actually gonna

use the state as it is we're gonna

create two sub states for this as you

since we're going to create a text field

in the middle kind of like this screen

and the user is able then to enter

pretty much any text in this text field

let's just assume so just normal text

not even integer so the user just say

hello world and then presses the plus

button what should we do in that case

plus button plot plus thing like adding

hello world to the previous value of

five means nothing so we're gonna divide

our state into a valid state and an

invalid state and then present this to

the user in two different ways so let's

go ahead and create a class called

as i've mentioned there counter stayed

so i'm going to actually grab that code

so we don't have to type it ourselves as

here we have a counter state valid

extends our counter state which is this

one and we have a constant constructor

that says okay give me a value a valid

value and then i'm going to call my

all right so that's a valid state

now let's then create a an invalid state

i'm going to bring the correct caption

let's say counter state invalid number

in this case we want this state to

actually include some sort of um

the value that actually made our state

invalid so i'm just going to say that

value is a string and we're going to

call it invalid value here okay

and i'm going to say const and let's

just bring a create an initializer here

a few required parameters in here and

like this so in this case we're going to

create two required parameters one is

the invalid value that caused the error

or cause the state of our block to be

invalid and the other one is going to be

a required of the required parameter of

because we may actually need the

or something or maybe like the ui needs

to display that to the user so if this

is the output of our block the state

remember is the output maybe then the ui

actually upon me trying to plus hello

world with five he may want to use this

previous value to populate that text

field or populate the ui again and say

this value that you entered is invalid

but the previous value was this so i'm

just going to show that okay so that's

why we need previous value and here

we're getting an error because we're not

let's call super with the previous value

okay that's our counter state invalid

our two states that uh come from counter

states immutable abstract class

let's go ahead then and create our

and remember counter event is very

similar to state so first we actually

and let's go ahead and define that event

and you can see it's an abstract class

called counter event and it just

contains a value so it just says the

string that comes from the ui can just

go directly into the counter oven that's

and let's make this actually immutable

and what we're gonna do is to create an

so let's go and say class increment

and in here we're just going to say

constructor for it and we just grab a

value in here so a string value and it

should just go to the super that's it

and what we need to do is just to grab

this event as well and create a

let's call this decrement here

like so and again remember the event is

something that we need to trigger and

send to the block from the ui all right

so we're gonna pack these increment

event and decrement event with with the

string that the user has entered in the

ui and then send it to the block as

so let's go ahead now and do the main

part of this application which is our

block and the way to do that is to

create a class if i can spell class

block and you'll see it'll now auto

import it for me because we hadn't

and now let's see if block is imported

somewhere here and that's the package

block block if your editor doesn't allow

you to auto import you will have to do

so the way to create a block is first

you define the state of that block like

what type of state does it have sorry

events first we start with the counter

event and then the counter state okay so

if you look at the definition of block

class itself you can see the two

parameters are or the two generic types

so that's here we're saying our events

are of type counter event and our states

so that's that then let's go ahead and

and what it does is it has to call super

you see and our super actually needs the

every block has to have an initial state

and that's when you pass your super okay

so what we're gonna do is we're going to

say we start with the value a valid

value of 0. so we say const

state valid and we start with 0 just

let's see what happened there

okay so that's the initializer in there

now what we need to do is actually grab

these events as they come remember the

uh basically pass us these events so the

ui is gonna say here's an increment

event with this value here's the

decrement event with this value so we

need to catch those how do we do that

there is a function called on on the

block itself that you can use so we're

going to say on increment value

and then it gives you two parameters so

if you look at the function signature of

on it actually gives you you see it

gives you the event and an emit so let's

and in here we create a new function and

put semicolon at the end so that's how

we're gonna handle the increment value

same we're gonna do for decrement so

let's just copy that and paste it in

all right so what are we doing here now

remember the event that comes in now is

an increment event because we literally

we're we're then going to get that

integer from our events so remember our

is of type counter event and then it has

a value of type string so we're gonna

try to parse that as an integer okay

so we're going to say final integer is

and we're going to say event dot value

like that so and try parse is a function

will try as its name indicates it's

gonna try to parse a given string and

try to make it an integer and if it

can't then that integer is gonna be null

and then we put an else in here

and in the case of an else actually so

it means that hey you gave us something

that we couldn't parse as an integer

what do we do with it all right then

we're going to use our emit

emit is a function on its own you see

it's an emitter that allows you then to

pass a state out your block so i

actually scared myself with my own

have you got your you got your um this

event in now you want to create a state

and pass it out that's how you do it

with emit all right so we're gonna then

if actually let's do integer null if we

we're going to handle the error here

sorry about that so if we got not what

we're going to do is we're going to emit

so the invalid value was this value that

was passed to us in here you see event

so let's just say that's the event.value

and the next parameter is the previous

value and the previous value is always

so let me actually do some cleanup in

here so you see the code better

a comma here so let's see what happened

in here you see we're emitting so we're

sending a state outside our block

so we're saying given an increment event

where the integer where the value

couldn't be parsed as an integer we're

emitting a new state saying that hey

your value which was in this event is

and the previous value that we had is

stored inside our state so your block in

all your on functions you have access to

your current state before emitting a new

one all right so that's the previous

and if we could actually grab an integer

we're going to emit a new value a new

state and we're going to say counter

and we're going to say we take the

current value in our state plus it this

decrement i'm going to remove this comma

by the way it was annoying me a little

bit and decrement it's very similar to

increments so i'm just going to copy

this code and remove this decrement one

and paste the increment one one more

time and then this time i'm just going

to change it to decrements like this all

and for the big decrement the only thing

you have to do is just to change this

wow a lot of work a lot of work so

now we've basically gotten the block

down so the block should be working as

so let's now go into this homepage that

we created in here and create our text

so for that i'm just going to say

text editing controller and we're

calling it controller as i can see here

let's go into init state and override

also the dispose function okay

i'm gonna bring the code so you can see

in in its state we're gonna instantiate

our controller so this is nothing new

you've already done this before many

and in here we're gonna dispose of that

uh fantastic all right that part is done

so what we need to do now inside our

build function we're gonna basically

our main ui so i'm gonna bring the

caption for that as you can see we have

to use block provider and block consumer

so in the build function right now we

only have a container so let's instead

of doing a container say okay we want to

create a block and we also want to just

like make sure everything after this

return statement has access to that

block so we need the block provider so

provider and block provider is in a

flutter block package as you can see

here and we haven't imported that yet so

parameter we get a context as you'll see

i can get visual studio code to complete

this for me it says i will give you

context and you'll give me a block back

so i'll say okay i'll take the context

and i'll create a counter block here

so that's the first parameter then we're

getting an error here just because we

haven't provided a child here so if i

and press command s then we see hello

world right there okay so in here our

task then is to create a scaffold so

let's create our scaffold just we

let's create an app bar in here and say

can't see anything because the

documentation is all over the place cons

text and i'm going to say testing

all right so now we have a blog provider

that created an instance of our counter

block and then we have a scaffold with a

beautiful app bar displayed on the

so as the caption at the bottom screen

uh our child the child of our block

provider is a scaffold but inside the

scaffold itself we have body

and for the body then we're going to

create a block consumer so remember a

the combination of a block listener and

we need a block consumer here is and the

reason for that is upon every

pressing of the plus or the minus

buttons that we're going to develop soon

we want to clear the text inside of our

by us saying that okay whenever there's

a new state coming out of our block we

want to clear something so this is a

signal when you want to do a side effect

that has nothing really to do with like

then that is your listener so

so we're saying that we need a block

listener but also we want to for

have a builder so we want to build our

ui based on the current state of the

well that is block builder so if you

need a block listener anywhere in your

application and a block builder you need

to instead use block consumer if you're

if you need them at the same level okay

so block consumer combines block

listener and block builder so that's why

we're using block consumer in this

block consumer it's going to say okay

what block am i operating on so i'm just

going to say you're operating on counter

block and then it says what state am i

operating on and we're going to say

let's see if they're available counter

and you can i mean i'm not making this

up this stuff is present in the

documentation if you go to block

let's see in here what it says it says

uh extend state state streamable so

the b here b for me means the block and

s is the state so it's not so clear

because it's working with a lot of

generics but you can read the

documentation about that okay

so let's go in here and in here let's

and it's complaining that some named

parameters aren't present as you can see

named parameter listener is required so

let's go ahead and say listener

and i'm going to get visual studio code

to help me clean this up and upon any

new events or sorry upon any new states

produced by our blog i want to clear our

text editing controller so let's just

what do we call it do we call it

yeah so we're going to say controller

clear so we're going to clear the text

that is displayed inside the text field

then we need the builder function so in

it will give you the current state and

you need to return a widget back okay

so what we're going to do in this

in this is first we're going to grab

to see if there's an invalid value so

let's just say final invalid value

is and we're going to say if this state

with a question mark so we're using

turner here and we're going to say get

the states uh let me bring the code up

if i then in here say invalid value as

you can see it's now a string okay

and the reason behind this to be honest

the a little error message to the user

should there be an invalid value so if i

have if i have entered some information

in the text field instead of a number

i've entered hello world and then

our block produces a counter state

invalid number we're going to display an

error to user and this error is gonna

disappear the next time actually the

user enters a valid number in the text

field okay so we're gonna use a new

widget that we haven't used before

called visibility and this visibility is

gonna be based on whether there is an

you'll soon see actually how we're gonna

let's go and as our builder's main like

okay and column has to have children all

what we're going to do is to first

display a text field sorry a text in

and we're going to say current value is

all right so that's going to be the

state and if i do command s you can see

that it says current value is 0.

so that's the current value then what

we're going to do is to go ahead and

visibility widget which in case the

current state is counter state invalid

number is going to display an error

message to the user so let's say we're

going to control the visibility of that

error message using the visibility

and it's childband is going to be

invalid inputs and then we're going to

add the invalid value in here as you can

see as we've constructed that up there

and the visibility flag you see we have

to return a boolean okay so how do we

with visibility and that is if you can

grab hold of your state and say okay

this state is actually counter state

invalid number so let's just say state

is counter state invalid number just

like that okay so that's how we grab

and you can see at the moment it's not

displayed all right even if we even if

and then save it and you'll see now it

says invalid input so it's just

displayed right there okay but if you

say state is then it's going to

disappear because the current state is

okay that was for visibility now let's

so where the user can actually enter

some information in the ui so let's just

as the first parameter we're going to

and what we're going to do is we're

going to give it a hint text so let's

say decoration is a const inputs

like that i'm going to put the code a

little bit higher on the screen

so for the hint text i'm just going to

like this okay and also let's just

all right but also remember if you

the controller has not been initialized

really i thought we initialized the

yeah maybe you have to do a hot restart

there we go so now we have enter a

great stuff now all right this is what i

was going to say even though we have a

text field here and we actually said

that the keyboard should be numerical

but i can still paste non-numerical

numbers in here so if i like use the

paste functionality in android or is so

that's the reason we have that invalid

state in case someone else someone

actually enters another value except for

a number and there are also input

formatters in flutter that you can use

avoid users entering non-valid values in

your text fields but that's a whole

other subject that we're not going to

then what we're going to do is we're

going to have two text buttons for

increment and decrement so let's after

this text field create a row so

a row is like the opposite of a column

whereas a column displays those

components vertically one after one

after each other a row creates its

components horizontally from left to

right and left speaking languages and

speaking right side speaking language i

i think actually row changes it's uh

it should at least change is uh

how it arranges components based on the

language but i'm not quite sure about

so let's say row it has children

and it's two text buttons okay

that have unpressed at the moment empty

it's a child it just says cons text just

minus like this okay so that's first

and then for the next one i'm just gonna

copy this text button and i'm gonna

paste it right here and in here i'm just

all right so in here when the minus

button is tapped i want to convey this

information to our block so i want to

say grab the controllers text and make

sure that you send this increment

increment event to the block so we kind

of need to grab hold of our block

how do we do that the way to do that is

using a convenient function that

very good ventures have created on

and in here you can actually say i want

to read my counter block like this okay

so this gives you access to your block

that has been created by the block

so let's go ahead and in here let's say

after we read that we want to add a new

event to it like this and we want to add

an increment event that has the value of

this is how you send events to your

block and the same thing since we're

actually sorry about that this should be

decrement so let's just say decrement

like that and we copy the same code and

we bring it to our increment function as

unpressed button here and instead of

decrement then we're going to say

perfect okay so let's see now let's test

this application so at the moment we

have current value zero now if i press

the plus button as you can see it says

and press the plus button you can see

the value of 2 is entered there if i say

i press minus and it says oh invalid

input hello world is invalid and as you

can see it clears this text and that's

because of this listener here

uh this listener because a block

consumer is also block listener remember

so it's a combination of a block

so that's the clear working and the part

that is handling this invalid input is

this thing so visibility if the current

state is an invalid number then this is

becoming visible but if the current

state is not an invalid number so let's

it's going to be three six then the

current state is actually not an invalid

valid it should be counter state valid

so then the visibility is hiding that

so that is pretty much it i mean um

huge congratulations if you could stick

with me throughout this chapter it was

very heavy i understand it was a very

heavy and very like technical chapter

talking a lot about business logic but

believe me if you didn't understand like

most of the things i talked about you

i'm no genius nobody who knows how to

work with block or stuff like this is a

genius everybody has practice put it

into practice done their own

applications done this test just go and

create this counter application that i

just created try not to look at

the code that i've written or rewritten

remember the stuff from your memory and

after exercise and practice and practice

and practice and you will get it and you

will get the idea of what a state is

you'll get the idea of what events are

what block is and read documentations

and you'll get this eventually i promise

as is tradition we're gonna now uh since

we're done with what we prom promised in

this chapter we're gonna go and commit

so let me change the screen layout a

terminal and increase the size get rid

and let's have a look at our log

chapter we committed step 21 so let's

and there were just a few things changed

so let's add everything and just say git

and then i'm just going to say git

a tag to see our last tag and i can see

so let's tag this as step 22

there we go so now step 22 is also

what is to come this is also a tradition

we have at the end of every chapter

we'll talk about what we're what we need

to discuss in the next chapter and what

we need to discuss in the next chapter

is and we will convert our auth process

we've now talked we've act we actually

logic inside our application and that

was our auth service i don't know if you

but we need to convert this auth service

and uh so in that way we're actually

putting our knowledge about block into

use and combining it with what we've

application better and our logic not so

spread around everywhere in the ui so

if you want grab some refreshments tea

or coffee and i'll see you in the next

chapter hello everyone and welcome to

chapter 40 of this letter course in

previous chapters we've been talking

our aus process and also storing um

users notes into a firestore database

and in the previous chapter we also

talked about block so um i'm very aware

that block could be an intimidating um

topic for some developers and that

getting started with block could just

be conceived as like an extra step that

however i can assure you when you get

more into professional software

and which is which may not be your goal

i completely am aware of that but when

you get more and more to professional

software development you'll understand

various layers of your product and that

the um the presentation layer where

you're taking care of for instance

displaying stuff on the on the screen to

the user shouldn't really have to talk

with your authentication directly um or

for instance your authentication layer

doesn't necessarily have to depend at

all on other parts of the application so

in a very clean and concise way to

separate the various uh layers of your

application into their own concern

layers so and the services are going to

be only concerned with services and then

your ui is going to be only concerned

with ui and so on so and so forth so

um it could be beneficial if you could

actually before starting with this

chapter to go to the previous chapter

and maybe watch it again or maybe even

practice yourself with block

um i understand i know for sure that the

block libraries website as we looked at

in the previous chapter they have quite

a lot of examples and i highly suggest

that you go through some of those

examples at least and develop and

implement those examples also yourself

to get a bet to get a better hang of

what a block actually means and how

if you've taken care of that and you

understand like the basics of block

then we're we're we should be good to go

so let me bring up the caption for what

we're actually going to do in this

chapter you see the way we have our

application at the moment is that we

authentication service and our

authentication service let me just bring

and let's have a quick look at it so if

auth service you'll see that we have

function functions in here we have

and we have uh we are exposing the

current user we have login logouts and

email verification and initialize

now this is all good however we are it's

very raw the way it is in that the ui is

our auth service which in case which in

a provider which is our for instance um

firebase provider author provider so if

you go in here you'll see firebase auth

provider and that is talking directly

in a way you could say that the ui is

talking pretty much directly with

firebase it's just going through some

functions to get to firebase but that's

what pretty much it's doing so

what we want to do in this chapter is to

make sure that our authentication is

behind a layer of block meaning that all

the logic that has anything to do with

authentication is hidden behind a layer

which we're going to call off block

so that's going to be our off block so

it's like the and as you remember from

the previous chapter every block has two

what comes inside the block so what's

entered and what is the output

the input to your block are your events

so you pass for instance your ui upon

you pass an event a packaged event that

we call our auth event you're gonna pack

package that up with any parameters that

that particular event is required it is

required from you you take that event

and you give it to your auth lock then

your off block is then gonna have some

time to process you remember

we have these on function functions on

your uh off on your blocks when we

talked about the counter block we had on

increment event on the command event etc

so these are the events that come in so

we're going to package those events up

from our ui and pass them to our off

block then our off block is going to

have some time for itself to process

those events and based on those events

it has received and based on its current

state it's gonna either output the same

state or it's gonna output a new state

events come in and states go out and the

off block sits in the middle so event

off block and estate and these are three

components that we're going to develop

take care of our state and remember

again state as its name indicates is the

state of authentication either you're

logged in or you're logged out okay and

you could also be logged out with an

error remember so you're either logged

we're going to start looking at these

off states so what we need to first do

is to create a file as the caption

under lip services auth block off state

let me do some reshuffling on the screen

maybe decrease the font size a little

bit because it's just ginormous the way

it is right now so maybe this font is a

i'm going to put visual studio studio

to the left and then i'm gonna bring scr

okay so i'm gonna close all these tabs

that i have right here how we left the

application in the previous chapter and

let's go ahead inside lib let's let's

see actually what we have in here we

have lib and we have services

and under services we already have auth

but we don't have a folder called block

at the moment we have auth provider etc

so let's go in off and just create a new

slash auth state state like this dot

now if you remember from the previous

usually states are immutable and that

they're also they're like at the generic

states that every other state in your

is usually an abstract immutable class

meaning that it is a class pretty much

almost with no logic at all it may have

in and on itself it does nothing so it

just is dictating that hey every state

that comes out of this off block is of

let's go ahead and create our off state

so maybe i should actually increase the

so we're going to start by writing um

states as you can see so we're going to

code that in auth state.dart file

so i'm going to go ahead and just say

abstract class auth state okay

and let's just create a constant

constructor for it as well in case one

of our states needs to also have a

constant constructor so this is this is

a pattern that you may have already been

by creating abstract classes and if you

have like sub classes that conform to

your abstract classes and those

subclasses actually want to have

constant constructors then you need to

have a constant constructor in your

abstract class as well so that those

subclasses can actually call that const

constructor in the abstract class

otherwise you won't be able to have

constant constructors for your

subclasses so for instance if i say

extends off state and if i say const

blah like this you can see it says a

constant constructor can't call a

non-constant superconstructor and that

is the reason that i usually create a

classes for states and for um the events

okay now we have our abstract class off

state now let's go and make it immutable

and for that we need to import material

or actually it is foundation let's

import from foundation in that case and

we could just say show immutable

can we do it like that yeah that works

so that's that we have a generic off

state so um actually i don't mean

generic in terms of like a dart generics

which i just mean an abstract class that

every other off state can conform to

low i mean we have quite a few states so

i'm just going to start doing and doing

and creating those off states one at a

while you're authenticating for instance

you've just opened the application and

then we need to basically tell our

authentication um provider which is

firebase to initialize itself while it's

doing that then our auth state is in the

state of loading or initializing

whatever you want to call it but we kind

of need have to have a state that

indicates to the application that hey

something is happening with the auth

process and it is in the in the process

of loading so let's go ahead and define

that so let's just say off state loading

extends off state just like that okay

and this could also have a const

constructor so let's just say like that

that's the state of loading and we can

actually use the state of loading and i

believe we're actually going to use it

while the user for instance is has just

opened the application and the

applications is initializing

and we can also use it for instance when

you tap the login button in order to log

into the application and we're

communicating with firebase and that is

also a state of loading okay

so you will see soon now these states

are very important how the ui then

reacts to various events that are or

various states that are happening in our

we have the loading state let's just

define a a logged in state so when the

user has already logged into our

application then that is its own

separate state so let's go ahead and say

and it extends the off state

this is important to see okay when

you're logged into the application what

does the application actually need from

us well the only thing the application

needs from us when you have logged in

with the user is the current user at the

moment we are going to our auth provider

and or our auth service and grabbing the

current user but if we're gonna move

over to block and like blockifying our

entire auth process then it makes more

sense for us to grab the current user

that has logged into the application

from the current state of our auth block

it's it's i mean to me it's really

it makes sure that we can separate

the auth service and the auth provider

from the ui by putting a block in the

it may sound like you're blocking the ui

but that's not how block is written as

but that's that's what we need to do so

let's just say we have the final off

user and it's going to auto import it

for me if you're using vim if you're on

linux and or if you're using subline

that it's not able to auto import things

then you'll need to auto you need to

import off user yourself okay

so let's say that a state of logged in

or always carries with itself the

currently logged in user okay so we're

just going to say user and i'm going to

create a constant constructor then for

this class as well which in turn is

automatically for us on off state okay

so that's our state of logged in

now let's say that we're going to define

a logged out state and but also we want

actually before we go to log out maybe

we have to talk about talk about login

when you're trying to log in a user in

our application today if we go to our

login view you'll see that upon pressing

the button to log in then we're doing a

try a weight of auth service firebase

login so we're literally going towards

firebase directly and then if anything

goes wrong then we're doing like a user

not found off exception wrong password

off exception so we're handling our

exceptions in this way and the way that

we need to do this now with uh fire with

block is that we need to produce a state

you see the ui needs to only talk with

that block so it says hey block here's

and then it says and then a blog is

going to do some processing and then

maybe it says oh incorrect user

or password is wrong or whatever so that

needs to be its own state so

an exception has occurred during login

that is a state login failure we're

going to call it login failure so the ui

is then going to react to that

particular state in order to display for

instance an error message to the user

and we're going to extend our off state

in here and what we're going to do is

a login failure we need to carry with

that state the actual exception that

caused the failure so let's just in here

say exception exception just like we're

doing we're carrying the user with us

when you log in we carry the exception

with us as well if you couldn't log in

okay so that's how you should think as

well so your state should carry with

them all the information the ui or the

consumer of that blog requires in order

so in this case upon not being able to

the ui is going to require the actual

exception that occurred so that it can

switch on it or do some if statements

and see what kind of exception it was

and display the correct correct

so let's go ahead and then define that

and since we've expected an exception in

here i'm going to create a constant

oh actually we got a warning here it

says prefer declaring cons constructors

on immutable classes that's actually

beautiful yes sorry constant fantastic

okay so that's our login failure

then what we need is you remember also i

mean at the moment since we have our

counter block uh in here and the counter

application that we did in the previous

chapter i can't show you the ui of the

application but if you can recall what

we also had is if you try to log in with

a user and that user's email is not

verified when they were actually gonna

what we are what we were doing is that

we were sending the the user to the

needs verification view or something

that we call it let's say let's see very

verify email view right so we sent the

user to this view and we need to also

we need to also produce that state so

upon user pressing the login button and

if our off block realizes that hey this

user does exist but here she hasn't

verified their email address then we're

gonna produce a state telling you ui

that hey this user needs to verify their

let's go ahead and implement that so

and then here we're just gonna grab this

as a cons constructor like this all

and also after doing that so now we have

login and login failure we have needs

verification and we have the loading

state if we're in the middle of for

instance making an api call that could

the other state that we need is also

logged out if you're in the log out

state then we need to produce that so

let's just say class off state um

and this is going to extend offset as

let's then make a constant constructor

for this like this great all right

so log out when you're logged out you're

logged out there's nothing that the

logged out state actually has to carry

with itself it doesn't have to carry the

currently logged in user or anything or

even the current user in firebase even

if even if you have anonymous users the

logged out state for our application

doesn't have to carry with itself

and last but not least we also have to

define our logout errors and so upon

encounter some errors like if if

a firebase for some reason is trying to

make an api call and that api call

doesn't succeed then it is going to give

us an error so let's just define that as

well let's just say class you see we

have that already for login failure

let's go and actually copy that and

and here instead of login i'm just going

to say log out failure and copy that

name and put it in the consonant

off states so that looks actually really

so our auth states are now defined okay

we need to define the inputs you see the

states have been the output of our off

block which we're going to write soon

the off block we haven't written it yet

but these have been the outputs now what

are the inputs imagine in our off inputs

we have to think about what the ui what

the ui is actually going to call so

the ui is going to send packages of data

to this off block and these packages of

data are the events so we need to make

can contain with them the data that the

ui can package and send to our off block

for instance during logging in what

event is it okay it's let's just say off

event login what should it contain well

it should be the email and password

something like that okay upon log out

okay that's a log out event what should

no it's nothing it's just a log out

event it shouldn't even provide the

email and password it should log out the

currently logged in user from the

so we need to think about events and

their consumers and also the states and

their consumers so you have to pack

enough information both into your states

so that the consumer of your blog can

actually both receive enough information

and be able to pack enough information

okay now what we need to do is just go

and define our auth event right here in

lib services auth block off state

we have written our off state so i'm

just going to close that file and let's

go in the same folder called blocking

here you see lib services auth block

we're going to create a new file called

auth event so right click new file off

all right and now we have our off event

and we need to do something very similar

to what we did with off state in that we

a super class an abstract class that

engulfs all other um auth event so every

auth event in our application is going

to be of this type so let's say

immutable and we don't have access to it

let me just write it for now let's just

and a constant constructor which you now

an immutable comes from foundation we've

already done this so import immutable

sorry i programming quite a lot of

languages python and rust and swift and

you name it javascript so it's sometimes

a little bit messy in my head about

there are quite a lot of different ways

of important things in different

languages so i sometimes mix them up

and so now we have our aus event

which is an immutable abstract class so

now what we need from the ui is upon it

wanting to initialize our auth you see

at the moment let's see actually what we

main dart file this is just us having a

and that's that's the counter block but

how we had it before is if you remember

in our home page we had upon the entire

home page being loaded we were saying

auth service firebase initialize so this

is a signal from the ui that needs to

now go to our auth block and say hey

let's define that signal or event

let's say auth event initialize

and it has no parameters it's as you saw

in main darts it's literally just a

function being called so we're going to

represent it with an event that has no

parameters but it has a constant

that's that's that okay we have now our

what we also need is an auth event for

logging in and as i mentioned it's very

simple it's just with an email and

password so let's just go ahead and say

of event login something like this

or log in with a capital i extends off

and we need we need two parameters to be

passed in here let's just say final

and we also need a password so let's

password and now we have the email and

password we're just going to create a

constructor here and make it constant

so now we have our login event

and so login event should carry with

itself every piece of information that

the auth block will need in the future

in order to log in that user into the

into our provider which in this case is

so after defining login we also need to

define log out now if you have a look at

there are so many files in here so views

and we have notes and then we have

excuse me we have notes view if you have

a look at notes view if you have a look

at this and log out what it's doing as

you can see it's a weight of service

so this is a clear event with no

parameters it's just telling the off

block then or in this case the off

service that hey you need to log out no

parameters log out the current user okay

so let's go and define that as well in

here so let's just say class

event log out extends off event

and it has no parameters as i mentioned

so let's create a constant constructor

for it which in turn is going to call

the constant constructor of the abstract

all right fantastic those were the only

events that we had to define initialize

login and log out so these are the

inputs to the block and then we had our

auth states which are the output our

outputs of our off block which we're

so we have the events and the states the

only thing that's missing is the

uh auth block itself so let's go ahead

inside this block folder create an off

now we need to actually write our auth

block and this is for me at least this

because we're going to put together

three pieces of uh two pieces of

information the states and the events

and now we're creating the actual login

the logic of our authentication block so

very exciting so let's say class

off block like this extend block now

it's going to complain saying that well

so let's go ahead and import that import

that as you can see here now remember

block if you go into source code it has

two parameters there's two generic data

types in here event and state

our events are called off event and it's

going to auto import that and then we

like this which also is going to be auto

just like our off service if we go back

to our off service in here you'll see

that our auth service at the moment is

taking in as a parameter a provider so

we're going to do the exact same thing

in our auth block it's going to say

give us a provider to work with is it a

firebase provider or what is it

but we're not gonna directly go and say

give us a firebase provider we're gonna

say give us an auth provider remember

that we had an abstract class called

the logic or defines the interface for

every auth provider whether it's a

firebase auth provider gmail auto

that's how the interface should look

like okay so what we need to do is to

a constructor and in here what we're

going to say is to give us an auth

we expect an auth provider auto import

okay so if you're getting errors here

it's because you have an imported off

provider the way visual studio code just

imported it for me right now

that we call the provider in our

constructor and if you remember

correctly from the previous chapter we

need to also make sure that auth block

that's what block as a super class

requires so let's see you see that's the

of the block libraries block class that

says it should have an initial state so

our initial initial state is going to be

in the k in the state of loading so

let's say off state loading

okay so and i can see right now that i'm

not using scr cpy so much so i'm just

yeah i'm just moving it to another

so we don't get bothered by it and that

enables me then to increase the size of

visual studio code in width so it's a

so i'm gonna go create a constant here

and then we're gonna create our curly

brackets in order to go to the actual

initializer or the constructor of this

all right now your job in here inside

the auth block is to actually handle

various events and then based on those

what is the first event remember this

event initialize so if the user tells us

auth block what should we do well we

should go to that provider and actually

so let's go ahead and do that so i'm

just going to say on off event

and remember every on function you see

the event let's see actually yeah it's

the event and then an emitter it's not

it's quite generic it's i would say it's

but that's that's the way it is so we

take the event that came in so in case

you need to extract some data from your

in this case initialize is an empty

class so it has no data but it when we

actually start loading for instance and

we start handling the login event we do

need the events to actually come in so

that we can extract this email and

password okay but in the case of event

initialize the event is pretty much

useless so we could literally ignore it

by just doing something like this okay

but we're gonna take it in anyways

so now that we have that event we the

second parameter in here is called emit

and emits then allows you to um

actually emit and send states from your

off block out to whoever is watching

the stage changes in your off block

which is going to be our ui okay so emit

is your way out is your communication

so let's make this function asynchronous

gonna call our provider and call some

asynchronous functionality on it so

let's go ahead and see if we can do that

so the first thing that we need to do in

here is to call our provider and say

and initialize you can see is it returns

a future of void so i'm just gonna wait

on it all right so then what we're gonna

do is to say okay after doing that we're

final user is provider current user and

that is an optional off user if you

remember from its function signal or

from its getter signature you see

null after doing an initialize then we

know that the state should be logged out

it means we initialize the provider but

there is no user you are logged out okay

so let's just say if user is null

then we're going to emit a new state and

we're going to say auth state logged out

so now we have a user we're sure that

we're not coming into this block here

that says auth user is null if there is

a user but that user is not email

verified then we're going to produce

is email verified not so it's not email

verified then we're gonna emit

okay so that makes sense as well

otherwise we're going to say where our

state is bought state logged in and

remember the logged in state actually

um that is actually working quite well

that shouldn't really happen because the

so we have already checked the user so

we could put let's see what is it

user value of type null can't be

assigned to a parameter of auth user in

a cons constructor try using a subtype

or removing the keyword const and

i mean i understand this part to be

honest with you and that's correct

that's a mistake that i've made in here

and that's because i said a constant

constructor is being called with a user

which is a variable so you should also

know that we can't do that all right

because user in itself is not const

hence we can't call a const constructor

on a on a state that uses a variable

now we've handled the initialize events

what we need to do is to handle the

login event so let's go ahead after this

i'm just going to put a comment in here

initialize just to make things a little

bit separate from each other and then

i'm going to bring the code up so you

see it sorry about that it was a little

bit hidden when i wrote this comment so

now you can see how it looks like

then we're going to handle login events

so remember again an event is something

that the ui is going to send us and that

event if you remember it has a username

sorry an email and a password then we're

going to unpack that email and password

provided to give it to our provider and

provide it to our provider give it to

the provider and then react to the

various results that come back from the

so we're gonna say then on off event

login oops yeah login and we're going to

and we're going to say this is an async

function and it goes in here all right

now this is the beauty of a blog using

emit you can let your consumers know

let's say someone says login what is the

first thing that we're up to yeah we are

loading we are in the state of loading

because we are going to start loading

and make api calls and that's exactly

why we have these off states in here

remember we have the auth state of

loading so let's change our state as

soon as you tell us to log in we're

going to say oh now we're loading okay

because we don't have a state that says

but we have a general state that says

if you want to you could remove this

i have a class for instance auth state

logging in that's also acceptable but

uh state for everything like even if

you're logging out you should say off

uh so then you have to have a loading

state for pretty much all the states

that do something asynchronous

and that's why we haven't done that we

have a generic or a general loading

state that indicates to the outside

don't worry about all these saved

operations that have been in this off

state file i pretty much i mean i didn't

change anything in this file okay so it

is how we left it when we finished off

all right so let's in here then emit a

and upon logging in what we need to do

is just to grab the email so we're just

going to say email is equal to the event

email and password is equal to the event

so we're gonna say await provider um

i believe we have let's see what the

let's then create a user so let's say

final user is equal to provider dot

we have a login function on our provider

and here we're literally passing email

and password to that function okay and

remember login function at the provider

throw an exception but that's fine

because we have a catch in here so if we

go to the login function in our auth

provider let's see if we can find

inside the login function let's see if

we can find out here we have various

exceptions that are going to be thrown

user not found wrong password generic

auth exception so if any of those

exceptions happen we're going to come

into this catch block all right

if nothing happens if no exceptions

happen then we're going to emit and

we're going to say const or actually we

can't do a const because a user is a

variable so we're going to say auth

and it's just going to say give us a

should any exception happen we're going

to emit a login failure and we're going

what's it failure login failure i can

and in here we literally pass the

can't be assigned and then so we

probably just have to see i can i mean i

understand this exception as well it's

because exceptions in dart maybe this is

side talk but exceptions in dart can be

anything i mean i posted something on

linkedin on twitter a while ago saying

an enum value as an exception and that's

dart exceptions are of type object and

in this case i believe they're even

object optional object no it's actually

an object so here the error is that

you're saying that off state login

failure that needs an exception but

you're passing it an object so let's say

and that's because we know that our

login function is not act let's have a

look at the login function and see if it

can throw anything other than an

exception and we see now that it has a

block which throws a generic auth

exception which in turn is an exception

so in our application right now as it is

we're not throwing anything that is not

an exception so every exception is

coming from the exception class

fantastic now we have our login um

event in place and we're emitting the

correct states logged in or login

failure now we have to handle log out so

let me bring the code up and we're going

to say log out and this is very similar

to login a little bit less code so let's

again we're going to handle inputs okay

event log out so if someone tells us to

like this then we're gonna say okay we

take the state oh so much documentation

and then the emit and then we make this

function asynchronous like that

and the first thing that we have to do

since in log out we're going to call the

logout on our provider which is an

asynchronous function we need to tell

the ui about that we need to tell the ui

log out from the off block you have to

do some loading what better way of

indicating that to the output to the

outside world by actually changing our

state using emit so we're going to say

off state loading okay so that's us

indicating to the outside world that

all right so uh let's then do a try and

if an exception occurs then we're going

off states failure we had a log out

failure and that expected an exception

so i'm just going to put the e in there

we could also put this image in try it

doesn't matter because this doesn't

really throw an exception it can never

but we're going to put it in try catch

because i believe just it's a little bit

cleaner it's it's like a transaction

so what we're gonna do is to say await

and log out in here all right and should

the logout actually go through then

we're going to go to the next line which

is line 40 for me maybe another line

and then in this case we're just going

to emit a const of off state

that was it really i mean it was just a

lot of talk a lot of creation of like uh

but um we've now gotten there so now we

have an off block and then we have our

auth event and off state so now that we

have those i'm going to close those tabs

after you've saved them so make sure

that those files are also saved

then what we're going to do is just to

get rid of that ugly counter block that

we created in the previous chapter which

dirtying down our main user interface so

home page the way we have here let's see

so let's go in this new home page that

we created for our counter block and

just completely remove that everything

that is related to that counter block

and then let's go ahead and bring back

we have flutter block and block in there

and that is causing a little a

little bit of a problem but that's okay

so what we need to do now is to actually

captioning here as you can see now we

need to use block provider and block

builder and we're going to do that in

jumped over the previous chapter because

i talked a lot about in the previous

chapter about block providers block

builders block listeners block consumers

and what they are how they're different

from each other and there's a lot of

information and material available

online that you can read also

about all these things online but if

you've skimmed over that chapter and

didn't understand really how things

worked what we need in here just think

of it that our main application needs to

offlock the auth block is responsible

now from this point on to handle

everything related to authentication

not the ui part remember the ui part is

completely separate that's the goal of

block in its core to separate business

logic from presentation logic so your

presentation logic everything related to

the ui for instance displaying dialogues

displaying exceptions handling etc etc

etc that's all in the ui has nothing to

do with all of what but the off block is

going to be responsible for actually

initializing the authentication process

and also with with firebase and also

allowing us to log in and log out et

we need the auth block so how do we get

off block in our main application since

the entire application is dependent on

the auth block even when you're in the

main ui of the application you should

still be able to for instance log out

then we could literally say that oh

everything inside our application in the

main function is gonna be dependent on

that off block so what we're gonna do is

let's see in here here we're right now

saying we have a home const homepage you

see actually let me command s this and

bring uh scrcpy bag back here

back so home page is fixed now

so what we are going to do in here we're

going to instead of a const homepage

we're going to replace this with an auth

we could do this as you can see we have

um do we have sorry with a block

i have the block extension in visual

studio code which then gives me the

ability to wrap things with various

components and flutter block components

and you can go to extensions and install

extension for visual studio code

if you're if you're using another uh

development environment if you're for

instance using sublime you may not have

what you'll need to do is to write this

by hand so i'm gonna take advantage of

wrapping this homepage with a block

my home page now let's see here

let's say this is a const as well

home page before its creation is

dependent on the creation of a block

so let's go in here and say the block

provider is also using our off block

which i believe now visual studio code

is going to auto import you may need to

import that by hand if you are not using

visual studio code or an or text editor

or an id that has this feature

parameter of our block provider we

actually have to create the uh block

that we promised we're going to create

and you can see that being created here

and i can now see directly in here it's

but we can't have that simply because

our auth block if we go back to our off

block in here i believe that our

constant so if you put const in there

you can see that it's not allowing us to

block itself as a library as a class

here it has no constant constructor so

we can't have a constant provider so

let's remove that const from there okay

now in here we have to say it should

requires an auth provider so let's go in

fire and that's going to be auto

block provider that's fantastic so

now what we need to do is to have a look

in here and see what else we have to

what we have at the moment i mean we

of course we have this functionality

auth block for us in the main function

but we're not actually really using that

in inside here we're using future

so what we need to do is instead of

using future builder let's use our um

what we're going to do is we're going to

i'm sorry block builder and block

builder is kind of like future builder

but it's going to use but it's going to

which is defined here now this may seem

all very complicated to begin with and

what you need to understand is that

there is a lot of magic happening behind

the scenes in block in that when you

create a block provider in here and then

it gets a context and then it goes here

to create the block what's happening

internally in block is that that context

itself is gonna get injected with your

off block so when you create the auth

login here this context from this point

on inside the entire application is

it's going to be populated with an auth

block that you can read from okay and

so in the build function of your

homepage what you need to do in here

see we have this future we have the

let's just then go ahead actually what

we need to do to be honest with you is

we're not going to use so much of this

code so it's perhaps makes more sense

just to shift it down a little bit to

so in uh sorry a block builder

so our block builder has a builder

function but we also are going to get

actual block in here in the block

when you come to your home page what the

first thing that we need to do is to

tell our os block to initialize itself

do you remember our auth block has this

um event handling for initialize so

somehow in this build function we need

to tell our author like hey

initialize yourself so how do we get

i talked about this how do we hold off

how do we get hold of the off block in

here since we don't have access to it

here but i just mentioned that

when you create an auth provider sorry a

blog provider that blog provider is

going to inject your off block into the

context so the the auth block is hidden

somewhere in this context and the way to

read that is you just say context dot

read and then there's a you see there's

function in here and if you go into this

read function you see it actually comes

flutter provider provider dart okay

so in context read let's just say that

and what we're going to tell it to is to

tell it to initialize but if you put dot

in here you see there is no function

called initialize or anything and that's

because the way you communicate with an

auth block as we saw in um or the way

that you communicate with a block

generally is that you send it messages

using its add function so add is your

way of communicating with your block or

your blocks about various events that

you're sending okay so in this in here

we're going to say add and then we're

if you're getting an error about this

auth event initialize not being in

context it's probably because you don't

have an auto import for this uh file in

we have now we are sending initialize

now that that is done we need to do our

block builder so in this builder

function let me go here and get help

from visual studio code to complete that

and you can see now i get a context and

so let's go ahead and handle various

states that could happen during this

period during the initialization period

if the state is off state logged in so

if we are actually logged in then we're

gonna return const notes view like that

then let's see what we were doing we

were returning this verify email view so

let's go ahead and do that here as well

excuse me if the state is logged out

then let's see how we were handling that

um if we were logged out we were going

to the login view like like here

so if we were logged out then we should

send the user to the login view

what can we do let's say that in the

future you're going to add some more

block block builder right now is not

um what you want is still an application

that is in working condition you

shouldn't crash or anything so

let's just in this case return a

and let's in the body of our scaffold

create a circular progress indicator

just like that all right so it looks

like that also you could mark your block

builder as well to say that it

and also it has off states you remember

block builder has these parameters in

the builder and sorry the block itself

and the state that's why i've marked

them like this okay and now as you can

see state is not an uh it's not just a

normal object anymore it's an off state

before writing that state was just an

object but now i've marked it as off

state and you can see it's become an off

great stuff now let's get rid of the

future builder that we have from before

so i'm going to remove all that code

and now you can see we have our off

our block builder here and a block

so that's all we have to do um now it's

great actually we're getting this issue

um and you can see it's i love these

errors i mean a lot of developers are

scared of stuff like this but it's so

important to actually read what's inside

this what is what it's telling us is

this happens because you use the build

context that does not include the

provider of your choice and that's

is this thing context read auth block so

so what flutter is saying that hey

you're expecting me to extract an off

block from the context but it's not

there okay why is it not there it's

simply because the main function i've

mentioned this quite a few times in the

course but i believe it's so important

that i want to mention it again the main

function does not get called during hot

reloads and i just did a hot reload by

there is no block inside the context

because the block is actually created by

the block provider which is inside the

main function so if i want this auth

block to be injected in the build

context then i have to do a hot restart

now the application is working as it

so we've now taken care of our main dart

file removed the stuff that we have for

the counter application which we created

with auth with which we created with

block and now we've moved to using our

first two components from block which is

block provider and also block builder we

have a few unused imports so let's just

okay just to make sure that this file is

the part is that it's done now what we

need to do is to use as you can see in

the caption we need to use our off block

in the login view and the only thing we

really need to do is upon pressing the

login button we need to send the off

that's very very simple so let's go

ahead and take care of that this is just

go to login view as the caption

indicates and where we're calling this

as you can see we're saying

password and we're just yeah calling a

let's see we also have is email verified

so we're not gonna take care of that at

uh take care of email verified so in

this in this try statement here verify

we will fix that soon so let's just

try everything in the try block

and what we need to do in here we need

to read our block our auth block and

then convey an event to it okay how do

we read the the a block and that is

using context dot read or what was it

called read i believe actually yeah but

and three function is not available

provider and i can see in here says

package provider src but in the

in our main file we didn't actually

import provider so we've imported our

flutter block so let's go ahead and do

that as well in here so inside login

view dart please import your flutter

block so now all of a sudden we're going

to have access to the read function okay

so in there what we what we're going to

do is just to add an event to

let's see if we can get access oh for

that we need probably to import block as

let's see if then all of a sudden we're

gonna get the add functionality in here

context read oh sorry about that it's

because this is a function i need to

call the function so add and i may then

get away by removing block from here i

apologize for that we didn't really need

okay i understand this is a little bit

jumpy that's okay though so all we're

doing is that we removed everything in

the try uh block and we're removing

we're replacing that using context read

we're reading our off block from the

build context and now we want to tell it

log in so you remember we had a l off

so let's go ahead and do that and as you

can see it's going to auto import it for

so i mean here we have the email and

all right so that's gonna send that

event and then we have the rest of the

exceptions though how are we handling

at the moment our exception handling is

completely broken by going towards using

auth block everything is broken

as far as exceptions go because um

you can see the way our auth block

actually throws exceptions is by

emitting them inside states so you see

it says a state login failure and then

there's an exception in it so we're not

handling those at the moment so you're

right exceptions are completely broken

for the entirety of this chapter and

that's okay because we're gonna fix them

exactly right after this chapter

so now you know what's coming in the

all right that's that's for uh our

i don't think we need to do more to be

honest inside our login so let's go into

our imports and just clean up the

great stuff so that's for login um

what we also have to do now is the

caption indicates we have to go to our

make sure that we can log out using our

auth block as well so let's go to notes

and right now what we're doing is saying

we're awaiting on the auth service

firebase logout so we're not going to do

so we're just going to use our off block

in here let's remove that and just say

that we're saying to where we want to

grab the auth block first okay so let's

say context and then we're gonna

like this and if he asks visual studio

code it's gonna it wants to import um

oh yeah it wants to import auth block so

let's grab off block to bring it in

it also doesn't know where read comes

so what we need to do now is to

import uh the block library in here so

so importing flutter block and then

flatter block guard and here i'm

actually drilling down inside flutter

block and just seeing that i'm

interested in read context okay and read

context is as you can see in the code is

reading here oh my god there's so much

all right so that gives us the read

functionality that we can use in here so

that's the function all right after

grabbing our off block now we have to

convey the message of logging out in

here so we're going to add an event to

it and then we're going to say we add

the event of off event log out just like

that and this is a constant constructor

as well so let's just send it send it

and after doing that we don't really

and we're also not in this case we're

not actually gonna go to to the login

what is gonna happen in here i'm

actually gonna remove that and we're

gonna start testing a little bit so

you'll see how things work okay

um i'm gonna do a hot restart in here

and see if everything's working as it

should so yeah what i'm going to do then

so in here i'm just going to say this

log out or cancel i'll say cancel so

and i say log out and then log out and

all of a sudden we came to the login

view but hey wait a minute what happened

we removed this code this code that was

why is why are we going to the login

view without that code so this may look

magical but what is happening is that

since the entire application is now

our auth block an auth block upon it

receiving the log out event let's go to

so you get reminded of the log out event

but what it is saying is that it first

goes to the loading state and then if it

could lock the user out and it actually

says that i'm logged out now remember in

the main function here we are actually

listening to various events that come

from our off blog and when the events

that comes in is logged out we are

showing the login view so it is the main

is the home page that is doing this work

it is to me it is absolutely beautiful

uh logic from our code and one step at a

login as well uh so what we need to

uh let's have a look in here at login

you see after login we're not telling

the application that you have to go to

and so we can actually test this so i'm

going to say my email address here and

see it comes to the main screen how did

that do that and that's again because of

the main dart you see it first said um

loading let's see are we handling

loading somewhere no we're not using

that um but if if it actually becomes uh

logged in then it says display the notes

view so that's how these screens are now

and displayed to the user without us

push routes or push name routes so

fantastic very well done we've taken

care of everything that we said we're

going to take care of in this chapter so

and what we usually do at the end of

every chapter is now that you're

familiar with everything you've come so

far almost 40 40 chapters in this course

so you should know that we need to tag

our work so that we don't lose them

let's go ahead and have a look at

if i can bring terminal up in here and

we see bit log you can see the last

commit was step 22 so let's say git

commit get status first actually

a whole new folder was added so we're

and let me increase the size of the

so we're going to say git commit and um

and we have a look at our logs get to

step 22 and step 23 and there is nothing

so let's also tag our work and we say

fantastic so if you look at our tags now

fantastic as this tradition at the end

of every chapter we talk about what

we're going to discuss in the chapter

as i mentioned just briefly

as a little note while i was talking

we've now broken our exception handling

signal to our block our auth block um

that in itself is not gonna produce an

but right now we're treating that add

function and we're putting it inside a

try block and then there's on exception

blah blah after that so none of those

so uh we're gonna handle that and fix

that in the next chapter so grab some

refreshments and i'll see you there

hello everyone and welcome to chapter 41

in previous chapters we've been talking

quite a bit about uh block and

um i suggested that everybody who's

taking this course to have a look at

block on their own time as well and to

read the documentation because

um i understand that block could be

something intimidating for especially

for those who haven't done for us this

however it allows us to create a good

and between our ui and our business

logic as that's the point of using block

in a flutter application for instance

so in this chapter we're going to build

up on top of what we've already done but

from this chapter onwards we're going to

spend a little bit of time to clean the

logic up i mean even though things may

be working the way they are right now

and there is like a saying in software

usually strongly disagree with that

people say if it's not broken don't fix

it however we've seen over and over

again that things that work don't

necessarily continue to work or things

necessarily working to the best of their

in order to make things uh a little bit

better in our source code we're going to

spend a little bit of time to make the

logic more thorough and we have to

think it more through um we've gotten

started with block but we are not really

there yet so in this chapter as you can

see in the captions we're gonna handle

off block exceptions during login so

moving around between different files

and we're gonna like basically clean

things up so we have to jump around

between files and i'm going to do my

when i move between files as well and

like what we're adding what we're

what we're modifying so i hope you can

all right so the first thing that we're

going to do as you can see in the

caption here is to remove our off state

so what we're going to do is um first of

all i'm going to bring the code to the

to the main screen here so you see it as

perhaps not even bring up scrcpy because

i don't really think we need scr cpy

the way it is right now i don't even

um if i say command p off state so let's

go to the off state dart file okay

and as you can see in here if i if i

make the size a little bit bigger

you can see that we have for instance at

a off state login failure and then there

is an exception in there and also we for

instance have off state logged in so it

seems like this is kind of like a

pattern that we're following so we have

off state logged in and then auth state

login failure with an exception and then

we have off state logged out and then a

however we're going to clean this up a

little bit here and make sure that

we don't have just like except

off states that we have to handle in our

so what we need to do is to go into our

logged out in here and add an exception

the point of this is that if you for

are logged out at the moment in the

then there may also be an exception and

you you you probably are asking like how

can a state of logout have an exception

what we're going to do is that when you

try to log into the application let's

let's say you're a complete new user and

you haven't logged into the application

before okay you download the application

what you what is your state your state

now let's say that you make up an email

and a password and then you write that

in the login screen and then you press

the login button there are no users

let's say in the system with that with

those information that you provided

then we're going to give you an

exception we're going to give you an

error saying that well you couldn't log

what is your state at that point well

you're still logged out okay but now

you're logged out and then the screen

also has to display some exceptions so

that's why we're going to build a build

exception right into the auth state

so let's go in here and just create an

optional exception in here like that and

just call it exception okay and i'm

going to get help from visual studio

code to add that parameter into the

and let me do some reshuffling on the

screen as well so you see it better and

perhaps decrease the size of the font as

so that was the first thing that we had

that i've written we don't really need

auth state loading in auth events login

what we're going to do is to go in

our off block so let me just save this

file and let's go to off block

and in here we have this logged out with

an exception and we're going to assume

fix that actually let's see in here

logged out at the moment and let's pass

a null exception in here as well

so i'm going to go to my notes as well

to auth block to ensure that i have all

the necessary information to pass

so let's go in here and also fix that so

now we're in our off block dart file and

we fixed the error that was caused by us

adding an optional parameter

um to our off state um logged out all

then the next step as the caption

indicates is we're going to remove the

emitting of off state loading

let's go ahead and do that so we're

going to go ahead and remove this image

from there okay so we're not gonna

display any kind of like a login screen

as you can see in here we're now gonna

um i've talked about block listener

block provider block builder block

consumer before but for those of you who

are not aware of what a block listener

is a block listener as its name

indicates and it's only going to listen

to changes in the state of a block for

instance our off block and it is going

a side effect is for instance displaying

of a new screen or displaying a dialogue

or removing a dialogue or removing a

from your navigation stack these are

to be for instance uh to replace the

current widget that's on the screen

instead they can create something that

is on the side as its name indicates so

listener is perfect for that so the

or the listener parameter of a block

listener doesn't return a widget except

it's just a void block so it allows you

to do something with the incoming state

so what we're gonna do now is we're

block listener in our login view for

in order to basically handle our

exceptions because if you have a look at

login view right now you can see that we

and in there we're sending an

event of login to our auth block

but we're also handling exceptions in

this way and as we mentioned before

these exceptions are never going to

block or any block doesn't necessarily

have to throw an exception the way it

works for us if we go back to our auth

look at our login you can see that if

there is an exception what we're going

to do and what we're doing at the moment

is like we're saying off state login

and what we're what we also need to do

actually is to clean this up because

login failure shouldn't really be there

so i'm going to go to my notes as well

and make sure that that yeah that seems

to be completely removed so let's go to

our off state actually and as part of

logged out that we added the exception

let's go and remove this login failure

completely okay so now i'm in off state

off state login failure because as i

mentioned a login failure is now

expressed by the auth state logged out

you're either logged in or logged out

that's how i'm thinking and if you're

logged out there may be an exception

therefore for instance caused during the

login process so now that we've removed

that state auth state login failure in

here we're going to replace that in our

osblog dart file we're going to replace

log out and then an exception in here

so now we're talking about uh auth

listeners so let's go ahead and try to

fix this up so in our login view

so i'm just going to go into my notes as

so if you have a look at our login view

right now we have a text button at the

which looks like this this is a text

button and it has an on press with an

async okay so that is the actual login

button all right and this login button

is the one then for now that is going to

take care of the exception handling

block listener so as you can see in the

cache it says our login view won't be

rebuilt since the state is the same but

so this is very important to actually

understand so let's have a look again at

our auth state in here and auth state

even if we put an a block listener and

wrap this button this text button here

you see once the application launches in

our off block you can see that

first we are logged out okay so when the

application launches there is no user

then the state is logged out and then

when you press the login button with

invalid credentials for instance

then the state is still going to be

logged out but with an exception

button won't be able to render or do

anything with those exceptions because

from our off blocks perspective it is

the same state one within without an

so it is the same state or it is the

we we are actually going to fix that um

but for now we're just going to go ahead

so let's go ahead and as the caption

indicates we're gonna handle some

exceptions in our text button in here

so let's go and wrap our text button um

with a block listener okay so i'm gonna

and then i'm gonna say wrap with block

listener and as i've mentioned this

previously i have this these wrap with

block etc because i have an extension in

visual studio code call call block that

is from felix angelov i hope that i'm

pronouncing pronouncing his name right

from um very good ventures who are the

people who are basically sponsoring

that is the reason i see all those wrap

with block etc in visual studio code if

you don't have that you may have to do

this part by hand like to create a block

listener in here but i'm just gonna take

advantage of having that extension in

visual studio code and just say wrap

and here you can see it says okay what

type of a block is it and i'm gonna just

and it says what state does it have then

all right and then here it says okay do

that was the wrapping of our text button

with a block listener so that's that's

just that just went smoothly

now what we have to do is as you can see

in the caption is to handle three

separate exceptions that might happen

during login let's go back let's take a

um so firebase author provider dart file

and you can see that there could be

three exceptions that might happen that

are called firebase auth exception user

so we need to handle these off

exceptions so user not found wrong

password and generic auth exception okay

so let's go in here and just say that

remember inside logged out we could have

an exception an optional exception and

that's exactly what we're gonna handle

that was you see we said now if state is

logged out so now in this code block in

here dart is going to understand that

okay anywhere in here state is

auth state logged out so you have access

so then we're going to say if states

and we're gonna display a weight

error dialog so let's make this a

listener also async and then we're gonna

and which we've coded before remember

this uses the generic dialog so i'm

going to go back here to login view dart

and for the text we're just going to say

then we have to also handle wrong

password off exception so else if state

exception is wrong password off

exception then copy the text here and

then in here we're just going to say

and remember in anything that has to do

with username and password it's quite

important that you don't tell the user

which part of their credentials actually

i mean if there is a hacker who's trying

to get into the system and just using

the ui then if you tell them wrong

password they'd be like ah so i got the

email right it's just a password that's

try not to tell a user even if it's for

good reasons like if it even if you even

if you think well i have no hackers in

it is still better just to say wrong

credentials because the user themselves

probably already know that their email

is correct or incorrect so they're first

going to check their email so if the

email is correct then they are going to

know that the password is incorrect and

we're going to later allow the user to

so just say wrong credentials in my

exception is generic auth exception

then we're going to display a dialogue

and in here we're just going to say

so that's that part done so now we've

handled those auth exceptions in our

login view for our text button that says

so now that we have that what we need to

do is to remove the uh exception

handling from the button itself so at

the moment we have a huge try statement

not a huge actually we have quite a long

try catch statements here that we have

we're catching three exceptions which

are now actually being caught here with

block listener so let's go and not

actually do that so i want you to grab

and where we actually pass the event of

log into our block and remove this

entire try and catch block and just do

the context read at auth event login so

event or sorry on your on press

parameter of your text button should

look very simple just like this email

password and then you pass that event to

all right so now that that has happened

let's actually check this out and see if

everything works and remember this is

like the beginning of us moving towards

a better approach of handling our

routing with blocks so things aren't

going to be smooth actually we have a

lot of problems we have to fix but this

is just like the beginning so i'm going

to bring scr cpy in here and let's just

now i'm on the login screen so okay i'm

then gonna go ahead in here and like put

and then i'm gonna put some inquiry

credentials in here okay and i'm just

gonna press the login button and now you

can see that our block listener is

taking care of that so it's saying oh

you're logged out and then it's wrong

credentials okay so i'm gonna press ok

then i'm gonna just put an email address

here that doesn't exist and then press

the login button and now you can see

user not found okay and to be honest

with you if you wanna if you wanna do

what i actually said before that it's

not tell the user whether it's their

user that is wrong or password you may

want to actually wrap both the state

exception of user not found and wrong

password and just display the same

message so you could do that by saying

and then you can just display the same

message and then you could just remove

this statement from there so that could

also work i'm just gonna leave it like

this but just so you know it is actually

better to do that approach which i just

all right so it seems like our block

listener is working fine in the login

view so this was just the beginning and

we have a lot to fix so we're going to

fix those things in the coming chapters

now that the code seems to be working

for login view let's just go ahead and

do what we usually do and commit our

work so that we don't lose the the code

make visual studio code a little bit

increase the size quite dramatically

let's have a look at our status

we've modified three files so let's just

let's actually let's do it at all and

then we just do a normal commenting here

now that it's done let's just push our

changes to the remote and then let's

just also gets get status nothing to

command so everything was committed

successfully and then let's just tag as

so that's our tag and then we push our

and let's have a look at our tags to

this point 23 we have where's 24 and

there is 24 so we have everything tagged

great so um as you can see and as is

tradition we always talk about at the

end of every chapter we talk about what

we need to discuss in the chapter that's

so you can see our routing and dialog

handling isn't isn't block based at the

moment we still have quite a lot of

places in our application that we're

seeing for instance navigator of context

push name and removed until or we're

so we've handled some bits and pieces of

our application and we're using block

but for instance we aren't handling

stuff in the register view or the verify

email view stuff like that so

we have a lot of work to do and the next

chapter is actually going to be a heavy

one but it's going to be such a key

chapter in this entire course

that if you could just stick with me

throughout the next chapter then you're

gonna see your applications architecture

actually become more and more robust so

grab some refreshments if you want to

and i'll see you in the next chapter

hello everyone and welcome to chapter 42

in previous chapters we've talked quite

a bit about cleaning up our application

logic and our authentication logic we've

come a good bit forward with that and

um we clean up quite a bit of stuff in

the login view and now we're using block

listener in the login view if you follow

all the chapters chronologically up to

up to that including the previous

so you should already know about block

block listener block consumer block

but we have quite a bit left and i'm

actually proud to say that this chapter

and maybe the next one or two chapters

glues that bring the application to a

lot more tighter point where it will be

ready for releasing to the app store and

the play store so if you stick with me

throughout these few chapters that are

we are going to basically create a lot

more cleaner product that is not only

usable by the end user but it's also

but it's also architecturally sound so

you're going to be proud of actually

releasing this application or maybe even

showing this code to your friends and

as a caption in the case in this chapter

we're going to talk about moving to

block for routing and dialogues because

right now you know routing what we have

in our application is kind of like a

hybrid in the main dart file and i mean

we don't have to talk about uh

so like abstract concept concepts we can

actually look at our main dart files so

if you look here what we've done in the

main dart file we're actually creating a

block builder and depending on the

states that are being output by our

block we're displaying the correct view

so this in itself is quite fine so

there's nothing wrong with this but

we're also mixing this up with custom

places in our application where we're

saying for instance context of

um let's see actually with navigator off

and you can see we're doing actually

that's fine but you can see in our login

view when you press the not registered

yet register here button in order to do

the registration of the user then we're

doing a navigator of push blah blah blah

so there's quite a few bits and pieces

left still in our application that we're

either directly talking with our auth

service which we shouldn't be doing we

should be talking to the off block

or and we're talking with navigator of

something to do push name so

in this chapter we're going to clean

these things up and make make basically

the consumption of our off block a lot

tighter all right using block and

listeners block builders and um

we're all also going to use block

as the caption indicates i mean i've

already talked about this maybe i should

have displayed this caption a few

but we've already talked about this we

should basically tighten up how we're

how we work with off service

and you can see in here we need a few

more auth events in order to be able to

achieve this so let's go ahead and open

i need to probably do some reshuffling

on the screen here so you see the code

better so i'll do what i usually do here

and then let's go to our off event

so these are the events that we have at

the moment we have log out login and

then we have an initialize but we also

have quite a few other ui events that

the application is doing in order to for

instance interact with authentication

um sending a verification email all

right so when you're in the verify email

view and the user presses send the

verification email again then that is at

the moment talking with our auth service

directly and we shouldn't be doing that

we should be asking our off blog to do

that or when you for instance um

ask the in in our verify email view so

if you go here you can see that we had

um log out button or the restart button

so let's go ahead and i'm going to bring

actually to be able to show to verify

email we have to have a user who hasn't

been verified but if you remember from

before if you've created a user just

or just just now for instance and that

user hasn't verified their credentials

then they're gonna always be moved into

this verify email view in which they

have to for instance say that yeah um i

am i did they had the ability to send a

verification email to their email again

or restart the whole process meaning to

log out and just go to the registered

that is at the moment happening directly

you can see it's off service directly to

the auth service and we should be doing

that and then there is a navigator of

push name then removed until which we

so in order to tighten these things up

we need a few more events in our auth

event dart file and that's what we're

so let's go to our auth event file and

i'm gonna do the same thing in my notes

new event that we're gonna create in

here as you can see it's called auth

event send email verification all right

so let's go ahead and do that i'm going

to get rid of this bottom view in here

and also the project structure

so i've already written that in my notes

so i'm just going to bring it here to

the to visual studio code so i don't

have to write it manually but the event

name should be called off event send

email verification the goal is for our

verify email view to send this event to

our off block in order to request a new

verification email to be sent to the

currently logged in user okay

we also need a register event so the

goal is that inside register view so

let's go have a look at the register

view right now and you can see when the

user presses the register button at the

moment we're saying uh firebase create

user so we're going directly to firebase

and we're saying create user and then

immediately we're saying send email

verification so we shouldn't be doing

any of these so these three things that

we're doing here are pretty much wrong

from the architecture perspective so we

shouldn't be talking with these services

directly we should clean this up okay

in order to achieve that we need to go

back to our auth event and create a new

so i'm going to bring that at the bottom

of login here so let me go ahead and

off event we call it class of event

and of course we're going to extend our

and for register we need two parameters

if we go back to the register view you

see upon registering we're always

sending the email and the password so

let's go ahead and do the same thing in

here so we say final string email and

i'm going to copy this and i'm going to

say just password and get help from

visual studio code to create this

constant constructor okay you may want

to make these required name fields using

these but i'm not going to do that so

i'm just going to leave it like this

with email and password okay

so that's our off event register

so the other thing that we need

an event called should register so um

basically that means for instance if you

um haven't really registered a user yet

send this event i'm actually gonna have

and that is if you for instance go to a

and then you have a look at this button

that we have in here not registered yet

register here that is basically the

event that we're going to implement

right now so we're going to tell the off

block that hey you should register user

okay and then off block is then going to

change its state to a state that the

application is going to understand and

automatically send the user to the

so um let's go ahead i'm gonna just

check my notes as well let's go ahead

and develop this should register and

i've already done that in my notes so

i'm gonna bring it at the bottom of off

event register but you will need to

write this yourself so it looks like

auth event should register extends off

event and it just has a constant

constructor so it's very simple okay

so that was for our auth um event should

at the moment if we go now as you can

see it in caption we need also and now

we've done the auth events like this

stuff that we had to create in order to

um events that come from the ui but we

also need to fix up our states so let's

go to our off state and have a refresher

in here you can see we have the state

logged in needs verification logged out

and log out failure but we're going to

clean this up a little bit and make sure

that we have every state that our

application requires in order to be able

to for instance display dialogs or do

in at the moment in our off state what

we need to do is to create you see we

have this loading state and what we're

going to do is to actually remove the

loading state and we're going to create

an auth state called on initialized all

let's go ahead and actually remove this

off states loading and create a class in

on initialized because when you land in

for the first time you may actually want

display some sort of loading screen or

whatever and we're going to indicate

that the application hasn't really

authentication system using this off

state uninitialized it's just this is a

cleaner way of indicating to the two

the call side which is ui that hey we

haven't yet been initialized so you need

to call the initialize function on our

off block okay or sorry you have to send

uh initialize auth event okay so let's

just to recap i removed off state

and now we're going to put in our off

state uninitialized so we're going to

say uninitialize extends off state

and let's just create a constant

constructor for it as well like that

so the other thing that we have to

obviously we've talked about login like

here login logged out and then log out

and and now we actually have to start

talking about what happens when the user

presses the register button when the

user presses the register button we also

the case that yeah we are registering at

the moment so it's a process that's

ongoing but we also have to talk about

what happens if the registration

fails so we're in the process of

registering either it goes fine and then

we say you're registered or we say

registry registration failed so let's go

a um a state in here right after

uninitialized let's just say class

what are we calling it registering

extends off state okay and let's just in

as we're doing in here for instance in

the state of logged out let's just copy

exception and bring it into off state

and then let's create a constant

constructor here for our off state

registering and i'm just going to say

constant here okay so now we have

so now we have registering logged in

and we also actually need to remove off

we have logged out with an exception

um so let's go ahead and do that right

now let's just remove off state log

so that's for off state registering

as you can see in the caption it says

loading of the logged out state we need

login screen to have a loading dialog so

we need is loading in the auth state

logged out so let's have a look at

previously we had this loading state as

a separate state so it was off state

loading and we were gonna generically

use it everywhere but now what we're

gonna do is to build this loading state

or to build this loading flag into

existing states themselves so

let's then go ahead and say well

when you press the login button what

we're going to do first is just to say

um actually wait let's go one step back

let's say you just landed in the

application but you already have a user

which you haven't logged them before

okay so your state is logged out and the

and we're going to add a flag in here

and say final bool is loading

and let's add that is loading to this

parameter in here and make both of these

required parameters okay like this

comma there as well like this boom so

when you land in the application

exception your state is logged out there

is no exception so exceptions null and

is loading is false because we're not

loading anything then you write your

credentials and you press the login

button then what happens state is still

logged out exception is null but loading

then let's just say that you entered the

incorrect credentials then what we're

going to do in our block auth block is

going to say ooh you're off state logged

out there is an exception and is loading

and then you'd be like okay now i

entered the inquiry credentials then

you're gonna correct those and then

press the login button again now what

are we gonna say we're gonna say okay

all state logged out exception is

nothing and then is loading is true

we can log you in that we're gonna

produce another state for you so you see

this is how we're using states to convey

cur like the correct state of the

application to the consumer which is the

so and this is not like you may think oh

how does he know that this is the right

right way of doing things well

there is no rights and wrong in here it

reason about your application

and when i say there is no right and

what i mean is that some things are more

right than the others and some things

are more wrong than the others but

what you need to find is like the sweet

good for your application and at the

same time is not incorrect okay and that

is the definition of write for your

application and in this case this is the

definition of right for this application

so you just need to find a sweet spot

now let's have a look in here a little

and talk a little about a little bit

what i mean by equality in here is that

you see what i talked about is three

different logged out states logged out

with exception null is loading false

logged out with exceptional is loading

true and then logged out with an

exception and is loading false for

so you're producing three different

types of states all of the same class

how will uh your application understand

that these are actually different states

you kind of need to differentiate

between various states of your off state

logged out so you kind of need to tell

although the previous state was also off

state logged out and the correct like

the one that i'm producing right now is

also off state logged out but these two

states could actually be different from

each other and in what they contain so

you need to kind of create like an

logic into your states to tell the

although it's the same is like a new

instance of the same state class but

internally is not the same thing and for

that we have to implement equality all

now there is a good package that allows

you to do this in order to implement

equality in your applications and in

your dart code and it is called

equitable so let's go ahead and import

that and don't be intimidated by all

these logs in here it's just because we

have a lot of problems that we're fixing

at the moment so let's go ahead and um

i'm gonna change the screen layout a

and let's just go ahead and say flutter

stuff like that and you can read more

about that so i'm just going to bring up

safari in here and let's just say

and let's just say equatable

and you can see it is actually developed

by flutter community dev in here okay so

it's a verified developer in here and

you can also actually follow flutter

community dev on twitter as well to get

some updates about their packages okay

so we're now importing that into our

application and we should now be able to

use that so i'm going to get rid of this

and change the screen layout again

okay so in here now let's go and import

equitable so i'm gonna just import that

i've already imported that in my notes

so i'm just gonna paste that in here you

import equitable like this package

equitable slash equitable dart okay

so what we need here is we're already

extending an existing class so what you

can do is you can bring in equality in

your classes using a mix and so we're

going to say mixing e quotable

so now that we're doing with that mixing

now we have to implement a few

functionalities in here as you can see

visual studio code helps me it says

create one missing override okay

so i do that override in here

and it says okay now we have to override

this property and you can see in here

what you need to return is a list of

properties that have to be taken into

account when the equitable package can

equality in your class and in here what

we're going to say is that we have two

properties in here called exception

and we also have is loading so take

these two properties into account when

computing equality in the instances of

very well done so that's that's what

we've done in here so we've made our off

state logged out class equitable and the

reason again for that is that we need to

various um mutations of this off state

mutations with various exceptions and is

loading need to be distinguishable from

each other okay and that's why we're

using the equitable package in here

this thing we've already talked about

and we don't need the off state logout

failure so we we've removed that already

as part of the cleanup that we were

doing earlier but if you forgot to do

that please just look at the caption at

the bottom of the screen just to make

and just make sure go you go to

offstate.file and remove your off state

logout failure and the reason behind

that since i explained before is that

now logout failure is actually built in

and baked into off state logged out

class inside an exception all right

all right let's go to the next section

you see at the moment we have no loading

screens in our application so

when something happens when we're doing

an api call for instance or we're um

going to our off provider and say login

or send an email verification we have no

loading screen inside the application

so there is nothing that indicates to

the user that something is actually

happening and we're gonna go fix that up

soon so as you'll see we're going to

create a new dialog which does some

loading for the user and then using that

dialog users going to understand that

okay something is happening i just have

but the user experience that we have

right now is kind of sub-optimal in that

the user presses the login screen and

sorry the user presses the login button

and depending on their internet

connectivity and the speed of their

internet internet connection that

anywhere between a few milliseconds to a

if you're making a user wait a few

seconds based on their internet

connection speed then you have to kind

of display to them that you're doing

well the the usual i mean way that you

could do that is to display some sort of

a small loading indicator for instance

natively you have a little loading

indicator that sits on on the status bar

that just moves a little bit and it's

very tiny i would dare to say it's less

20 pixels wide and 20 pixels in height

kind of it could even be like 17 pixels

width on height it's very little so it's

a subtle indication that something is

but that's usually i mean i find that

quite annoying because when something is

block the user from trying to press the

same button thousands of times so

if you display that little loading

indicator on the top on the status bar

then what you also have to do you have

to add some extra logic to your

application to block for instance the

current register button or the loading

button and you usually don't want to do

that but because that's just extra logic

what would make more sense is upon a

user pressing the login button or the

register button you want to display like

that tells them that hey i'm doing

something okay so don't do anything else

while this screen is is visible on your

mobile display so let's go ahead and do

so we're going to code a loading screen

as you can see in the caption says we're

going to do it in lib utilities

dialogues loading dialog so let's go

and bring up my notes as well

i'm going to close all these files just

to make sure we've also saved them

because if you close a file in visual

studio code at least which we haven't

saved before visual studio is going to

display your dialogue saying are you

sure you want to close this file without

saving it so it's usually good practice

to close your existing files before you

move into doing something new

so that you at least are sure that

you've saved those changes okay

um now let's i mean we have some errors

you should now be comfortable with

having errors in your application

because you know at the end of every

chapter we're going to tighten things up

and fix things okay so let's go to lib

dialogues and we're going to create a

new file in here as the caption

indicates called loading dialog dart

and you see this loading dialog what we

also have to have in this loading dialog

to allow the caller to display this

dialog but also to allow the caller to

dismiss this dialog so it's very

important to be able to dismiss a

dialogue when the application actually

needs for that dialog to disappear so

what we're going to do first is to bring

a create a type f in here and we're

gonna call it closed dialog let me just

increase the size of that font as well

and we're gonna make sure that it's

equal to a void function in here okay so

what we're to do in here we have we're

going to create a function that displays

a loading dialog but it also returns

back a function that the caller can call

to dismiss it so it may be a little bit

of a shift in how you think about

programming if it's the first time

you're doing something like this but i

promise you it will make a lot more

sense as we develop it so let's say that

we have a function that returns a close

dialogue um and we call it show loading

required parameters so let's put curly

and then let's just say we have

and we call it build context

or let's just call it context and then

we have a text to display so required

so and now you can see you get this

try changing its name and i'm going to

get help from facial studio code to

now we have just one error saying that

you're not returning anything in here

so the first thing we're going to do is

we're actually going to define our

dialog how is this loading dialog going

to look like so it's the only thing it's

going to do is just to have a little

loading indicator a bit of spacing and

using the text widget to render this

string so let's first define our

dialogue so i'm just going to say final

dialog is equal to alert dialogue

let's just go to the next line semicolon

and then we have to define the content

for it as you can see content should be

a widget so the widget we're developing

is a column because we want like a

vertical list of widgets the loading

screen a little bit of a size box

spacing and a text widget so you can

render that with column easily

and remember column what what column

wants to usually do is to grab as much

space as it needs so it could be like

the entire screen long we don't want

that what we want for the column to take

as little space as it needs to render

its content correctly so we're going to

exercise it should be of type main

access size and we're going to say main

exercise of minimum all right

are going to be an array of two constant

of a circular progress indicator like

and then we're going to say a constant

size box we haven't used size boxes

before but size box is really good for

as you can see in here it's just an

empty space with a height of 10.

and then what we're going to do in here

we're just going to say display also a

renders this particular text parameter

now we're we have a little problem here

with how this thing is rendered and you

can see they're in the same line and

that's why it kind of looks strange

let's put a comma in here and then save

formatting correct and let's put a comma

okay so now it's working as it should or

at least it's formatting as it should so

then what we're going to do in here

we want to display that dialogue so

and let's go in here and the context of

this dialog and i'm going to bring it

here so you see it the context is the

context that we are providing to this

and a barrier or dismissable and i'm

going to show you the documentation for

very dismissible and let's see if we can

it's not helping me with that but that's

what barrier dismissable allows you to

do is to say that if the user taps

outside this dialogue either allow the

dismissal of this dialogue or don't and

we don't want the user to be able to tap

outside this dialog in order to dismiss

it because a loading screen should be

dismissed when we want it to be

dismissed not when the user wants it to

for those who are ux designers who are

watching this course he may be actually

tempted also to for instance

um provide a cancel i actually think

having a cancel button in most loading

for whatever reason an application may

not be able to handle for instance

different errors and exceptions that

could occur while making an api call and

i personally have been in this situation

where a dialogue was displayed to the

user and it was just never dismissed

because something went wrong the

application wasn't able to handle it so

i personally as a user had to go and

force kill the application and restart

the entire process in order to get

things working so if you want to have a

cancel button in here it's fine but um

i'm not doing that right now it's just

for the sake of simplicity so that we

can move on with this code as um as fast

as accuracy as fast and accurate as

so now you know what barrier dismissible

and for the builder function that's what

this um error is here we have to just

and but in here what we do is just do we

remove we we return the dialogue in here

okay so now we're saying show this

and and then we're just going to say

the return value see we still have this

problem with the return value that we're

not returning a closed dialogue and what

this close dialogue is just going to be

is we are going to return a function

from our function so when the user then

calls that function we're going to pop

this dialog it's it's beautiful

so let's just say we return a function

upon calling which we are going to say

navigator of this context and we're just

going to say pop okay so that's how you

return a function that can be acted upon

so now we save this and you can see we

don't have any errors i'm going to just

resize this a little bit make the font a

little bit smaller so you see the code

now let's talk about loading and

exception handling during the login

let's go to our login view

and you see here we have already some

exception handling and we also have this

off block but we also have this text

button that is doing like manual

navigation it says push name and remove

until and we need to clean these things

i'm going to also do it in my notes

let's have a look at how we've done

things you can see in here we have a

block listener at the moment that is

itself around this text button so we're

not gonna do that we're gonna have the

text button exactly the way it is and so

meaning that we're gonna remove this

block listener from here okay

so what we could do is as the caption

indicates we're just gonna go here to

the scaffold and just say okay we have a

new block listener and remember this

should be the off block itself so i'm

gonna say off block and this should be

the off state like this so then inside

the listener what we need to do is to

text button in here so we have the

excuse me so as the caption indicates

we're going to do this exception

handling now inside our new block

listener on top so remove all the code

from your block listener for your text

button all the exception handling just

and bring it please up into this block

listener which is at the top level all

right and make this an async listener so

that you can await on your show or

dialogue okay so that's the first step

however we still have this empty block

listener in here so i'm gonna remove

that now so all of a sudden you see now

we have the text button in here

all right that was fantastic

so then what we need to do is to

screen basically so that is going to be

a bit of code so but don't be scared of

that we're going to handle that soon

display our loading screen we also have

to kind of like keep hold off this

close handle what do i mean by that

let's go back to our loading dialog you

see every time we call this function

this is going to give us a function back

the dialog we have to keep hold of this

so that when the states change inside

our login view we're going to look at

that previous handle and be like oh we

displayed to the user we have to first

dismiss it okay so let's go where we're

keeping hold of our email and password

close dialogue and it's going to auto

import that you see so if you don't have

auto import you may have to import this

so let's say it's an optional and we

so we keep hold of that we haven't

assigned to it yet but we're gonna do

so let's stand in here in the state of

logged out and right here just add some

and what we're gonna do we're gonna say

um do we already have a closed dialog

and what we're going to do now is we're

going to have a look at our states and

also if we have a closed dialog handle

and we're going to display correct

so what we're going to do is we're going

state is loading if we're not loading at

the moment meaning that maybe we were

then our goal in here is that saying

that if we are not loading and

excuse me close dialogue is not null

in this case what this conveys to us

saying it says that we're not loading

now but we were loading before

and that the bot part is coming from

here what we need to do in here then is

just to close that dialog so let's just

say close dialog we call that function

so we're just cleaning that up now okay

what we have to have so what we've

handled right now is closing the dial up

but we also have the hell of showing it

all so we're now going to say if the

and we don't have a closed dial sorry we

don't have a loading dialog yet on the

screen then we have to show it so

excuse me so let's say if state is

then we have to show the dialogue so

let's just say close dialog handle is

equal to show loading dialog we pass the

let's do some formatting in here and

and we leave the rest of this stuff in

the next thing that we need to do now is

as you can see in the caption on the

screen we have to hook the register

button to our auth block when register

button is tap send the auth event should

and what we're going to do then is go to

and find this button in here at the

bottom of the loading via sorry login

and upon pressing it let's just make

yeah i don't think it really has to be

any asynchronous code at all so let's

just in here let's say that we

grab our off block so let's say context

and we are looking for off blog in our

context and then we're gonna send it an

and we're gonna send const auth event

should register just like that okay

so and i believe add event is not async

or anything it's just a void so this

function doesn't have to be async so if

you had it as async you can just safely

i'm just gonna save this file as well

all right a lot of work we've we're kind

almost done with uh our login view

so what i'm gonna do is i'm gonna close

all these files that are on the screen

right now and we're gonna start moving

also blockifying our register view so

let's go as the caption says let's go to

and i can see in here in the previous

chapters we've been working with

cleaning up the login view so

blockifying the login but we didn't do

the same thing in register view and

that's fine we're going to take care of

that and i can see that by just looking

at our try and catch statements in here

you see these things shouldn't be

as like but one thing at a time as the

caption of the yeah as i capture the

bottom screen indicates we're going to

wrap the scaffold inside a block

listener so it's going to be very

similar to how we did it for our

a wrap with block listener here and i'm

block and it's going to auto import it

for me so very important if you're

getting errors for the auth block not

being found in this context it's

probably because you haven't imported

off block so and in here we're going to

and that's going to also import it as

well and block listener is not available

in this context either because we don't

have a flutter block so that's also

going to be all too important so that's

so that's the three um auto imports and

they're all available i believe so

you could actually bring it next to each

other if you want to so you know which

ones to import it's these three

wow okay um so what we need to do that

that was the first thing that we had to

we also as i said now we have to go and

this is very similar to how we did and

did it in the login views so we kind of

so now what we need to do inside this

listener of our block listener we have

to handle the exceptions that we are at

the moment handling here at the bottom

so this should be very similar process

to how we were doing things in the login

view from if you remember so if we oops

if i go to our login view you can see we

block listener and then we're doing this

kind of pattern in there so we're going

to do something very similar to that

except we're going to do it in register

inside register view the state is

i mean all the exceptions all the

problems that could arise are going to

be inside the um registering state so

we're just gonna first make sure that

we're in that state okay so let's say

and we're gonna say if state exception

is weak password auth exception

let's make this listener asynchronous so

we can do an await on our show dialog

and the text is just going to be weak

and then we're going to do another else

an else statement with another if and we

it's email already in use auth exception

and then here we're gonna display

another dialog then that says for

instance email is already in use okay

so let's then go to another else

statement so i'm going to just copy this

i'm a little bit lazy and i'm just going

to say generic auth exception and then

failed to register so these are the

various exceptions that can occur

while you're registering for a user okay

and you can see in here we have three

uh exceptions we're handling weak

password email already in use and then

we also have invalid email auth

exception so maybe we could actually

handle that as well so let's just go

ahead and add another else statement in

uh invalid email auth exception so we

so now we've handled those four

what we need now is to make sure as you

can see in the caption that in register

view the register button to send the

auth event called auth event register so

let's find that register button that

and that is this text button you can see

so what we need to do is perhaps to

clean this code up at the moment there's

just so much information in here that we

don't really have to do so go to your

register button please in the register

view and just pretty much just nuke this

entire try and all these cad statements

so now we have a clean slate so now we

have just email and password and let's

grab the auth block in here and ask the

auth block to do the registration okay

so i'm just going to say context

and let's just say we grab the

and then i'm just going to say add in

with email and password just like that

so your code should kind of look like

this and put a comma in here to make it

a little bit cleaner so just like that

okay that was for register

login button in here which right now

inside our register view do you remember

if you end up in the registry view and

incorrectly so you just tap on some

button and enter them in the registry

and be like oh i'm in the wrong place i

want to log in actually instance so we

have this already registered login here

button and at the moment that's doing

custom navigator or push name and remove

until and it shouldn't be doing that so

let's go ahead and fix that up so let's

go in here and remove that code and just

and we're going to basically add an

event in here of con of type const auth

log out just like that okay so that then

is going to send the user to the login

all right let's move now to the next

point as you can see it says send

verification button and verify email

it should send an auth event and when

you press it it should send the auth

event send the email verification to the

blog so i'm going to go into my notes as

and just find that button and now let's

let's go to verify email view

and have a look at that button that

we're talking about which is right here

and at the moment as you can see it's

doing all service firebase and email

verification but we shouldn't be doing

um we should ask our block to do that so

first of all remove that code inside the

buttons unpressed and then this button

doesn't have to be async anymore

and what we're going to say is just

going to say context and read

and but we don't have read remember

because we don't have we haven't

we haven't imported block or flutter

block into this file yet but we're going

to fix that soon so first of all just

say read the off block and that's going

to also import off block for us so

that's the first part and now you have

this error let's get visual studio code

the same provider but i actually want

let's go ahead and import that ourselves

so let's say package flutter block and

now it's fine alright so let's in here

and then add an event we say const off

send email verification just like that

so the next thing we have to do is you

can see inside this restart button at

the bottom of the screen at the moment

it's doing quite a lot of work

it is basically first logging out from

our auth service and then it's doing

navigation so this button is like all

over the place it's taking care of

authentication it's taking care of i

mean i'm actually very i'm laughing here

because i'm kind of laughing at the

progress that we've made so far and that

gone from very very raw programming to

handling of exceptions alien handling of

routing etc so it is actually really fun

to be here to be honest with you

so in here let's remove that code and

kind of grab this thing that we have up

here in our send email verification

button and bring it down here instead of

sending the off event send email

verification we're gonna send alt event

excuse me all right so that part is done

what we need now let's go in now let's

close this file and go to our off block

so we have quite a bit of work now to do

in our off block as you can see it's

i want to do the same thing in my notes

the first thing that we need to do is

make sure that we are not using this off

state loading because we don't have that

anymore what we have is off states on in

each light so please take care of that

we also have now an auth event send

email verification and we haven't

handled that yet so let's go on top of

this initialize i'm just gonna send say

send email verification okay and let's

create a new on to handle auth events

and email verification because we

haven't handled that so we have event

let's just go and say this is an async

function and then open it and then a

semicolon at the end to get the format

the only thing we have to do in the auth

event send email verification to

actually call and tell the provider that

hey um we're gonna basically send an

email verification all right so let's

just let's just say a wait provider

and email verification and then what

we're gonna do we're gonna emit the

so by coming into by sending this event

we are just going to do some work and

emit the exact same state that you're in

so we're not actually changing the state

of the application because remember when

you're in the verify email view and then

you press the button to actually send a

new verification email what happens on

the screen nothing we're not like doing

anything it's just we're sending the

email verification that's all so we're

not sending you to a new screen or

anything like that so that's why we're

emitting the exact same state as we had

all right now we have to actually handle

so let's go ahead and do that so that is

completely new so let's just say on

and we say we have the events and the

emails and an asynchronous function just

when we have the auth event register if

you remember from before this authentic

include the email and password in itself

so we can grab those and that

information right now just say email is

advanced.email and let's just say final

all right so then we're going to put

this into a try and catch block so we're

going to say try on exception

when an exception happens we're just

we talked about this before but just to

refresh when you're during the process

of register we actually can emit a new

state in here just called registering

and then it can it can contain an

exception all right so that's what we're

emitting in here saying that you're in

the process of registering but something

bad happened which is an exception all

so in here then let's just say await

provider and we're going to create a new

user with the email and password they

just fit right in so that's really great

and then if you remember from the

registration process that we had before

in our register view during registration

upon doing a registration we didn't just

register the user with the provider but

we also send an email verification just

to make sure that the user doesn't have

to go and send an email verification and

manually so we're going to do the same

so let's also wait on the provider

and we say send email verification just

um and then after doing that since you

registered a new user well what is the

states if you remember from our

we have this needs verification we know

that when we register and use a new user

that user is always going to need

verification right so let's go in here

and just emits that state so

uh auth state needs verification just

like that and that's an empty state so

it doesn't have any parameters and such

then we have to handle our auth event

initialize so let's have a look in here

and see how the code look looks like so

in here what we need to do at the moment

we have logged out but you can see we're

not providing that is a loading

parameter and we're not providing

exceptions so i'm just actually going to

click clean this and write it by hand

so in the emit let's just emit a const

when you initialize the application from

the beginning when the application

actually runs we're just gonna say by

default you're logged out all right

so let's go ahead and do that if the

so in the exception we don't have any

exceptions and we're not loading

anything as such so that's like the

default state so that's it comma in

there and a comma here just to get the

we also have the initialize in here

it's email verified and that so

yeah that looks that looks fine to me

okay now let's have a look at logging in

as you can see we have to take care of

our login and logic a little bit and

make sure that we're loading so when you

say i want to log in we're going to say

okay you want to log in that means

you're logged out but you're logged out

and there's a loading screen okay that's

why we created that loading dialog which

we're going to put into you so

so upon the user asking to log in let's

just say okay we're going to emit our

and there is no exception and the

loading flag is actually true

so like that and right there and just

and let's have a look at how we're doing

things in here so we have our login

and we also as you can see in here so

that that was that part we've taken care

of and now what we have to do is to

disable disable the loading screen if

um at the moment we have this user in

here you can see final user okay and

logged in but that is not complete

because we're not checking whether the

verified their email address or not so

and say as the caption indicates if

email not verified then disable the

loading screen by sending a new logged

out okay before sending the needs

verification so let's take care of that

so we say if um user is email verified

a constant of auth state logged out

and we say well no exception and we're

so that disables essentially the loading

screen okay by saying it's loading false

remember here we sent is loading true

now we're sending is loading false

when the email is not verified we

state needs verification just like that

otherwise if the user's email is

verified then we're gonna say we're

let me bring up the correct caption so

we have to do the exact same thing in

here we're gonna disable basically the

and then we're going to send

all right and also in our exception

handling we we don't use this uh um yet

we're gonna use off state logged out but

we're gonna clean this up so inside emit

we're gonna say auth state logged out

and then there is an exception and we

please place that inside the exception

now as you can see the caption that says

fix fix up auth state logged out

we have to emit the auth state logged

out and fix up exception handler as well

let's find out our auth event logged out

and we have a lot of errors in here

so it would actually be better

nuked this code in here and wrote it

from scratch so i'm just going to say

and then we'll say on exception

and then when there's an exception

during logged out logging out what we're

going to just say we're going to say

well you are logged out but an exception

happened all right so let's just say um

there is an exception and we're not

loading okay so that's what you need to

what do we actually have to do we have

and then we also have to emit the new

states that we're going to say you're

logged out and then there is no

exception so i'm just going to grab this

code from there and place it in here and

say there is no exception like that

and it says well this can now be a cons

so i'm gonna make it a const just like

the next thing that we have to do is to

clean up our routing because you see the

more and more we're blockifying the

entire process inside our application

the less we need different different

screens to actually do routing manually

because routing is going to be handled

by our block listeners and things like

so let's go ahead and as the caption

indicates in our routes dart file we're

gonna remove all routes except for

create or update node route so let's

actually before we do that i'm going to

close all the files in here just to make

sure everything's saved then go to route

and remove everything except for

excuse me let's now go now that we've

done that we have to go to our main dart

and we're gonna clean up our routing in

here as you can see we have those four

routes now that we've removed let's just

remove them from main dark file as well

so what we need also is as the caption

captioning case we should show the

register view if auth state is

so in main dart show register view if

off state is registering so i'm gonna

bring up my notes as well in here

so let's go ahead and see what we have

we have auth state logged out what we

have what we also have to have in here

we have to create another else statement

and open your curly brackets um

on curly bracket missing and in here we

just say return cons register view okay

all right that was a lot of work that

we've done and now if you then look at

your files in here you shouldn't you

basically shouldn't have any errors okay

so before testing this all because there

were just so much stuff that we've done

and we've also changed our main function

it just makes sense to do a hot restart

so i did a hot restart let me just

resize my visual studio code so we see

now this is the login view uh if you

look at our login view dart file uh if

you have a look at what we did when the

login button is tapped we're literally

auth block to do this thing in here log

in all right so we're sending a new

event to it so if something happens to

that and things don't work as well then

it says user not found wrong credentials

authentication error then we should

actually get an error displayed on the

screen so let's test this and you can

see it says authentication error so

that's in here okay so that's that seems

and it would be really good if you could

our loading dialogue and see if it works

foobar bads in here and say login

we saw that loading so that was our

loading dialog that was this logic right

here so it's it's really cool actually

how it's working let's go in here and

say log out and log out and then we come

to the login screen so this is all

and you could and if you want to see

your loading screen a little bit more

and like if you're in the process of

debugging it you could always go to your

and inside when you're asked to log in

you could actually a wait so you could

a weight future delayed and you could

say duration and you could say seconds

three something like this okay

so this is gonna await like it's just

gonna wait three seconds before it

continues so let me just save that and

enter some information in here say

google okay it's our gmail

oops that didn't work so well

i don't know why that didn't work so

well even though this is an async

function could this need hot restarting

log out in here and enter foo barba

avant np gmail.com foo barbas and then

login there we go now it's waiting more

than three seconds kind of then it goes

to the application so i would say that

is working very well so we can now

remove this weight in here okay

and maybe do a hot restart as well

that that was a lot of work we did but

that's what you do with software

development sometimes you break things

to make them better you have to break

sometimes the code that you have in

order to build up something better we

didn't really break things but we

we basically removed a lot of old old

code in order to make it and work better

i'm in this course my goal is to make

you a software developer using flutter

i'm not just going to show you the right

thing to do from the beginning we're

going to gradually make things better a

software developer also is not going to

be depending on their experience they're

not going to do the exact right thing

from point one or point zero

they're they're gonna make experiments

they're gonna google a lot of things

look at stack overflow find the right

way to do things get inspiration maybe

from like another product that's kind of

doing something similar and develop

things one step at a time make it better

so that's the reason we're in chapter 40

we've just gotten to this point

otherwise we would have done this from

chapter zero for chapter one so

through us sticking around throughout

this chapter and coming to this point

that we are right now so as this

tradition we're gonna now commit our

code and tag it so let me do some

reshuffling of the screen go to terminal

and like that and i'm gonna shuffle the

screen as well so you see things better

so let's go ahead and have a look at our

git status ginormous amount of things

we've done everything is modified and

there's a new file added so let's say

because if you have a look at our logs

the previous chapter was step 24 so now

so let's then push our changes now that

and then we're going to say git tag

25 as well so and then we're going to

if you look at our tags now we have step

24 and then somewhere in here we should

have step 25 as well as you can see here

congratulations for getting through this

chapter was one of the jumpiest chapters

i would say in this entire course and

that we moved so much from file to file

so if you made it through then

so what we need to work on in the next

chapter is our broken loading screen i

know it's a little bit of an anti-climax

in that we just work on our loading

screen so we should be kind of proud

however there is a problem with this

loading screen and that is because we're

navigator of context and then we're

popping remember popping inside

executing pop invoking the pop function

on your navigator and actually i can

without going into too much details so

let's have a look at our uh loading

see at the bottom of this loading

dialogue we're doing navigator off pop

this doesn't necessarily pop this dialog

it pops the current view on the

navigator so even if our dialog is not

displayed on the screen saying navigator

of is gonna confuse the navigation stack

in flutter so we're gonna have a look at

that and fixing that actually in the

next chapter so grab some tea coffee

chocolate whatever you want to and i'll

see you in the next chapter hello and

welcome to chapter 43 of this flutter

we are now very very close to actually

being able to release our application to

the app store there are just a few

things left sorry app store and play

store and we have a few things left um

to do before we can actually do that and

um one of the most important things we

need to take care of are loading screens

if you remember from what we've done so

far we've been working with block we've

been working with our auth service and

and we also have loading state in some

actually i can't call it loading state

we have loading property on some of our

off states so when our off block returns

a state depending on which state it is

then we can actually see whether it has

it is loading property or not

and we've been working with loading

dialogue so far and there are just

simple dialogues that we're displaying

on the screen with a column with a

circular progress indicator and we also

a size box just to separate the loading

indicator from a text that we're

this has been working okay so far but as

i mentioned in at the end of the

previous chapter we have a bit of a

if you remember from the code actually i

can bring it on the screen so you can

have a look here let's go to our loading

loading dialog at the end of this if you

remember we return a function

and which in turn upon calling which we

pop our navigation navigator

however as you can see there is no

transaction in here meaning that the

navigator can't necessarily know that

what it is popping at the moment is in

and this problem is actually quite big

in that you could for instance have a

loading dialog on the screen and then

while that loading dialog is being

displayed you could display another

screen and push that screen in your

navigation stack and then if you then

try to dismiss your loading dialogue

what you will dismiss in fact is the

second screen that you displayed in the

this process is not transaction based in

that you're playing literally with the

navigate in navigation stack in flutter

and that's not such a wise thing to do

so what we want to do in this chapter is

to clean up our loading screens in the

application and make sure that they are

so now i named overlays and it is a good

time then to explain what overlays are

and why they're good especially for

loading screens um as you know

normal screens that you display on on

mobile telephone for instance or on the

on a desktop with flutter there it

basically placed inside a navigation

stack so the navigation stack is there

to keep track of which screen is

displayed and then which screens you can

and so they have a hierarchy however if

you want to display something on top of

the navigation stack independent of the

navigation stack and the various changes

that could happen to the navigation

stack you could use and you probably

actually should use overlays either

directly or using other material

components that are provided by flutter

that in turn use overlays so

overlays as their name indicates they

have they have the ability to place

themselves over other content that is

currently displayed on the screen so

there and that makes them the perfect

candidate for loading screens for

instance because loading screens are

usually displayed on top of the current

content that the user is looking at so

in this chapter we're going to focus on

using overlays to improve the state of

our loading screens in the application

now before we actually get started

writing the uh our loading screen

um what we need to talk about is a

controller uh as its name indicates a

controller is an object usually that you

and using this controller usually an

object that receives that controller is

able to control either the contents or

the behavior of the object that

is being displayed on the screen for

so imagine a scenario where you have a

already appearing on the mobile device

and you're telling the user wait while

i'm logging you in now imagine that you

want to kick off another process while

that is ongoing and you want to display

a loading screen again to the user while

the previous loading screen is already

a typical way of doing that would be for

instance to dismiss the first loading

show a new loading screen with the new

content and when you get rid of the

second loading screen then you can

display the first loading screen again

as that process is ongoing however this

it is quite a bit of a race in that you

have to know the previous context what

loading screen was displayed before what

loading screen you're displaying now

loading screen before you have to

display it again so it's not so scalable

in that you will personally then be

responsible for keeping track of the

state of your loading screen so what

we're going to do in this chapter is to

create a loading screen that is a that

is able to be controlled and its text

and contents is going to be controlled

upon creating that loading screen we're

then gonna get a loading screen

and this loading controller is gonna

allow us to one dismiss the current

loading screen that is displayed on the

screen if any and then secondly it's

going to allow us to update the contents

so without further ado we could actually

start by having a look at creating this

loading controller and or loading screen

controller and then we're going to use

this loading screen controller where we

create our loading screen so as usual

i'm going to do some reshuffling on the

let me make the code bigger here and

then the font a little smaller

and let's then actually here i i'm

pretty sure that we don't need scr cpy

we're not gonna have a look at how that

loading screen looks which looks like

right now we're gonna write quite a bit

of code and then we're gonna put it into

i'm gonna make visual studio code full

and i'm going to get rid of this bottom

okay so as the caption indicates what

we're going to do now is to go ahead and

create our loading screen controller

loading loading screen controller and

let's go in here and have a look at lib

and we can see we have lib utility

service access you know constant views

but we don't have helpers so i'm gonna

right click on live and just say new

file and then i'm going to say helpers

and so that you can also see it here

and loading and then loading screen

so that's going to create the

folders for us as well so you can see

now we're under lip helpers loading

loading screen controller okay

so what we need here as i mentioned

before is the ability for us to be able

to control two things to close the

loading screen and also update its

contents so let's go ahead and define

these type def so let's just say type f

and we're going to call it close loading

that indicates whether the loading

screen could actually be closed or not

okay so it's just a function definition

for now there is no implementation of

so let's also go and create a type f

and we're going to say update

and this is a void function and actually

a bool function which will also indicate

whether the text could be updated and we

just say text so what we're saying in

here we will have two functions that

interface basically soon as you'll soon

let's then go ahead and create a class

and we call it loading screen

indicator or sorry controller

and let's mark this as immutable as well

and for this we need material so

um actually foundation would do as well

so let's just go in foundation and in

here i'm actually going to say show

immutable just like that so we just need

the immutable part of the foundation

okay so that's the definition of our

loading screen controller so what it

does is that it basically it takes in a

closed loading screen as a parameter and

and we also say final update loading

updates just like that and i'm going to

get help from visual studio code to

complete this as a constant constructor

and i'm going to make these parameters

also required so these things we've

talked about so much before so that's

why i'm kind of jumping over them as

fast as possible hot reload is not

working so well right now it's just

because the application on scrcpy is not

on the screen and that's why hot reload

isn't working so well so i'm going to

just jump to the application and now hot

reload works and then i'm going to put

scr cpy on another screen so it doesn't

okay so that's our controller so

we're then gonna work on creating a

function that can display the loading

screen and that function itself is gonna

return a loading screen controller to

you so that's the beauty of that

function using the controller then you

can close the loading screen or update

it so you can see that these two are

basically functions that the call side

can accept and call in order to close

and update the loading screen

all right that was the loading screen

controller what we need to do now is to

work on the loading screen itself so

um let's go ahead as the caption

indicates we're gonna go to lib helpers

and we're going to create a new file

inside loading and let's just call it

and inside loading screen we're just

going to create a loading screen

and we're going to make our loading

a singleton and since we've done

singleton twice before i'm just going to

basically paste the pattern in here so

we don't have to write this

boring code again but this is a pattern

that we've done so far twice as i

mentioned before so you should basically

know how it works so we have a private

constructor then we have a factory

constructor which is public which in

variable which in turn calls the private

it's just a bit of a we could actually

do it like this in so this is in order

basically so when someone calls our

loading screen constructor factory

constructor from outside in turn calls

this and this in turn calls this so it's

a it's a layer base it's three layers

okay so what we're going to do in here

we're also going to keep pulling up our

loading screen controller and so let's

go ahead and send loading screen

controller as you can see it's going to

also import it for me so i'm just going

to say loading screen controller and

let's just say it's optional

because we might not actually have it

and um then what we're gonna do in here

we're gonna have a function called show

then we're gonna have a few more

functions there that are gonna allow us

to control basically our loading screen

and i wonder which one is actually best

it could be that we should be working

show overlay function so let's go ahead

and do that so let's say that we are

going to have a function on our loading

screen um class and we're calling it

show overlay so and this show overlay is

then in turn going to return an instance

of loading screen controller so let's go

ahead and start writing that so loading

and this function has a two required

parameters so i'm going to put curly

bracket in here a curly bracket in here

and let's just say we need a build

context so build contacts and

it's going to auto import from material

so that's great build context

and require parameter build context and

i'm just going to call it context and

then upon you wanting to show an overlay

you also have to specify its text so

what we're saying in here is that an

overlay can't be displayed without an

actual text in it okay and remember

we're using the word overlay but in this

case our loading screen is going to have

a custom overlay with some material

components like a column and button etc

etc okay so show overlay in this case

means show the loading screen with this

so we call it that and then let's go

ahead and basically say this is a string

of text just like that okay

perfect so that's fine so now what we're

going to create now is um we're going to

new strings that are provided by this

controller remember we created this

thing so if someone updates the loading

screen text we're going to put those

strings inside a stream controller so

let's go ahead and create a final

so we'll say this is a stream controller

control controller of string okay

we just create that and it can't find

stream controller so i'm just going to

say import lib dart async so that's

another import um right here which you

might have to do by hand if you don't

have visual studio code or if you're not

using for instance a text editor or id

that can also import things for you

stream controller is available in dart

so then the first thing we're going to

do is to add the current text

our stream controller so this text

parameter that was provided to us we're

going to put it inside the stream

what we need to do is basically

use a new function that we haven't used

before which is called overlay of

if i look at if you look at the return

of this it will return something called

an overlay state and it says the state

from the closest instance of this class

that encloses the given context so we

need this state in order to be able to

display our overlay so let's just grab

this overlay of context and put it

and then what we're going to do is

since overlays are kind of displayed on

top of everything else that's on the

screen they don't have intrinsic sizes

as such so if you're using with if

you're using for instance material

various widgets inside your flutter

application if you create different

containers buttons they have some sort

of intrinsic size in them however with

overlays you kind of have to grab like

state of the current screen and what

components are displayed on and

available with the available height

to basically base our overlay on top of

so let's go ahead and grab our render

and i'm going to say using this context

and we're going to get find render

like this as a renderer box okay so

there's lots of documentation available

about what render box is but it is kind

of like low level and i'm not gonna go

into so much details about that but

let's go actually have a look a little

bit here as you can see it's a render

object and it is quite low level as i

mentioned inside rendering box and what

it will do it will allow you to

basically extract the available

have on the screen so let's go ahead and

create a final size in here and say

about size okay so that's that

then what we need to do we actually need

to now create our overlay so our overlay

and you may think oh this is the overlay

because we call it overlay here well

it's not really because the overlay is

in in this context that's overlay of

parent overlay uh context so

uh what you are going to create in your

application is actually called overlay

entry so um but when when we say we're

going to create an overlay what we

actually mean is an overlay entry okay

so let's go ahead and create an overlay

entry in here so we're gonna say final

overlay is overlay entry just like that

and then we have a builder function

now i'm gonna get visual studio code to

complete this it needs a context all

right so let's go in here now

overlays they don't have a parent like a

scaffold or anything so if you don't

like this component that you return from

your builder which should be a widget

let's go in here you can see it's a

widget if you don't wrap this inside

some sort of a material component such

as scaffold or material itself your

overlay is going to have horrible

styling because it's not going to have

any default system styling so excuse me

what we're going to do in here we're

going to return a material component

and material is going to allow you if

as a documentation of material it says

i mean okay um but what it basically

means it is actually let's have a look

at this code maybe that makes more sense

uh is a stateful widget so it will

create a stateful widget for you which

has some default styling so you can put

your components in there and they'll be

style according to the system skin okay

so let's say that we are going to give

the material which is going to cover the

entire screen this material component

that we're returning here is going to

cover the entire screen remember so

let's first paint the entire screen with

kind of like a dark color as you know

when you display like errors or

dialogues to the screen to the user

usually what they do is like they paint

the background the entire background

kind of like a dark color so then they

can display their dialogue in the middle

of the screen and kind of give it kind

elevation so it kind of it pops out of

the screen a little bit so what we're

going to do in here we're going to say

color the color of our material uh

staple widget in here is colors black

and then the child of our material then

it's gonna be a center okay so that's

what we're gonna create here so

let's then go in here and what we're

going to do is the child of this is

going to be container so i'm just going

to create a container here and then put

a semicolon there and it's happy now

so then our content container is gonna

place some constraints off on our

overlay so it's gonna say for instance

that its max width and height should be

a certain value so we haven't used this

before but we're gonna now use something

called constraints in here and you can

see the value of constraints is of type

box constraints so let's say constraints

and then we say box constraints okay so

we're going to start with max width

so then we're going to say size width

multiplied by zero at that eight and

what we're basically saying here saying

this dialogue that we're displaying to

the user is going to consume at most

eighty percent of the available widths

on the screen so this is our way of

creating some margins to the right and

left for those of you who are web

developers and are like know about

and even if you're a web even if you're

a designer you'll probably know already

about margin so what we're saying is

that this container needs to wrap itself

around its contents but if the contents

grow it's gonna go at most eighty

of the available width and this width is

coming from our render box okay

so that's that and we're gonna do the

same thing with max height so we're

going to say size height multiplied 0.8

and then we're going to give it a min

width of size with multiply 0.5 so we're

going to say at least it should it

should grab um half of the screen width

then let's give it some decoration so

we're going to say this is box

decoration so let's go in here

and so this is just to give it some um

border so uh usually dialogues or in

this case an overlay that we're

displaying to use or they have some sort

of a border so it creates this kind of

like a beautiful elevation so if this is

the dark background in here which we

created with black of alpha 150 then we

have an arc basically overlaying here or

overlay um we call it here as you can

see overlay entry then the overlay entry

will be placed here but it will have

separate it from the background okay so

this is just a technique to separate our

overlay from the background

so we're going to say the border is

our sorry color is white and then we're

going to say it has a border radius

all these documentations on the screen

are just driving me crazy and border

radius.circular and let's just give it a

circle value of 10 in here okay

sometimes documentation is just

so let's stand in here as you can see

now we have an empty container we should

never do that so let's go in here and

just create a child for it so the child

in here is going to be a padding

so um or maybe we could just say single

and then i'm gonna embed the single

child scroll view inside padding that's

that's my preferred way of doing this so

just like that and let's just give it

so the reason that the child of this

padding that we created here is a single

child scroll view is as you remember we

said the max height of our overlay entry

is 80 of the available height on the

your just your application display on a

then you're displaying a lot of text

well if you don't put your contents in

the entire contents of your material

widget inside a single child scroll view

then your content is going to be

basically chopped so the users are not

going to see the content in its entirety

and what single chat scroll view does is

that it tries to not scroll its contents

if the content has enough space to be

displayed on the container but if the

contents overflows the container's

height for instance then it's going to

allow the user to scroll on that

container so it it works perfectly trust

so let's go in here and then go and

inside the single chart scroll view

create a child and in here we're going

and our main axis size is going to be

main axis size of minimum because

remember if you don't give a main

exercise a minimum pure column your

column is going to grab as much space as

it can so it's just going to expand as

much as it can and if you say main

exercise is minimum it's just gonna

hug its contents as much as it can

and then we're gonna say main access

alignment is main access alignment of

center so it's also going to place its

contents vertically in the center okay

then what we're going to do in here in

column children so let's go in here and

say children then let's create a size

box um and give it a height of 10 so

we're creating some top margin from

um from top of the column so this is

saying that we have a column we're going

to put some stuff in it but give it 10

emptiness on top so it just creates a

little bit of a margin okay and look i

fully understand that this is a lot of

abstract stuff it would be a lot nicer

if you could actually see this on the

but sometimes when you're programming

especially in flutter since it's so

declarative then you have to kind of use

your imagination on how this thing is

actually going to look like on the

you could do a lot of experiments and

test this for your for yourself and just

maybe just even do this don't do

anything more than this just use a size

block on the size box on the screen and

just display it overlay and see how it

looks like that also works okay

and right after this let's go and create

our const of circular progress indicator

so that's going to be a little indicator

that sits there and displays that

and then we're going to give it another

size box with a height of maybe this

time actually 20 and so this creates a

and then what we're doing in here we

and but that text could change because

that text is placed inside the stream

controller so we're not going to use a

stream builder so let's say stream

there so what we need to do basically is

to grab the stream from the stream

controller and use it inside our stream

builder and then i'm going to help from

visual studio coding here and say that

the builder function should be like

and if you remember we could use a

getter on our snapshot that says has

data so let's say return or sorry um you

say if snapshot has data then we're

going to return a text in here okay

and the text basically is it's the text

of the text widget is going to be the

snapshots data as string we know that it

and also we are going to give it a text

alignment of text align in the center

so that's that part and let's put a

and also we're we're getting this error

right now because we're not returning a

widget in all the available paths inside

this builder and we have to put an else

and otherwise we just can return a

container as you can see in here okay so

since we have to return something we

could just return an empty container for

i mean you could also solve this in

another way for instance say okay if the

snapshot has data i'm going to return a

text like this or otherwise i'm going to

like an empty text like this

you could also try to do that but right

now we're just leaving it as returning a

fold this that we created in here which

is our overlay we've just created the

overlay that doesn't mean that we're

displaying it so the way to display an

overlay is to use that overlay of which

created an overlay state and say insert

overlay okay so this actually adds our

overlay to the entire overlay state that

flutter manages on the screen so

so now we've done that so what we need

to do then upon upon this happening we

take our return statement and that's why

basically loading screen dart file here

in visual studio code depending

depending on your editor or id that

you're using you may or may not see this

screen as having an error but if you

scroll up in here it basically tells you

that well you're not returning what you

said you should return so let's go in

here and create an instance of loading

and we have to take care of the close

and we have to also take care of the

update but let's take care of closed

first so it's an empty function

and the only thing it should do is to

have a look at our stream controller and

and then we have we go to our overlay

that we just created and basically

and also we just say yeah we returned

through from this okay and now we're

getting an error in here saying update

it's not provided so let's go ahead and

create update as well and if you

remember from update uh what it does it

actually takes the string as a parameter

in here the only thing we have to do is

to add that to our stream controller so

i just noticed that you can't see the

let's add that and just return true and

to be honest with you you could just say

well let's just not return any value in

here you could do that as well but i

um function signatures so that you can

also indicate an error to the call site

you may try to get rid of these

yeah let's go ahead and do that if you

want to but i'm just going to leave it

like this in case we want to extend this

functionality in the future so that we

can return false if things go wrong okay

all right that was the uh let's say that

was our show overlay function so that's

let's then go ahead and create a

function in here that we're going to

call also height now we have show let's

so let's just say void hide like this

and what we're gonna do in here we're

gonna take our controller like this and

if it's there we're just gonna say close

okay remember close the way it was

closes the stream controller for text

and it also removes the overlay and

returns true so that's gonna if there is

a controller available on the screen

then it's gonna return that okay sorry

so um and also we're just gonna say

so and the point for us is that to show

to use this function internally remember

this this function is going to return

this loading screen controller which

we are soon going to place inside this

controller variable at the moment

control variable is always basically

all right that's great stuff so now

we've taken our taking care of hide so

now that we have hide let's go and

create show so we say show and then we

two required parameters so let's say

required build context build context

and then we say required string text

okay so anybody calling this function

has to provide these two parameters and

they're very familiar because they are

the parameters needed by show overlay

so let's go in here and we say if we

have a controller um if we can actually

use this controller's update function in

and we pass the text in here or false

so now you probably are like starting to

see why i'm returning true from this

function and that's because well if you

don't have a controller then you can't

code you have to write shorter because

otherwise you'd have to do like this if

then you would have to update but in

here we're just saying either update the

if we could update the controller's x we

just return because that means well we

already have a controller on the screen

a an overlay controller so we could

update its text so show should just

return right after that it shouldn't

display a new um overlay otherwise we

create and we basically create a new

overlay using this show overlay and

assign it to our controller

our property on top so we say this is

all right fantastic so that's pretty

much all we have to do and for our

loading screen.dart file so we could

just save this and i'm just going to

save this file as well and close it

so let's talk a little bit about our um

and if you remember from our off state

and for instance here we have off state

logged out and that has a has is loading

um property in here but if you look at

for instance needs verification or

they don't have is loading so

what if we added is loading to a higher

level here to our off state so any off

state in our application could

potentially be in the loading state as

well so that means registering could be

loading logging could be loading whoever

wants to could have loading

and that's exactly what we're gonna do

now so i'm going to go to my notes as

let's go ahead and add these

parameters that we have at the bottom of

the screen to our off state okay so i'm

and also let's say final string

loading text something like this

undefine class build sorry about that i

just programmed so many different

languages um at final and they're so so

different every language is kind of like

they have their own data types and

typescript has their own lowercase data

it's just a mishmash of various

different types i just wish we could get

along and have like one standard for all

data types at least the primary data

but that's just wishful thinking maybe i

digress let's go ahead and add these

and let's go ahead and do this make

these required parameters so we say it's

it should uh this should be provided is

loading but the loading text doesn't

need to be provided we'll always have a

default we'll say please wait a moment

uh and we should close this have i not

so that's adding these two parameters to

our um auth state and loading text

always has a default string okay

so let's go ahead to auth state

uninitialized and add is loading in here

bool is loading so now that we've done

that we should actually you see now what

we're getting in here is saying that

wait you're not calling your super

because it's a super has this is loading

parameter in here that you need to

provide because it's required but you're

not doing that so let's go ahead and

actually add that parameter to our cells

and what we're doing here which is

called super and we say is loading is is

loading as is provided to us okay

so that's for uninitialized

um now let's go to registering and do

the same thing in in there so we're

going to say for registering we actually

have exception required so let's make

is loading required so it is loading

okay and let's call super is loading is

auth states logged in at the moment

we're getting taking the user

and you see i'm making these parameters

if you don't make them required as soon

as you go to two parameters three

parameters for creating a cons for

an object using this initializer then

things start to get messy because

they're not named parameters otherwise

so passing three unnamed parameters to

an initializer to me is just it's just a

little bit difficult to understand so

that's why we're making them required

so let's go in here and make this also

name parameter required if i can spell

and then i'm gonna say required uh bool

uh required bull is loading all right

like that and then let's call super is

loading with is loading all right

so that's for off state logged in

now we need to also think about off

state needs a verification and we're

just gonna take is loading in there as

so let's go ahead and say needs

verification also has a required

bool is loading and we're gonna do the

same thing super is loading it is

loading so all we're doing is that we're

making sure that every state has and is

loading and that is loading is passed to

the super class called off state all

and then we need to take care of also

our off state logged out so

you see at the moment we have a little

problem in here and it says don't

overwrite fields thank you dart and that

means basically it's loading is already

implemented on the super class so we

could just safely remove it from here

is loading and actually required bull

and also we take in a string of um our

now that that is like that we're just

gonna call super and say is loading is

equal to is loading and then loading

text is loading text just like that okay

and then put a comma at the end of this

perfect all right so that is basically

saying that we may want to customize the

off state logged out loading text

because we're taking it in and then

passing it up to the super whereas the

others are not allowing us at the moment

loading text so that's why we have

string loading text only for off state

locked out and not for the other classes

so that's that so we've already

basically taken care of this caption as

well so we've added loading text to our

so now we need to save this file and

just go back to our off block in here

and you can see now we have a little bit

of a problem in here so let me also go

to my notes so i can bring up my notes

auth state uninitialized in here and

what we need to do is say when the

application opens when you the

absolute initial state of the

application should be in the loading

state so we should say it's loading true

so that's that part we taking care of

so i need to what we need to do now is

to take care of as you say update off

state logged out in off block so

and we can have a look in here let's see

if we have logged out anywhere yes and

it says add is loading true to off state

so um i'm gonna have a look here and see

if we can actually find that so that's

and that's fine and then what we're

gonna do in here we're gonna say loading

and let's say please wait while i log

you in something like this okay

that's off state logged out that's the

first thing that we have to do and let's

see where else we're using off state

yes and that's fine that's fine

so maybe that was the only place that we

actually had to update our log state uh

i don't think we have anywhere else that

off state logged out has to be set to

true except for when we're actually

and i believe that we've done that now

so off state logged out is there with is

loading true there so that's that's the

only thing we have to do okay

the next thing that we have to do is to

add is loading to other states in off

block so let's start from where we're

getting all these errors so we have

excuse me off event initialize so i'm

going to find that in my notes in here

and in these cases when we're emitting

auth state needs verification we should

just say is loading false because you

when we actually end up in this state

we're not loading anything we've already

done the work that we were supposed to

and that's sufficient basically in here

so here we have the user so now this is

a required parameter named parameter so

it has its user and then we're going to

and in here we're going to say false as

well so command here to make the code

and let's then go ahead in here which is

this problem at the end which is off

and when we've emitted this off state

needs verification is loading is also

false so pretty much is loading is false

except for when we're actually loading

which is for instance uh let's see

when we're actually logging in for

instance okay so when we have the user

in here we say user is a required

parameter and is loading is false as

and just looking up and down this file i

can see we also have a problem off event

register so let's go to auth event

excuse me and let's just say auth needs

verification is loading is false as well

and in here we have an exception name

parameter i believe and they require

parameter and then we say is loading is

false as well so just a comma in there

to get the formatting working

and that is working as it should so we

shouldn't have any errors basically in

our offline at this point all right

so then i'm gonna close that file

what we need to do as the captioning

case we need to go to our login view and

remove everything that has anything to

loading so let's go to a login view

and at the moment you can see we have

this closed dialog close dialog handle

all that stuff so we shouldn't do any of

that so now you see the point of what

we've done is for our application to be

the loading dialog just in one place

loading dialogue should be handled in

one place in the entire application

that's what we're trying to do we

shouldn't have loading states and

loading like handling loading and or any

dialogues and that has anything to do

with loading in various views inside our

application so that's what we're trying

to get to okay so let's first go to this

close dialogue handle and remove that

because we're not going to need that

anymore and then let's go in here and

remove all this code inside your login

view dot dart file that has anything to

do with loading so now you should just

have exception handling all right

here have a look at what we have you can

see at the moment we have a block

builder inside the main widget of home

page in in our build function we have a

block builder but what we want is to

changes to something that has a loading

in it okay so you see this state at the

moment is off state but inside there

this state could have is loading set to

true so how do we handle that remember

block builder is not supposed to have

any side effects that's the job of the

however we need the block builder we

actually need to return something in

different views depending on the current

state but we also need a block listener

so how do we do this how do we fix this

well the the solution is using a block

so a block consumer i've mentioned this

builds on top of a block builder and a

block listener so it allows you to do

both things at the same time so if you

ever end up in a situation or

application where you want a builder a

blog builder and you want a blog

listener block listener at the same time

there is where you need a blog consumer

so let's go in here and say that in our

main file i'm going to go to my notes as

we don't have a block builder

and now we have listener in here and

what we're going to do in here is say if

then what we're going to say is we're

going to say loading screen and it also

imported for me okay and then we're

okay we have the context already and

then we either take the state's loading

text or we say please wait in a moment

so if the state's loading text is not

available we just use a default one in

so if the state is not loading we just

dot height all right so that's that so

now that we've done this this is pretty

much like the last building block that

we have to build inside this um inside

this application for now so i'm just

going to close this main dart file and

resize the screen let's go ahead and

and if i dare i'm gonna hot restart the

application entirely because we've done

and let's go ahead in uh just for

experiment i'm gonna go into

what is it loading okay i'm just gonna

in firebase auth provider inside this

like this we could basically have a

little bit of a delay so because

otherwise we may not actually see the

our little uh overlay so i'm just gonna

first not do that and try to log in

you saw did you see our little overlay

there so i'm going to log out now and

but if i try to now put a little bit of

a delay in here so i'm just going to say

delayed the rate const duration

and just hot restart the application

my normal credentials foo bar

and press the login button and this is

right and it has the ability for you to

actually update its text as it's

then yes everything is actually working

as it should so now we have an overlay

we don't have our loading dialog anymore

so you could safely basically go and say

well i want to get a complete rid of

the loading dialog so i'm going to leave

as now that we did we don't need the

loading dialogue so what we achieved in

this chapter is actually huge because we

now have a loading um screen that is

independent of the entire application

and it's in just one place that's the

goal we don't have many different places

in our application that are handling the

so let's go ahead and make sure we're

not going to lose our code our precious

code that we've written so far so i'm

gonna rid of i'm gonna get rid of scr

cpy increase the size of the screen

and let's go as we usually do and commit

and tag our code so if you look at our

logs the previous commit was step 25

everything and say git commit

i'm going to push these changes and

but if you look at our logs now so we

have step 26 in here and if i scroll a

little bit step 25 is before it and all

the tags are also available in here you

can see 25 and 26 available right there

all right so we've done what we promised

to do at the beginning of this chapter

and we created a great overlay that we

can reuse in the in the application and

just show and hide only in one place

so what we need to do now is the very

exciting stuff in that we're getting

really close to being complete with our

application so we have login register

email verification we have loading in

screens we have sharing deleting it's

just we have pretty much everything for

we still have some little bits and

pieces left to make the application more

useful because remember when you create

your application and send it to apple

and google for review there's actually

going to be real people who sit there

and interact with your application to

see if they can make sense of it so we

need to clean the ui up so that it's a

little bit more user friendly and that's

exactly what we're going to take care of

in the next chapter so i'll see you

there hello everyone and welcome to

chapter 44 of the swata course in

previous chapters we've been basically

working quite a lot with block and we've

been making sure that our applications

loading screen is working so we have one

place in the entire application that

we're taking care of the loading screens

and we also have wrapped our whole

authentication process inside a block

and we're very now close to being able

to release our application to the app

store apple's app store and google's

this is usually what we do as software

just before releasing our product or we

basically go and clean it up as we say

so we put some final touches to it so

even if you're a designer you usually do

that probably like if you're working

with figma or you're working with sketch

you first are like designing your

product and then before you present it

to the product owner or the developers

you probably put some final touches to

it so um that's what we're gonna do in

this chapter and we have um a few things

also left to do which have nothing

really to do with the final touches to

the ui it's mainly to do with the

products functionality and we'll talk

so if you think about it what we have at

an application that a user can register

they can't send an email verification

they can log in and they can go into the

list of notes that they have they can

create notes delete notes and edit and

share notes however we haven't really

exposed a functionality for a user to be

able to reset their password so

imagine a process imagine an application

where you've created it created a user

in the application and you forgot your

password and there's absolutely no way

for you to get back into the product or

the software and because you just don't

may then have to personally contact the

application developer and say could you

reset my password so it's a very very

difficult process to do manually and you

shouldn't really do that so what we're

we're going to do in this chapter is not

only to do final ui touches but also

we're going to create a password reset

functionality into our application

so let's get started with that i'm going

to do some screen reshuffling in here as

you can see in the cache we're going to

go delete all users in firebase console

i'm going to bring up console

firebase.com and i'm going to bring it

to the main screen in here

let's find our application i believe

it's this one and i'm then gonna go in

to a firebase date the firestore

database and let's start by

these documents so let's say delete

document and we have four documents so

just one at a time we delete these

and those are our documents gone so you

could just keep your collection i think

it's best because our application at the

moment is assuming that there is a node

if you remember from our node service

so that's that part we deleted the data

but we haven't really deleted the user

so let's go off to authentication

and in here i'm just gonna say delete

and let's just delete this account as

well so now we're basically starting off

fresh so no users and no data in the

so that's that part let's do that i'm

going to then bring up our source coding

my notes application as we've called it

so that's visual studio code i'm going

to resize it a little bit and then i'm

going to bring up scrcpy as well which

has our app running at the moment and

the application thinks at the moment

because it hasn't really communicated

with the back end yet so i'm gonna just

do a hot restart in here and this is

this is the problem that you'll

sometimes actually notice in the in your

firebase isn't gonna immediately

understand that this user doesn't exist

on the back end anymore so if you delete

a user from your firebase backend it

doesn't necessarily mean that it's

immediately going to be reflected to the

application so let's see what happens in

here if i then log out with this user

like this and then try to log in with a

user that used to exist in the

application but i just deleted it foo

and let's see what happens in here and

now you can see we see we say user not

found okay we're gonna clean up that

message as well soon in this chapter

so good we have a clean slate now so we

have no users and no data in the

so what we need to do now is to start by

defining our events and states for

forgotten password okay so if user says

hey i forgot my password we have to have

so that we can send that event

so you can see in here we have to go to

auth event dark file and add an auth

so let's go ahead and do that so i'm

going to open off event dark file

over log out in here we're just going to

say class i'm going to increase the size

in here as well obviously better

class um off as we've said in the notes

here off event forgot password extends

and in here we need to grab the user's

like that and i'm gonna create a

constructor for this as well just like

or here with curly brackets okay

all right so it's a name parameter now

um and we just said auth event forgot

fantastic so that's that part um then we

also need to go and define a state

because when a user presses a button for

instance saying i forgot my password

then our off block is going to produce

that state and say hey application that

your state right now is forgot password

and then in the main dart file as you'll

soon see we will go and edit and add

that state to our state handling as you

can see in your main dart file

the moment we have all these states but

we're going to add a new state that says

else if state is off state forgot

password then display a forgot password

view which we're also gonna develop soon

as the caption indicates let's go and

let's go to the file off state dart file

and i'm going to do that in my notes as

well after registering it really doesn't

matter where you place that code i'm

just going to place it here after

and just say off state forgot password

and then we have to also take care of

what should the state actually indicate

let's say that when you're in the forgot

password view which we're soon gonna

um there could be two things that you

wanna convey to the user in that screen

either the user has just landed so there

are actually three three states that

either the user has just landed on that

screen meaning that there is no errors

nothing we haven't done anything so it's

just a clean slate so that's the default

of off state forgot password so nothing

however what if the user has actually

send reminder email because you see the

way we're going to handle for a password

is we're going to actually ask firebase

and say firebase this user forgot their

password with this email send a reminder

email to them or send some kind of like

an email to them that they can't

actually reset their password

so upon user pressing that button to

send a reminder email to their email

actually two things that we're going to

we tried to send an email but it didn't

succeed so kind of an exception so

that's the second state remember no

second state is there's an exception and

there's a third state that there was no

exception but we've actually sent the

email so three things we have to handle

so the default state with no values is

state number one nothing has happened

state number two would be actually

having an optional accept exception here

has sent email like this okay

so let me go ahead and create a

constructor for these i'm not gonna

explain this again because we've talked

about this quite a lot and i'm gonna

make these required parameters okay just

and put a semicolon at the end

and in here we're just gonna call em

we're gonna call super but remember from

super off states has a constructor here

that has to provide is loading okay so

in in this case let's just actually take

a bull is loading as well as a parameter

and then we're gonna pass is loading to

our super as well just like that

when we're actually working with this

auth state for that password we can

actually give it is loading parameter

and that's going to get delegated back

to off state so our main dart file is

going to be able to display a loading

screen if is loading is true if you

main dart file we have this beautiful

block consumer with the listener that

that looks at any off state and as long

as this auth states is loading parameter

is true or that auth states is loading

variable or property is true then it

all right perfect so now we've taken

care of off state so we didn't make any

changes in main dart file yet okay

all right what we need to do is now go

to our um auth provider dart file and

define an interface function for sending

i'm gonna go and do that right now auth

i'm gonna do it here as well off

so let's go ahead and define a function

that every auth provider including our

firebase auth provider has to conform to

okay so let's say this is a future

point and we call it send password

reset like that and we have a required

string parameter to email just like that

after defining this you'll understand

now soon that we have a few errors

because auth service conforms to auth

and so does firebase auth provider but

we're gonna fix these soon okay

so as the caption indicates let's go to

firebase auth provider in here and

actually implement that so i'm gonna go

and i'm also going to go here on the

off provider and you'll see an error in

here in visual studio code you can

actually get help from visual studio

code to complete that missing overwrite

for us you can see create one missing

override and this is basically saying

that you're conforming to auth provider

but you're not actually overwriting all

the functions that boss provider wants

you to override okay so if you're

working with vim or if you're working

with sublime that doesn't for instance

plugin then you may have to override

that function yourself but the signature

of that function is very easy you can

just go to auth provider and grab this

override before it okay so that's

completely fine as well but since i'm

working with and this is asking me to

save this file but there's pretty much

nothing that i did in this file already

so since i have visual studio code i can

ask it to create the missing override

for me and it's gonna probably create it

right at the bottom in here okay so

so let's put this whole thing into a

catch block so i'm just gonna say catch

all right and then if anything happens

during this process of sending a

password reset email to the user we're

a generic auth exception in here okay so

then um and also if you're wondering

about this syntax this is just like you

ignoring an incoming variable in swift

and in rust and some other languages

like python you could also do something

like this that you ignore an incoming

variable using underscore but in dart

it's not really you ignoring ignoring

the variable it's you naming the

underscore but i try to sometimes use

this just to indicate that hey i don't

care about this variable okay but just

know that internally you're not ignoring

it you're just naming it underscore okay

so let's go in here and and now ask our

provider so um so we just say await

since we're in firebase auth provider we

can actually say wait firebase off

oh and we have to mark this function as

async otherwise we can't use a weight

and then instance and then there's a

function called send password reset

email and it it says to which email and

we're gonna say to this email okay

all right so that's our catch in there

but we also have to have another catch

that is that catches firebase off

exception as we're doing in many other

places so let's have a look

um here for instance okay so let's go

before this catch and say on firebase

catch e something like that

and then curly brackets and curly

brackets close so i'm going to bring

this code up so we see better

so there are two things that we have to

handle two codes that we have to handle

as you can see we're handling a few

codes in here for instance user not

found wrong password and these things

i haven't really found the correct

documentation for these things like

where firebase has documented that these

errors are going to happen with these

codes it's mainly that i found them out

through experience just like trying

different things and seeing that things

fail and upon failing i caught their

error code and now i know which error

codes i had to actually have to handle

but if you search on google i'm pretty

sure you're gonna find some good

documentation about a firebase and the

google team are great at documenting

so one error that we have to handle is

called firebase auth invalid email and

the other one call is called firebase

off user not found so let's first

grab the um error code so i'm just going

to say switch e code in here because

any firebase auth exception that comes

from firebase has a code of type string

as you can see here and that's that

string that we're interested in so let's

handle firebase auth invalid email for

and then in this case we're just going

to say throw um invalid email off

we already have this defined from before

in our off exceptions here dark file you

and the other case that we have to

firebase auth user not found so it's a

user it's like anyone asking for a

reminder email for their password and

that user just doesn't exist in the

database so then we have to handle that

case as well it's called user not found

just like that okay and then we're gonna

a user not found off exception

in any other case of firebase

authexception we're just going to throw

generic off exception just like that

and we're going to save this file

fantastic so we fixed firebase auth

provider but if you look at your project

explorer you still have a problem in

auth service because if you remember

auth service also implements auth

provider but it delegates all its

responsibility to its auth provider

so let's go into our auth service and

implement the send password reset

functionality so i'm just going to go in

and get a visual studio code to complete

this with command dot on mac or control

dot and linux and windows and just say

create one missing override okay and in

here i'm making this an arrow function

because i believe every other function

we've done in here is an error function

all these functions inside all servers

basically delegate their functionality

which is given to it inside its

so let's go ahead and create an error

function and in here just delegate this

to the provider and we just say provider

verification and in here we just say um

send password resets actually called

sorry provider send password reset to

email to email just like that

all right and let's just save this file

is to actually handle our auth event for

god password in the off box so

i understand there's lots of like

jargons that are flying around here so

you may just be a bit confused about

okay what are we actually doing so what

soon what we're going to do is to create

say forgot password so when the user

lands in the login screen they may be

like okay this is my email but i

actually forgot my password so they have

to have a forgot password button

upon them pressing that button

in the login view we're gonna send this

event to our off block so if you

remember from our off event so i'm going

to go back here you don't have to go

here if you go to our off events you can

see we have an auth event forgot

password so the goal is for our user

for our user interface to send this

events to the auth block and then off

block is going to calculate its state

so let's go now into our auth block file

and i'm going to do that here

in my code as well and we're going to go

this functionality here forgot password

like this and let's go and say on off

forgot password just like that and you

quite used to this syntax emit

and this is going to be asynchronous

function and just uh curly brackets just

like that so this is like the bare bones

okay now we're handling off event for a

god password so what we're gonna do in

here is we're just gonna say

uh by default we're emitting

off state for a god password

exception is null has sent email is

and it's loading is false so what we're

basically saying in here is saying by

the user pressing the forgot password

button what we're doing is saying

yeah go to the forgot password screen

that's all that's all we're saying okay

because then our main dart file is gonna

handle this it's gonna say okay if this

date is forgot password i'm just gonna

go to the forgot password screen okay

so then what we're gonna do is we're

gonna extract the user's email from this

event if there is an email in there it

means that the user was in the fargot

password screen and actually press the

button to send a forgot password email

if that's not the case then we know that

all the user did is just to go to that

screen so there is no email to handle so

let's just say final and if i can spell

final email is event email and we say if

email is null then we just return

meaning that yeah the user it seems like

the user just wanted to go to the forgot

if that is not the case so let's just

put a comment in here user just wants to

and if we end up in here in line 21 for

me user wants to actually send a forgot

password email okay and in this case

let's just emit the exact same state as

we did before but in this case we're

saying loading okay remember

our main dart file is going to catch all

the states that have loading and

actually display our loading screen or

the loading um overlay okay so that's

but then what we're gonna do is let's

and we have to actually say in here do a

try catching here so we say cat on

and since we're in our off block we have

access to our provider so let's say we

wait for the provider to send a password

reset to the email just like that okay

and then we have to enable two variables

in here we just say boolean did send

password or set bits and email

and we also have an optional exception

like this so the goal is we have a try

and catch block in here and in the try

we just say yeah this email was sent

because yeah if you don't end up in the

catch block meaning that there's there

then the email was actually sent

successfully and we will also say the

exception is basically null so we don't

after this point but remember we are

basically saving these two variables in

here so that after the try and catch

block we can actually emit an aust state

for a password with those variables so

this thing is going to go in here in oh

the documentation it's going to go in

and this thing is going to go in here

okay and it's loading is going to be

false so that's why we're basically

storing them in here so in the positive

case in the happy path as we call it

we're going to say did send email is

and we're gonna say exception is no okay

and in this case that's an email it's

gonna be false and exception is gonna be

e all right so we store those

and let's just then copy this state from

above and let's just paste it in here

so in this case we say hey the exception

invalid oh yeah it can't be constant if

it's a variable so um let me bring it

here again so you can see exception is

it has sent email is going to be it send

is loading is false so that's it now we

are emitting that state to the

after all of this you see if and now

that we've handled that event and the

state in our offload we also have to

display some sort of a dialogue to the

user so if you're on the reset password

um screen and you enter you've entered

your email and you say hey send me a

after you've done that we're then going

to display a little dialogue to you and

say hey okay we did that we've sent any

an email to you go check your email so

we basically need a dialogue and if you

remember we have a generic dialogue

already so we're just going to reuse

that okay so let's go ahead as the

caption at the bottom of the screen in

the case go and create a file under lib

utilities dialogues called password

so um let's let's go ahead and do that

under i'm gonna close this file as well

have a look at what we have in here and

i'm going to create a new file in here

and just going to call it password

and email send dialogue dot dart okay

and so that's the file and we're just

gonna say this is a future void um

uh reset sent dialogue all right so it's

a function that just needs a build

and we're going to get an error here

oh visual studio code imported build

context for me automatically that was

so we're just gonna return show generic

dialogue okay and you can see this is

also gonna be auto imported we've

already had this function from before

so let me put a comma here and a

semicolon at the end just to get the um

dart formatter to format my code and i'm

just going to in here say this is a

and for title we're just going to say

password reset like that with a capital

r and the content is also string we can

so like this please check your

something like that okay and you can

change the string if you want

and for the options it's an error

function that has to return a map and it

has only one button with the value of

all right so that's our show password

now what we have to do we also have to

develop the actual view for password

as the caption at the bottom of the

screen indicates we're gonna go to lib

and we're gonna go here you see lib

views and under views we're gonna create

a view called forgot password view so

let me go ahead and do that forgot

password view dot dart okay

and i'm gonna go into my notes as well i

forgot the password view okay

but we're gonna create a stateful widget

in here so that's actually quite a bit

of code that we have to we have to write

but we're gonna take care of that so

it's not a problem so let's go to forgot

password view and the first thing i'm

going to do is to create a stateful

widget with stf in visual studio code

i'm just going to call forgot password

and since we need a text field on the

screen and so that the user can enter

their uh email address just like we're

doing in the login view let's go ahead

and create a text editing controller but

before all of that we also have to

import materials so that we get rid of

all these errors that are on the screen

right now so let's go in here and just

create a text editing controller so late

text editing controller and let's just

and you remember this pattern from

before so i don't have to explain it

again so we go into init state

inside in its state we create the

controller so we say it's a text editing

in dispose we just dispose of it

basically so controller dot displays

just a boilerplate there's nothing

magical happening in here we're just

so what we need to do also in here we're

going to create inside this build

function we're going to return a block

based on the various states of auth

state forgot password so let's go to

or god password here based on various

states of this we may have to show or

hide different things for instance

if we know that the has sent email

boolean flag is true then we're gonna

basically clear the text fields value

using the controller's clear function

and we're also going to display that

dialogue that we just wrote

it was let's see in our dialogues

uh where is it in our dialogues if i can

find it it should be under utilities

dialogues and then we we should be

called a password recent email sends

so we're going to display that

and that is why we need a listener so

inside this build in here what we're

going to do is just going to say we

return um a block listener and this

needs to be auto imported as you can see

and this block listener actually listens

for off block which also needs to be

auto imported so there's lots of imports

and if you don't have a good text editor

like visual studio code unfortunately

you'll have to import all these by hand

and that's just a huge time waste direct

i don't usually give advice but um

my advice here at least because i think

it's so important is to get yourself a

good text editor because it makes

development a lot easier if you have

so we have off block and then the second

and generic parameter is off state which

also needs to be auto imported so

there's if you look at the top of the

file there's quite a few um imports

already that i didn't have to do

manually and so we have a listener let's

get help from visual studio to complete

the listener and we also have a little

um let's see we have a child in our

block listener that we can return so in

here for now let's just say we return a

scaffold as a constant all right so

but we can now work on our listener

so inside the listener the only thing

we're the only state that we're

interested in because this is going to

return any off state to us as they

change we're only interested in

is off state forgot password so that's

the only state we're interested in

and then we say if state has sent email

then we're going to control go to

and then we're gonna await on and

displaying the dialogue so async and

and i forgot the name of our huge file

in here again utilities dialogs and

password reset email so i'm going to

grab this the name of this function at

so i grab the name of that function

paste it in here and get visual studio

code to auto import it for me okay

and in here the only thing we have to do

is just to pass the context in there so

if the email was sent the password reset

was sent and we're going to say clear

the text on the screen on the controller

and then show the dialog telling the

user hey we sent an email to you

then what we're gonna do is to display

an error to the user so we're just gonna

and i think that also got auto imported

so then we're going to say error dialog

with that context and then we're going

please make sure that you are a

registered user or something like that

please make sure that you're a

or or if not register a user now by

so this is just some text i mean you

don't have to write this text it's just

basically saying that if you're in the

screen and you're saying that hey i

forgot my password it's my email if we

can't find that email if there's an

um we're gonna display this message and

say hey you may not be a registered user

and remember in here you could be you

could try to be more fine-grained

because remember our exceptions in here

off state exception in the case of auth

if you go to our off block um

in this case remember the exceptions

come from the send password reset so

this send password reset if you go to

send password reset oh my god where did

in this case those exceptions could be

invalid email or user not found so you

could actually try to be clean and in

your auth sorry in your forgot password

view and actually check what kind of

exception that is so i actually think

it's it's better if you do that i'm not

going to do that in for the sake of just

saving some time but you may decide to

go ahead and do that and i encourage you

to do something like that if you want to

is we've done the listener so that's

really good but in the child we actually

we have to create a um proper scaffold

let's go ahead and remove the consonant

in here because at the end we're not

going to end up with a constant scaffold

it's very rare that you'd end up with a

i'm just going to say we have an app bar

and it has a title and the title is just

going to be constant text and we're just

some commas in there to get the

correctly and in the body we're gonna

this is what i usually like to do create

a column and then i'm going to wrap it

in some padding like this and let's just

say padding of 16 as well okay

that's that's basically our

main focus in here so we need to work on

a little column in your forgot password

so now we have that as the first child

of the column we're going to add a

little const of text in here

and to tell the user actually what they

should do in this screen so let's just

and i'm going to grab the text that i

and paste it in here so i don't have to

actually write this thing again so uh

let's see why is it complaining

what is the actual error um too many

positional arguments okay i've messed up

right of course because in the column i

added actually didn't say children

children inside the children first i'm

going to put this text okay so if you

have the same problem like me it's

because you place the text right inside

the column and that's not okay we have

to put it inside children property of

and we're going to create a text field

right after this where the user can

actually enter their email address so

let's say text um text field

but we don't have a comma at the end of

this either so i'm going to put a comma

in here okay text field so the screen

looks a little bit scary right now it's

just because it thinks that it has to be

a constant but it's not a constant so

these little warnings are gonna soon

so let's say keyboard type and it's a

text input type so i'm gonna say text

autocorrect on email fields always has

to be false okay you don't want

autocorrect on email fields it's very

and we autofocus as well so that when

the user ends up on that screen the

textville is automatically focused on

and then we put a controller and after

this the problem with the constants is

so that's fantastic um and then let's

just go and create a little decoration

with a hint so we just say const

and we're going to say hint text is

your email address like this okay

so that's that part now we've created

after this we actually need to have a

text button we actually need two of them

so i'm going to say text button

and inside the text button on the first

one it's going to it's going to be the

actual cta call to action meaning that

when the users enter their email address

then they're going to press this button

and this upon pressing this button we're

the email to them okay so let's say i'm

pressed and this is an empty function

just like this for now and its child is

just going to be const of text

and we're gonna send send me password

so that's the first i'm gonna copy this

text button actually and paste it again

right after that and in here we're just

login the login page and in here we

actually have this functionality from

before in our auth blog so let's just go

inside this and say context read or off

block from the context and then we're

gonna add an event in here and say off

so this is gonna send the user to the

login page okay so that's the second

and in the first button let's just grab

the user's email so let's just say email

in here we're then going to tell the off

block that it has to send a password

reset to this email so we're just going

to say context dot read off block from

the context and we're going to add and

and the email is email just like that

yeah it's cleaner not to have a comma in

there because if i put a comma then it

formats a code like this but without

having formats like this which to me in

my opinion is a little bit cleaner okay

so i think now we've implemented that so

this screen should be ready our forgot

so as a caption now at the bottom of the

screen in the case we need to go and

look for the off state for god password

and return for god password view in main

so i'm gonna go to main dark file um

so let's let me close this and close

this and let's go to main dart file and

we are handling already quite a lot of

states and right after here login view

else if state is off state for a god

and in here then we're going to say

const forgot password view and this is

going to be also imported as well okay

that's that's that part uh our forgot

and what we also need to do is to make

inside our login view so let's go into

we need to have a little button in here

that allows the user to go to the

foreground password view so we're gonna

add that in here so i'm just gonna

create another text button so copy the

text button that you have at the bottom

and paste it in between in here okay and

in this text right now we're just going

to say i forgot my password like this

and in here let's just send off event

so now if i press the command s button

to hot reload you can see i forgot my

password displayed here and we press it

and at the moment actually nothing is

happening it's probably because we

changed our main dart file and we

haven't done hot reload so sorry hot

restart so i do a hot restart now and i

say i forgot my password you can see we

end up in this screen that we just

developed and then you have the avail

um reminder email and if you say back to

login page then logout is sent and you

now what we need to do also in a login

view dart in here so let's go to login

and have a look at how we're handling

this user not found at the moment and we

have just user not found but if you

think about it there is going to be

people from both apple and google who

will test your application when you send

uh google play store so just saying user

it's i don't want to say it's wrong but

encompassing what could what the problem

saying user not found is like the bare

minimum of what we could convey to our

user so let's just make that better by

text in here so i'm just going to write

this text that i had from before so we

it's better just to say cannot find a

user with the entered credentials okay

just a little bit better message

as now that we're we've basically done

the forgot password where we're going

into the cleanup state so we're adding

some final ui touches to our application

to make it look better so as the caption

indicates let's go into login view and

add a padding in here you see we just

have a column and it kind of looks like

edge to edge it's not so professional so

let's just add a padding in here i'm

just going to say wrap with padding

and we're just going to say padding of

16 in here okay so it looks a little bit

nicer in my opinion at least looks

cleaner okay even if you're doing

for instance elements on the screen they

have like your user agent has some

padding already or margins built in to

inherited widgets it's our inherited

um unless you go and change your css so

this is kind of us adding that um

padding in our elements in the flutter

the next thing that we need to do in

here you can see in the login page at

the moment it's just on the top says

login and enter your email blah blah but

it doesn't actually give the user any

instructions you see here in the i

forgot my password we're giving the user

some instructions on what he or she has

to do but in the login page we're not so

let's go ahead and remedy that and just

add a text on top of the screen i'm

going to paste that text from what i had

before inside the children of this

column and we're just saying please log

into your account blah blah

and you'll see now that appear here just

makes it look a little bit nicer in my

we've already now fixed this and going

forgot password we've already added that

in here as you can see so this element

at the bottom of the screen this caption

is already addressed we don't have to do

anything special about that

register view as you can see our

have you broken the register view not

registered yet i can see that that

button at the moment isn't working so

event should register okay

event should register i can see we

haven't even handled off event should

we need to definitely do that right now

so let's go to off block and

have a look at handling our um

i'm gonna remove this caption right now

because that's not what we're working on

right now so let's go to our off block

i'm going to maybe actually add that so

what we're working on right now okay so

let's go to our auth block and say on

and let's just say event and emit

and what we're doing in here is to say

constant off state registering

okay and there is no exception and there

is no loading so false just like that

okay and a comma here to get the

formatting working so now let's press

hot restart because remember you're

changing your auth block which is being

provided in your in to your entire

application in the main dart file so

so you can see in here it's the

block provider that is basically

creating the off block so if you change

anything in your off block you may

actually have to do a hot restart okay

for those changes to take effect for app

for entire applications so not

registered yet pressing it goes to the

so as the next point that we have to

handle here is to add some padding to

as you can see in here our register view

at the moment looks like this we have

the register button and already

registered button buttons right here but

we don't have any padding around our

register view so let's go ahead and take

care of that so i'm going to go to

let's go ahead then and wrap this column

at the moment in here and just say wrap

it with padding as the caption at the

bottom of the screen says we're going to

you can see now we have some padding in

there and soon just like in the login

view we're going to add some text to the

top of the register view so what we need

to do is just to ensure that deleting

that their text inside this column is

actually pat it's and it's basically

sticking to the left side of the column

because by default all the components

that you place inside your column are

vertically aligned and no sorry they're

horizontally aligned in the main axis of

column so if you that's what i mean like

if the column what i mean is that the

column is expanding to the entire

space uh real state and then all the

components that you're placing inside

your column they're horizontally aligned

that's actually a better way of probably

saying it so and what we need to do in

here let's just go and say uh inside the

column as you can see in the caption at

the bottom screen we're going to say

we're going to say cross axis alignment

start if i save this and go back to the

register viewer you're seeing this in

here basically like that and what we're

is to add a title to our column so i've

already added that before so let me

i'm going to add a little title to the

first item inside the register view so

it looks like this but we also now that

we've done that i mean we want our text

field to be left aligned that's why we

added this cross access alignment but

we've kind of messed up the alignment of

our buttons in here so we need to kind

of wrap them inside centers so

what we could do is to inside you see we

have two elements in here but we don't

want to wrap both of them in their own

centers so what we could do is just to

text button inside a column

then we put the other text button also

inside the column right here

and then we will wrap this column

inside a center so wrap this column then

inside a center just like that

so if you go back to our register view

now we have a nice little layout

so we've taken care of that we've taken

care of the title of our application

and what we also need to do is to make

sure when we come to the register view

that we are auto focusing on our uh text

so let's go inside the effects if the

and right after auto correcting here

true so when i press save in here and i

go to the register screen you can see

that the keyboard pops up automatically

auto focusing on the first email field

okay now we also have a little problem

fixed our tests as you can see in here

implement send password reset and mock

and throw i can see there's a spelling

error in the caption i'm going to fix

and that is here so let's go and fix our

test so i want you to please go to us

testing here and you'll see that we have

an error here telling us in mock auth

provider saying that we haven't

implemented the last function that we

just added to our off provider called

so let's go in here and just ask it to

create that missing override

and what we're going to do for this

exercise at the moment is just we're

gonna leave this as it is on implemented

error and i actually encourage you to go

and do an implementation for the send

password reset you may for instance do

mock and password reset do some future

uh delayed a weight on it and change

some states in your provider if you want

to you're more welcome to do that so you

could just take this as an exercise but

we're just going to leave it like this

for now but i highly encourage you to

actually write some tests for this as

so we've now done quite a lot of work

we've done quite a lot of reshuffling

things around what we could do is just

to have a look at the entire app and see

how it kind of looks like so i'm gonna

and we end up in here you can see our

and if we try to log in with a user that

doesn't exist in the application anymore

so i could just type any password and

say login and we get our updated screen

that says cannot find a user

then i can actually go and register that

user the text field is autofocus that we

and we can see that we get this verify

email we sent you an email verification

we also have to clean this view up soon

because i believe that this is not a

part of this a particular chapter at the

moment that we clean this up but we're

gonna we're gonna clean it up soon

um so the verification email should have

been sent now so if i go to my mail

application i'll just see if i can

have i received any email from firebase

yes and that email is available here i

as you can see there is a link on it so

i'm gonna tap this link and this will

firebase so if i say console firebase if

we go to the console of our application

now we should see that user generated

so that user is right here and is

verified user so we can just press the

restart button and log in with that user

log in and we see our dialog and there

are no notes so i'm just going to create

and it's sitting there thinking

and then i'm gonna say hello world all

right that's my first note gonna go out

let's go to the console again and to our

application and have a look at

our fire firestore database and make

sure that that note was actually created

and i can see that was actually created

here hello world with that user id nvic

if i go to authentication i can see nvic

it seems to be working we have quite a

bit of work still left we have worked

with some margins we have worked with

icons app name etc before we can submit

it and these are things that we're going

to take care of in the coming chapters

but we've got we've come basically a

so we're almost there but not really

but no worries we're going to fix those

soon and let me do some screen

reshuffling in here and let's have a

look at the committing of our work which

is something that we usually do at the

i'm going to minimize scr cpy increase

the size of visual studio code so you

see my screen better let's go in here to

the terminal and have a look at this

shell in here and say git status

a few files that are on track which are

new which is our forgot password view

which is new and password reset email

and quite a lot of files that have been

updated in here so let's just say git

and also git commit step 27 all right

and we have to push our changes also

so after we've done that let's also tag

as is tradition at the end of every

chapter we're going to tag this

and after doing that we can say git

status as you can see there's nothing to

commit in here and nothing to push

again as a tradition at the end of every

chapter we talk about what we need to

discuss in the coming chapter

so this is the exciting part at the

moment we've been working a lot with the

application code itself but we haven't

really done anything to make it ready

really for release the app store and the

play store google play store and there

are a lot of things that we have to do

such as screenshots we have to prepare

each respective store and we also have

to prepare the app icon the app name etc

lots of work to do and that's the kind

of thing that we're going to take care

of in the next chapter so i'll see you

there hello and welcome to chapter 45 of

the slatter course in previous chapters

we've been talking quite a bit about our

authentication and authentication block

and then in the previous chapter we made

our application a little bit more ready

for releasing in the app store and

google play store but we still have

quite a bit left and these are like some

of the final touches that we're gonna

put on our application before we can

release it in their respective app

um so what we're gonna do specifically

in this chapter as you can see in the

caption at the bottom of the screen

we're gonna take care of our app icons

and the app name and i'm gonna take you

through the process which works very

well and has always worked for me so i'm

going to show you how to grab

free icons bring them into your

application and also be able to kind of

like automate that process you don't

have to generate the icons by hand

so to begin with we have to talk about

what app icons are so so far we've been

just kind of like running our

application and just looking at what is

inside the app itself we haven't really

have we haven't had the time to actually

look what's the application

how the application is represented from

perspective on the operating system so

if i bring up scr cpy in the middle of

and then i bring this application and

all the apps up in this android phone

for instance this you can see is our

application right here so if i change

a little bit here so you see better so

notes application is right here and it

has a default icon so every application

on both android and ios and pretty much

in every operating system has its own

icon so flutter allows you or flutter

provides a default icon for all the

applications that you create with

flutter create so you have a default

icon that is displayed for your

this is just a default flutter icon as

i'm mentioning so we need to have our

own icon that the operating system can

in order to represent our application

amongst all the other applications that

are installed on that target operating

so that's for the icons and then what we

have to talk about is what splash

screens are so splash screen is this

little screen that the operating system

displays on the screen and as soon as

you open an application so i'm wondering

if there's any application for instance

open up in order for us to see a splash

screen so let's for instance go here to

the clock application and as i saw here

let me just bring it up again so if i

by going here and then i go to the clock

application again you can see that there

displays instantaneously and then just

disappears that is the splash screen and

or in this case you could actually see

it's the lack of its flat screen because

there's no splash screen apparently for

the clock application and let's go to

and this application opens up so fast it

probably doesn't even have a splash

screen but what essentially his flash

screen is is a screen as its name

indicate that gets displayed to the user

just very fast while flutter is

loading its binary to display to the to

um the user so there are two stages for

flutter to actually show a splash screen

one is when the application binary is

being loaded by the operating system and

then there is another stage when the

flutter engine is being loaded to be

basically kicking off your applications

process basically but i'm not going to

go into too much details about that but

just know that splashbearing is a screen

that the operating system displays the

user while it's loading the application

so if for instance your application is

being loaded or is being displayed for

the first time on an android telephone

version that has very old hardware

because there are thousands and

thousands of android devices out there

then the operating system may actually

take a lot of time in order to load your

binary and that time it will and during

that time it will display a splash

screen so we're going to fix both the

app icon and a splash screen soon

so let's now talk about where you can

actually find some icons so if you're a

designer and if you're comfortable with

figma or sketch for instance then you

can go and design your own app icon

you're more welcome to do that i can i

feel free with figma i'm not a sketch

user but i can design my like icons in

figma but that's not what we're going to

do in this chapter we're actually going

to go to this website as i'm showing you

here stockio.com and grab some free

if i minimize scrcpy here and bring up a

stock io.com you can't see that right

now i'll bring it to the screen

like that and you can see you can hear

go to for instance icons and then

there's a search functionality where you

can search for the type of icons that

you're interested in these icons are not

really free sometimes they're actually

they need to be paid for however you can

also find um cheap or even free icons

that you can use in your application but

it's very important that you attribute

the author work the way they ask you to

do that and i'll talk about that soon

so for our application we're actually

going to grab this particular icon so

it's called stock io we're going to go

note file icon okay so that's the icon

we are going to use for our application

and and you can go ahead and do the same

thing i mean it's not that the app store

is gonna like google play store and apps

are not gonna set us like they're not

gonna stop you from releasing your

application just because your icon

is the same icon as someone else's app

basically check that really unless your

icon represents a very well-known app

add the facebook icon to your

application then the people who are

reviewing your application are going to

know that immediately and recognize it

and then they're going to flag it and

perhaps reject your application but this

is such a generic icon that i don't

think anybody is going to basically

have anything to say about it if someone

else has used this already in one of the

hundreds and thousands of applications

that are available in in those

respective stores so what we need to do

here go and say free download as an svg

so i just did that so let's go in here

so i'm going to bring it up here and you

can see it's an svg and that's been

downloaded on my computer right now so

basically talk now a little bit about

so as you can see here in the

information that is provided here on the

screen i'm going to increase the size so

you see it better it says free for

personal and commercial use that's that

means even if your application is free

in this in this flutter course we're

going to release our application as a

free application of course but if even

if it's for a commercial use you're

allowed to use this icon but it says

with attribution to stock io.com so

what we should do if we're a good

citizens of the internet land then when

you basically upload your application to

the app store and google play store as

i'll show you later we will actually

write a little sentence and attribute

the um stock io.com website and even

maybe say icon is provided by

stockion.com and even place the entire

inside our application description when

we submit it to the respective app store

so be very careful about this because

there are actually artists that are

creating these icons for you so

see that it's free you may be attempted

to just say yeah i forget about i'm just

gonna put it there i'm not gonna

attribute the author but if you think

about it it's just one line of text that

you're going to write in your

application description it's worth it

because someone has actually sat there

spent quite a lot of time designing this

karma to make sure that we follow these

attributions apps that are provided in

the website where you download your

so now we have this svg icon so if i

bring my finder here so we just have one

file in here but as you'll soon see when

we submit our application to app store

and play store google play store we have

to provide various icon sizes all right

it's not that you have to provide the

various icon sizes to the app store but

when you build your application you

actually have to provide these different

icon sizes to the operating system for

instance if the user is loading your

application on a very old iphone without

a retina display which i highly doubt

now nowadays almost all ios devices have

then that user with that phone that

phone particularly cannot display very

high resolution images so it needs to

app icon resolution however if you run

app for instance on an iphone

13 pro max then that device can actually

display a high resolution image so

using this svg file we have to create

and slice it up so that we have various

icon sizes to provide for various

operating systems and device

so that's what we're going to do but

we're not going to do that by hand we're

going to use a tool in here called app

icon dot co so let's go in app icon dot

and this is a great free tool that you

can use and you can just basically

target and it will generate your icons

for you so let's go ahead and do that

i'm going to drag this svg in here just

all right and you can see that i can

generate the icons for the destinations

that i'm interested in our application

doesn't support watch os at the moment

and we're not a mac os application so at

the moment we're just saying iphone and

so let's just generate these icons and

if i go in here i can see that there was

a zip file generated in here so let's

just unzip this file and have a look at

it and you see that there's a folder

it has android app store assets etc in

so now that we have these icons

generated here as a caption indicates we

have to add them to our application so

how do we do that do we go ahead and

add these by hand no but there is

actually better way of doing this so

i'll explain it to you right now

there is a package called flutter

launcher icons that can take care of

this for you so instead of you having to

place these icons manually inside your

application binary or inside your

application source code for instance

visual studio code or android studio it

can do that for you so let's go to pub

i'm getting rid of this dialog here as

well and let's search for flutter

and we found it right here and you can

see that it is provided by the flutter

community right there and there is

information on how you should actually

configure this and we'll get there soon

but what we first need to do

our application so this uh

let's go to installing in here and

you'll see here that it says

dart pub and with flutter we want to do

this basically father pub at flutter

launcher icons okay so let's go ahead in

our application so i'm going to bring

let's go to terminal so let me bring

and let's just paste that command in

all right so that is just going to add

flutter launcher icons to our

and so that's the adding of it so if you

go to pop spec yaml now and have a look

at our yaml file you can see that

there's this flutter launcher icons

added right here okay then what we need

to do is to create some sort of a

configuration file for this plugin and

to understand how it should generate our

icons for us you can see if we go back

you can see that there's some

information about that if you read the

readme file it actually asks you

actually to generate a file called

flutter launcher icons yaml and that's

exactly what we're going to do in here

so let's go to the root folder of our

folder in here so make sure that you're

in the root folder of your application

and then i'm just gonna say new file

and let's just add flutter launcher

and in here they basically say add this

here copy this information as it is

stated there and place it there but we

and basically key in here called remove

alpha ios and we have to set this to

true and this is a key that i don't know

if it's actually documented so let's

have a look at the documentation in here

let's see version scores change log

it's not really documented unfortunately

but there may be inside the git

repository for this application like

there may be some good documentation to

be honest with you change log

flavors could there be anything in there

no unfortunately but i will just explain

what this key basically does what it

as an operating system it doesn't allow

alpha channel transparency channel on

its icons on its app icons so

what you need to do is to get rid of

that so when we generate our icons we're

going to tell this plugin that hey when

you're generating the ios icons remove

the alpha channel and for you designers

out there you already know what alpha

so it's just a transparency layer

all right so what we need to do now is

to grab our icon the downloaded icon and

place it inside assets icon icon.png

okay so as you can see in here let's see

if you have an assets folder and we

don't so let's go ahead and say new file

and i'm going to say assets

and then we're gonna call it icon okay

and let's go then and bring that app

store png file that is right here and

just place it inside the folder that we

just created so it's a huge file okay

so now that we've done that and you'll

be wondering okay where why is it under

assets icon and that's because in this

launcher configuration we said that that

icon should be there you see icon png so

what we need to do now is just to rename

package can find it under assets icon

icon ph png as it's specified here okay

so in order to then generate your icons

you just have to run this for

this command right here so i'm gonna i'm

let's see uh terminal is actually right

um let's go here terminals and i'm then

going to clean the terminal get rid of

the left hand side bar i'm going to say

flutter pump run flutter launcher icons

that is going to basically do its job

have a look at um the configuration and

then it's going to generate our icons

so in order to test this we actually

need to make a clean build and this is a

little bit of a pain in the neck and

that's completely okay it's just because

we change something dramatic in our

application and then we need to just

make sure that we stop the running of

our application so i can see now this

particular application at the moment

isn't running in scrcpy so that's really

as you can note here this is the icon of

our application right now without us

so let's just do as the caption

indicates we're gonna do flutter clean

and after cleaning is done we're just

pop get in order to grab all our

and i can see that you can't actually

see what i typed there but that's what i

typed flutter pup get as you can see

and it grabbed all the dependencies

again and what i'm going to do is just

going to go to main dart file in here

just run the application but before

doing that i'm just going to also make

sure that flutter select device has

selected the correct device which is my

android app and which is my android

phone and just gonna say run without

it could actually help if you removed

so just to make sure that that

application is completely deleted from

the phone so it's completely gone now

and really all we have to do is just

right now wait for this gradle task to

complete its work so i'm just gonna let

now you can see that our application is

running on uh scr cpy which is an actual

real phone in here so if i now go back

here and bring up all the apps installed

on this device you can see we have this

application running right there my notes

and it has this little icon here and

this is another application that i've

had from before so i can just uninstall

that safely and we just go to our

application in here you can see it is as

we left it last time but the important

thing is that there is a new icon

that's really good now we've tested that

on android so the testing of android is

actually done so you don't need this

caption at the bottom of the screen i

should have brought up brought it up a

little bit earlier and what we need to

do is just to run our application on ios

as well so i'm going to stop the the

execution of the application on android

and i'm just going to say flutter select

device and iphone 13 pro which is a

simulator and then i'm just gonna say

run and this is also gonna perhaps take

some time because usually i run my

applications on the android telephone as

you've seen with scrcpy i usually don't

run with an ios simulator or a device

when i'm developing with flutter

and but it is always good practice to do

that so now it's doing the xcode build

and let's just wait for it to finish

okay and now we can see that our

application is also running on ios so

what we can do in here is just to send

the app to the background and then you

can see that we have our my notes

application right here and the icon that

we basically created for our app so that

what we need to talk about now is our

app name and as you can see in the

caption at the bottom of the screen

since we need to update the app name

it's not so nice as it is now and right

now it's just saying my notes with a

lowercase and and capital m and all in

one word so it's not as it should be so

let's go ahead and fix this and the way

to do that is that you have to do it in

two places one for ios and one for

android so we're going to take care of

ios first so in visual studio code i'm

going to jump into a file called info

key list and this is the info p list is

like basically an ios applications and

kind of configuration place which you

can configure a few things for

application like permissions etc and if

you go to this uh file ios runner slash

info p list so let's go in there and

then there is a key in here called core

let's see if you can find a bundle name

cf bundle name at the moment it says my

notes in here so we need to fix this

just to call it basically my notes like

and let's see if there's any other place

in here we can also see that there is a

bundle display name which we may also

have to fix so let's just call it my

and to be honest with you we don't maybe

actually have to change the bundle name

i would say maybe changing the bundle

let's not do the bundle name actually

i'm going to change the caption and just

call it changing the bundle display name

because i would say a bundle name and

bundle display name are two completely

different things the bundle name is like

the binary name of the application and

the bundled display name is what the

user sees on the screen so let's not do

the bundle name and let's just change

the bundle display name in here and just

so after doing that we could try to

stop the application in here and then

it may take effect it depends kind of on

how flutter is gonna trigger these

changes with xcode build and how xcode

build is going to interpret our changes

it might actually be necessary for you

and then run the application again on

that target platform so that's just a

bit unfortunate when you change like

huge changes when you make you changes

to the applications structure

and i could see now that my notes was

actually taking the fed effect right now

so we don't have to do any flutter clean

then what we need to do also is to

update the app name on android and we do

that by going to android app src main

and we could just do that right now so

let's go to android manifest xml

and you can see here is android app src

main i'm going to go in there and then

key in here android label and just

change it to my notes all right

so let's just do that and then i'm going

to go here just to a flutter select

device run it on my android phone then

i'm just going to stop the ios execution

and just go to run run without debugging

so that you can try to run the

application on this android phone so if

everything works as expected then we

should have our mynotes application

right here with the correct uh

icon and then we should also have the

correct label alright so let's just send

let's go in here and have a look at our

application you can see now it says my

notes the right icon and also um yeah

the application is running as it should

and if you go back to our ios

application then we can see the name is

also correct and the right icon

so we could actually say that we've

already tested things on ios they seem

to be working so if i bring up the

simulator the app is working as it

we don't have any crashes the icon is

correct and the label is correct and on

android if we bring up scrcpy again you

icon is correct and also the name of the

we've done what we said that we're going

to do in this chapter we talked about

icons and we also talked about what

splash screens are in preparation for

the next chapter and it's usually the um

what we do in the and at the end of

every chapter we talk about what we need

to discuss in the chapter that's coming

so what we need to do in the chapter

that is coming is to prepare ourselves

for creating splash screens you now know

what splash screens are but in the next

chapter we're gonna go and create them

we're gonna add them to our application

so grab some refreshments if you want to

i'll see you in the next chapter hello

and welcome to chapter 46 of the

slaughter course um if you follow the

chronologically you'll know that we've

done a lot of preparation and we're

actually about to start preparing our

app to be submitted to the app store and

google play store but before doing that

now that we fixed our icons and

our application name for both android

and ios we need to fix something called

and we talked briefly about splash

screens and what they actually mean in

the mobile world for instance in both

android os and ios and ipad os for that

matter but for those of you who missed

a splash screen is a screen that is

displayed to the user when they open

your application from a cold

boots basically meaning that your

application hasn't been running for

instance in the background in that

operating system and while the

application binary is being loaded to

the screen and the experience is being

um then the host operating system in

this case android and ios will have to

display something to the user while

they're waiting for the experience to be

so in native applications for instance

if you're creating a native

coupling for ios sorry kotlin for

android and swift or swift ui for ios

then um in that case there is there is

only one stage of loading for

you submit your binary to apple and then

um to google play store and then the

host operating system just loads your

binary and then that um your main user

interface is displayed to the user so

in flutter however there are two stages

of loading your application one is

the your application binary in itself

being loaded and the second stage is for

the flutter experience to actually be

loaded inside your application since

flutter is its own sdk basically

so what we're going to do is we're going

to create a splash screen that gets

displayed to the user while our

application binary is being presented to

so let's have a little look at a the

official documentation for splash

screen up here and increase the size

perhaps a little bit so like this

as it is explaining here first and you

android for instance operating system in

here and you tap on your application

icon and then it goes through a series

of steps in order to land on your

main interface and here there's a great

documentation basically for splash

screens which i recommend everybody

who wants to submit their application to

ios app store and google play so to read

this thoroughly because there's great

pieces of information here even if you

are just following for instance my

advice in this chapter but it is still a

to go ahead and read about this

before we actually go and start

i also have to mention something that

this chapter is quite i mean you need in

order for you to be able to go through

the chapter you will unfortunately need

to have a macintosh so because we're

actually going to play a little bit with

um ios splash screen and for that you

need to have xcode but i'll talk soon

so how do we go about creating a splash

i mean there are so many different ways

if if you're a developer from before you

probably are not so comfortable you're

not this kind of like a unicorn

a so-called unicorn developer as a

developer who's also comfortable with

or you might you might only be a

designer and you've started this course

and you've come to this point so you may

actually be comfortable with a tool like

depending on your background you may or

may not be comfortable with designing so

i've basically taken the liberty of

using a design tool a free design tool

and for this chapter which you can

access freely with for instance a google

or you could just create a normal free

but i don't make the assumption that you

know anything about designing and for

that what we're going to do is we're

going to create a very very very simple

assuming that the person is watching

this course has no information about

figma or designing previously okay

now that we talked about figma let's

so um what we can do in here is to bring

our application to the screen so i'll

app in here increase the size a little

and what we can do is to bring up

terminal in here so get rid of a little

bit of distraction in here so

so if you say good status we have a lot

of stuff that we've done but we haven't

committed them so that's fine let those

be there we're going to commit them soon

so in your application what i need you

your ios application so there is

something in the ios application

template when we created our our

template from the absolute beginning of

and there is a file a specific file

called a launch i believe it's called

launch screen dot storyboard if you're

not comfortable with ios development

like native ios development from before

i can just explain you that a storyboard

a file that apple designated for um

developers to be able to visually design

their application and then write the

code for it later and apple's decided

that for specifically the launch screen

for instance that gets displayed to the

user there should be a a dedicated um

storyboard file for that so

we're gonna go ahead and launch xcode

on this macintosh in order to manipulate

that storyboard file but before we do

that i'm just going to go ahead and open

the root folder of our application

then i'm going to go and let me also

change the screen layout a little bit so

then inside this ios folder so in the

root folder of your application go to

ios and then you can see two files in

here runner xcode proj and runner xc

workspace and dependent on your settings

on your macintosh you may or may not be

extensions of these files i i've i've

done so in my macintosh that i can

file extensions because it's important

for me so if you're not seeing the

extensions you just have to trust on the

icon so one of these files has this

bluish icon which says project here and

the other one is a workspace i need you

on this workspace in order to open it

so let's go ahead and open this

and let's then go have a look at this

launch screen inside this runner folder

if i collapse everything inside you will

see that you have your runner and which

is the flutter templates created

inside there we have another runner and

in that runner folder then you'll have

we can then have a look at this launch

screen and see how it is created

in order to expand the contents of this

view controller to have a look at the

internals of this launch screen and a

good trick is if you want to expand you

can see here you have to expand this and

then you have to expand this and expand

if you don't want to expand one step at

a time you can always hold down the

option key or the alt key and then click

on this little arrow and that expands

the entire chain for you and if you want

to collapse the entire chain you can

press down alt and then click and then

collapses the entire change so

let's let's expand the entire chain and

then in here you'll see that there is a

view and then a launch image image view

which at the moment is pointing to a

file called launch image which doesn't

exist because if you go to our assets in

here you'll see that launch image is

just empty at the moment okay so there

is no launch image meaning there is no

we're gonna manipulate this file a

little bit as you'll soon see so let me

so that was the basics of that launch

as you see at the caption on on the

caption at the bottom of the screen this

is an unfortunate unfortunate thing that

isn't as open in my eyes at least as

many other companies like microsoft and

in that if you want to for instance do

native ios development and have xcode in

order to open your project and run your

project for instance then you'll have to

have a macintosh because xcode isn't

available on other platforms and it's

it's it's nothing to really be proud of

i would say i'm a native ios developer

and i'm actually ashamed of the fact

that xcode the tool that i use on a

daily basis is only available on a

macintosh because i might personally for

like to write my code ios code on ubuntu

or some of you may actually prefer

windows but let's not go there let's

just say that you'll unfortunately need

macintosh in order to be able to

um launch screen as storyboard file and

for those of you who don't have a

macintosh you'll need to contact perhaps

somebody in your network who does have

access to a macintosh and ask them to

manipulate the storyboard file for you

and add your icons as you'll soon see

how and then send that storyboard file

so what we need to do is to actually get

roots of what we need to work on in this

chapter and that is creating a splash

screen okay so as i mentioned in the

beginning of this chapter i'm gonna rely

on a free tool called figma

so let's go ahead let me see if i can do

reshuffling on this screen

and close a tab in here i'm gonna bring

gonna minimize our application and bring

up my browser right here so i need you

to please visit a website called

and in figma.com then you will have the

ability to create your design files all

so i'm not gonna show you actually how

to register for figma because that is

very easy so you can just perhaps if i

for instance go to and bring up a

tab in here and say figma.com where i'm

not logged in you can just say sign up

and as you'll soon see here you can

continue with google or use an email

address of your choice in order to sign

for figma and as i mentioned figma is

free until to a certain point

and you can you can for instance um

normal design files in figma without

having to think about actually

paying for a subscription but if you

want to do advanced work for instance if

you want to do a lot of sharing of your

work with other team members etc then

after you've registered your account in

figma what i need you to do please is

just to go and click on new design file

okay so i'm going to increase the size

in here and just say new design file

all right so it's created a new design

file here for us and as you'll see as

you'll see in the bottom of the screen

in here um i wonder if i actually have

to bring my face to the right because

so i hadn't noticed that so um

so what you'll need to do is to create a

maybe this is a better screen um

yeah set up maybe this is better okay so

what we need to do in here is to create

2778 and i didn't i didn't like make up

this is the size of a screen for an

if you're not a designer you may not

notice but when you're designing things

you always have to create like your

design so that it it scales to various

sizes this was not a problem back in

2007 or 2008 when we only had one iphone

and just a handful of android devices

but nowadays you have to kind of like

create a template in for instance figma

and then ensure that it is scalable for

different sizes but we're not going to

focus on that right now all we're going

splash screen and then inside our ios

app and android app we're just going to

make sure that it scales okay so let's

just target one device at the moment and

in here i need you to go in here and

actually here sorry about that and

after creating a rectangle we're going

to go in here and set the width to what

i can see my keyboard and the height is

okay so it's a huge rectangle

that's our rectangle and what we need to

do is to kind of give this a background

color now as you've seen so far and if

you follow the chapters chronologically

for this course you'll know that i

soft theme in visual studio code for

uh coding and i absolutely love this

it's the preference you may like a light

team i like a dark team such as tokyo

night and tokyo night is a visual studio

code theme that is open source and you

github so what i'm going to do in here

is just to make sure that the background

color of our splash screens actually

painted with that color okay so let's go

in github and you'll end up in this

website github.com and kia tokyo night

vs code theme so if you don't have this

link and if you couldn't be bothered

writing this name you could just google

and so i'm just gonna go to google and

say tokyo night theme okay and you'll

end up with the github link so you can

just click on it all right so i'm gonna

go down here in this um theme and i'm

going to grab this beautiful editor

um actually either we could use storm or

night i'm gonna choose storm and just

see how it looks like so grab this code

the rgb code for uh tokyo knight and

let's go to figma into our rectangle and

so that created a nice little background

color for us okay so we could just live

then what we need to do is i like to

basically create some sort of a gradient

in this background color so it's not so

bland as it is right now so what i'm

gonna do is just to go to effects in

here and then say that we have actually

no not effects it's probably in fill

let's go and fill press the plus button

and in here just click on this little uh

you know what actually i would really

like to change the screen layout a

little bit so you see my figma screen

better so i'm gonna hide this caption

and see if i can change the caption

and hence i can change the screen layout

with my screen with my face still

visible so i think this is a little bit

better okay after doing this fill so we

added a fill effect in here using this

and go and tap on this um little icon

next to fill you see here clicking on it

you can then say that you want for

linear should we create a radial maybe

or a linear gradient let's see

let's create a linear gradient okay

then this as you can see is a gradient

that at the moment is going from black

transparent with zero percent in here so

let's make this black point as well

zero and we're gonna in both these cases

set the background color as the starting

point and the ending point so click on

the starting point change this color to

tokenite background color and here as

well so that's that okay then in the

middle somewhere we're gonna create a

point and give it a hundred percent uh

transparency and let's see how it looks

in here can we not have three points

yeah figma just went a little bit

ballistic on us but that's okay

so in here we have that color in here we

so so the start and the end have to be

transparent with that color that we've

chosen and let's go in in the middle and

just kind of change the color to red and

you can see that it gets created here

and then what we're going to do for the

middle we're going to go and create

grab this particular color here as you

can see it's kind of like a light very

soft light blue starts with 7d so it's

and i'm going to go back to the figma

change the middle color to that

just like this okay so it kind of

creates a nice little effect for us in

so after doing that let's go to our

downloads and grab our icon so i'm going

downloads and if you remember we had

sticky note svg file and figma is great

with stuff like this so let's just grab

middle okay and that's our sticky note

so let's see what we can actually do

should we use the svg or should we use

it's probably better to use actually the

app icon so revert this change please so

let's not use this svg let's go to our

app icons that we extracted in the

previous chapter and let's grab a

rasterize png which is this app store

icon and bring it right here okay so it

actually is a nice size i'm going to use

these built-in layout guides in figma as

you can see it tells me where the center

is so i'm just going to place our icon

right there and as you can see it

actually blends really well with that

background linear gradient that we

created so it's a it's a subtle effect

so you can see that the linear gradient

and if you disable that linear gradient

it's very bland so without that linear

gradient it's our splash screen doesn't

look so well so you can also play a

little bit with the transparency of the

entire thing like 100 and i feel like um

crazy so maybe 20 was actually pretty

so here let's go back here and say 20

as it was so now we have a really good

base for our splash screen so what we

need to do now in order to download this

splash screen you need to select those

two layers so on my macintosh i'm just

going to hold down the shift key and

click on this icon for instance and then

click on the next one in order to select

both where i think you could actually

no you can't select like that so you

need to basically hold down the shift

command g on a macintosh or ctrl g on

linux and windows in order to group

these two layers together okay so now

it's a group and i'm just going to call

splash screens just like that it doesn't

have to be called like that splash

screen but i just call it so okay

so what we need to do is to grab this

splash screen in three flavors so

normal like um in normal ios development

you have to support three different

resolutions for your assets usually

so they only support for instance the

and if this doesn't make sense to you i

will just explain what this actually

on ios at least they're called at their

screen and they're called retina devices

and it's just a term created by apple um

and where they said basically they

doubled the amount of pixels that a

device can display on the screen but

they held the aspect ratio as it was so

if in a little square in an old device

the device could display four pixels

then the new devices could display eight

pixels so they doubled the amount of

i don't know how you want to say it and

they call it retina and then they added

every developer needs to provide an

image for the old devices and we call it

and the new devices will have 2x

then newer iphone devices came out they

had more modern retina displays and even

more pixels packed into the same

space so they said now those devices are

able to display eight times more pixels

it's basically gonna be um one x two x

so um i think it's eight times more

so it's 1x2x and 3x that we have to

support so let's go in here

let me see if i can shuffle things

around so you see better um maybe like

this so let's go in here in figma at the

bottom of the screen you see this export

button so i'm going to press that export

so i'm going to press that export button

actually three times as you can see in

here so we have the first one is a png

make sure that they're all png files and

the first one has no suffix second one

has two x and the third one has three x

that's exactly what we need okay

after doing that what we're gonna do is

to say export splash screen just like

and that's gonna do its processing so it

may actually take some time depending on

our internet connection as well and then

we downloaded this zip file so our work

in this file is basically done and this

is the contents of that zip file as you

can see splash screen png and they're

all the same but their sizes are quite

different you can see the first one is

604 kilobytes the second one is 1.4

megabytes and the third one is 2.5

so after doing that let's now remove

safari or your web browser from from the

and we need to basically go into our

source code now so i'm going to keep

this window here do some reshuffling on

let's see i'm gonna bring our uh

application to the to the screen like

okay and actually we don't need the

application sorry about that we kind of

need xcode in here so let me bring up

but let's bring xcode to the screen and

what we need now is to go to our assets

in here run our assets and we have our

launch image right there so what we need

to do is to grab these images one at a

time and bring them in here okay so and

they can be called splash screen that's

not a problem xcode will do the mapping

for us so as long as this thing in here

is called launch image then we're

so as a caption any case we're now going

to go and bring these images in here so

we have three images you can see in here

and we have three placeholders in here

that we have to drag and drop our images

into so let's begin by splash screen png

let's bring our splash screen 2x into 2x

that part is now done but we're not

really done designing this splash screen

let's go to the launch screen storyboard

file in here as you'll see it doesn't

we need to find this launch image that

is displayed in here and you can see at

the moment its constraints are like

very very wrong so it just thinks that

if you go into this tab it thinks that

this image is one two eight four by two

but we don't want that okay we want this

image to be as big as the screen but we

fix the aspect ratio of the image so

that it always fills the entire contents

of the screen even if that means the

image goes a little bit outside the

outside the boundaries of the screen

okay so that the launch screen looks

so what you need to do here is just a

little bit of a work on ios side so you

need to go in and select your launch

image in this tab in here which is your

dimensions the size inspector as as it

is called in xcode go and say that the x

is zero and y is also zero so that kind

of like make sure that your image starts

right there then let's just zoom out a

little bit and go manually and drag this

a little bit so that it fits the screen

so i'm going to drag this point let's

see if i can do that with my trackpad or

mouse and it's it's like playing a

little bit with me just because this

launch image at the moment has some

constraints so let's go and actually

remove these constraints so i'm going to

remove this horizontal constraint by

pressing the backspace button on it or

if you're on windows and linux you have

to press the delete button on your

keyboard so now i've removed those

constraints so i should be able to

freely size this hopefully let's see

and it's not letting me size this but

that's okay so what i'm going to do is

i'm going to have a look at this view

and see its size i can see that view is

896 then i'm gonna go to my launch image

and say okay your height is also 896. so

that's going to ensure that the height

of my launch image is the exact same

height as the view then i'm going to

have a look at the views with is four

one four and i'm gonna go to the launch

image and say you're also four

so now the image container actually

looks good however this launch image it

now has hard-coded values hard-coded

width and hard-coded height

it's x and y and y are quite fine but

what we need to do is to create some

constraints for it and constraints are

literally i mean we're not going to go

into native ios development at this

moment so you need to kind of have some

knowledge about this yourself and if you

don't i'm just going to tell you just

quickly how we create these constraints

so what we need to do is to click on our

and hold down the control button on your

hold down control and drag from launch

then this menu appears on the screen and

then hold down the shift key on your

computer on your macintosh and say you

and also you want to see leading space

that's fine for now i would say i mean

ideally what we want is for this screen

to be in the center as well so maybe we

could just say center horizontal and

center vertical so check these four

items as you're holding down the shift

button and then you can let go of the

shift button and then just click here

anywhere on the screen to dismiss of

so now you can see xcode is also happy

with the constraints that we created

then what we need to do is just to tell

according to its width and height so

let's go into this tab which is called

let's see what this tab is actually

attribute inspector and inside this

it's not scale really i believe it

should be content mode in here and let's

just say it is aspect fit okay

so it keeps the aspect ratio of the

original image but it also ensures that

it's like yeah it's fitting on the

all right so let's then go ahead and

actually see if this looks okay so what

we could do is to write in xcode let's

let's run on ios 13 pro which i believe

is the simulator and that i have already

from xcode itself we can press the run

button to have a look at how this

actually looks like and while this build

process is going you can also go to your

simulator here and say file

and open simulator and i'm just going to

choose another simulator as well such as

iphone 8 plus okay it is just good idea

usually to test your splash screen and

the functionality of your application on

as many devices and simulator as you can

i mean i actually prefer to test on real

difficult for me to bring so many test

devices on the screen so i'm just going

to use a simulator to test the splash

so now what we're doing is just to

compile our application for iphone 13

pro which is a simulator we've been

using so far when it came to for

testing our application so let's move

this to the background because this is

not really our application this is our

application so let's bring it here

just give some time to xcode to do

the work that it needs in order to build

our application for this simulator and

also install it and run it so that we

can have a look a little bit at

the splash screen so i'm just going to

waiting until that process is done

all right now our application is running

on a simulator called iphone 13 pro so

what we need to do is to actually kill

the running of the application because

after the application is launched we're

not going to see the launch screen even

if you for instance send the application

to the background with command shift h

that sends the application to home and

bring it back up there is no launch

screen remember launch screen for an

application is only displayed when the

application is completely dead and it's

cold booting so in order to send in

order to basically kill the application

what you could do is either press the

stop button here on xcode which

and also kills the application so now

you can actually click on the

application in your home screen and

bring it to the foreground and as you

saw that was the little splash screen

that we saw on the screen so i'm gonna

kill the app and bring it back up again

and that's our splash screen so seems to

be actually looking fine on iphone 13

pro let's now change the target in here

and change it to our iphone 8 plus

which is the other simulator that i

and the reasoning for that is that

iphone 8 plus is still a major player in

the market a lot of people have iphone 8

plus and the screen is fabulous it is a

great phone that people are still using

so and the huge difference between

iphone 8 plus and iphone 13 pro is that

iphone 8 plus has no notch so it doesn't

have um the notch that you can see in

here on an iphone 13 pro so and it has a

home button so that's a little bit of a

thing that we have to think about that

you need to test your application on

multiple devices and now i'm going to

kill the application oops i don't

let's go in here and i'm going to kill

the debug process on iphone 8 plus as

well and run it again and let me just

delete this old app from here so we so

if you run the application did you just

see it momentarily that the application

that the splash screen doesn't look so

good it's not doing so well so if i run

it again with do you see the spacing on

the right and left if you pause the

that is because we have a little bit of

problem with our aspect ratio in here

because you remember in this launch emit

launch image we said aspect fit what we

need to do is just to say aspect fill

and aspect fill what it does it tries to

keep it it doesn't try it keeps the

aspect ratio but it always makes sure

that the image is that is at least as

big as its container so having done that

let's run the application again on

with that change in mind and let's see

how the application looks like

now it looked a lot better so there was

no empty space to the right and left i'm

gonna kill the application like this

and let's see oh it's because my debug

debug process i just killed my debug

process so let's kill it again

if i c if i can manage to do that kill

and now i can see that this splash

screen is actually looking good on

great now that things are working fine

on ios we need to focus on android so

let me bring up the caption for the next

section that we're going to talk about

we're going to talk about android slash

screens here i'll also try to open this

so you'll see that there is official

documentation about creating splash

screens for android as well on

um here there is a lot of information

that you can have a look at and like

even animations as you can see in here

what splash screens mean to android

applications and that you can even

animate them etc etc so i suggest that

you actually read the documentation for

splash screens on android to get a

better understanding of the differences

between ios splash screens and android

splash screens it's always good to know

i like the underlying implementation and

how it actually works under the hood

if you're a flutter developer you don't

necessarily have to only focus on

flutter but you since you're deploying

your application compatible with for

instance mac os linux windows and

android it's always good to know in my

how it works under the hood so

if you want to have a look at this

please go ahead and read the

documentation on how it works and now

let's go to this a little beauty

of a link which is on stack overflow

which which is one of my favorite

solutions that i can't even think of the

answers to sorry the problems that i

can't find the answers to so let's go

ahead and have a look at this url in

here which will explain to you the

different resolutions that we have to

provide for our splash screen for an

android device and you saw it from our

so here you saw that when we exported

oh this sticky note shouldn't be there i

don't know why it was added there so i'm

just going to remove it and i hope that

we actually didn't create our

splash screen with that in we could

double check that by bringing up xcode

and have it looking have a look at our

and just have a look at these images

excuse me i'm going to bring it up and i

can see that little sticky note wasn't

in our splash screen so that's really

good it was just probably a mistake

that's great so as you saw for ios we

exported these assets in here three two

with these suffixes so two x four two x

three x for three x and nothing for the

splash screen on one x devices but on

android there's a lot more that we have

to export so i'll open that url in here

that you can you'll also see and you'll

see that these are the various um

resolutions that we have to export for

our splice screen on android we're not

in our application supporting ldb ldpi

in here so we'll we're going to go and

export mdpi hdpi xhdpi and etc etc so

let's go ahead now in your figma design

right there select your splash screen

from the left hand side and go go ahead

please and remove all these exports

that we've created earlier okay so what

we need to do now is to make sure that

we're conforming to these sizes for mdpi

for instance and we're going to

basically select the splash screen and

that okay these are the sizes so 1x

let's just say we don't want any suffix

and i've already prepared something like

that before so let me just show you how

and i'm going to select this splash here

and you can see this is pretty much how

you should create it so one x and we say

mdpi as it was displayed in here mdpi

you see and then we say one and a half x

is hdpi and xhdpi etc etc okay so let's

go ahead and do something similar in our

splash screen in here so one x and as

you could as you could see in the one

that i preferred here one x was mdpi so

let's go ahead and say a suffix is mdpi

i'll create another export in here and

we're in this case we need hdpi which is

one and a half x so let's select this

and say one and a half x and we say hdpi

and then we go for the next one which is

xhdpi so let's go and press the

plus button in here and say 2x is a x

and then we go to the next level which

let's press the plus button and say

and last but not least we have triplex

four x the resolution so let's say xxx

and in here this should be 4x okay so

now oops i didn't want to create this

that's how yours should also look like

with all these uh various resolutions in

so now what i need you to do please is

just to go ahead so make sure that your

slash screen is selected on the left

hand side and then just go and export

all of these so let's just press the

so that's going to take its time and

calculate basically all these different

resolutions prepare the pngs for us and

it's going to pack them into beautiful

it's going to download that packed file

for us so depending on your connection

speed this could take some time and the

result i can see is an untitled 2 zip

of about 10 megabytes so there we go

double click on this file in order to

unpack it and i'm going to open the

folder here for you so you can also see

as you can see splash screen

it's all there so they're all looking

very similar to each other but they have

very different sizes as you can see

though so the xxx hdpi has the size of

almost four megabytes whereas the mdpi

now we got our images perfect so what we

call them splash screens and then place

mipmaps folder in our android

application so let me bring up visual

studio code in here let me see where

i've placed my visual studio code right

go into exploration a little bit here

you can see we have an ios folder so let

me just make the size a little bit

and we have an android folder in here so

if you go to android and then app src

main and then res and you'll see that

you have these mipmap folders hdpi mdpi

and all those one two three four five

folders that we need for our five assets

in here okay so let's go ahead and

actually name this file in here and let

me close this little folder that i have

at the bottom of the screen as well so

okay so um we start with mdpi in here

let's just call it splash okay slash png

and i'm just gonna go to this mdpi

folder here and i can see i have a

launcher icon an ic launcher so let's

just drag this into mip map mdpi if i

and mid map mdpi there it is so the mdp

i'm going to delete it from here so now

we have hdpi then i'm going to call it

splash again remember it's hdpi so i'm

going to drag and drop it into the hdpi

folder so it's called png there as well

then i'm going to delete it from here

then we have the xhdpi so i'm going to

and remember xhdpi so let's go and drag

it there great then delete it from here

xxhdpi so call it splash again

and bring it into xx folder in here

and i can see it's right there splash

and last but not least we have the

triple x hdpi and we're going to call it

slash again and then let's go in here

great so now you should actually see one

and five images that we have exported

and placed inside our android folder so

then i can delete the last one safely

so now that we've done that we need to

actually tell our android application to

use those splash screens so what we need

to do is to look for android window

background inside our application i'm

going to close all these open tabs and

i'm going to search for android window

background just like that okay

so you'll find four of them but only two

of them are actually interesting for us

so what we need to do is actually i'm

going to go to my styles as well here so

as you can see here is using a drawable

but we're not using a drawable a

drawable is something that for instance

if you look for launch background let's

fine launch background actually is there

a drawable called launch oh we don't

have it right now okay anyways so i'm

android window background as it was our

so let's go in here and find that window

background and here as you can see it

says drawable launch background and this

file is android app src main res values

styles xml so that's the first one okay

that's this drawable so i need you in

here to change this to mipmap

and in here just say splash which is the

name of our file that we created okay so

that's the first um occurrence of this

android window background and then we're

going to go in here as well which is in

android app src main res values knight

styles xml and call this mipmap

and in here we also say splash perfect

so what we need to do now is to actually

test our changes on android as well so

i'm going to close all those tabs as you

saw and let's just go to main dart file

just to have a dart file open

and then i'm going to stop the running

of this application because i don't

really know i think it's actually

running the application on um the iphone

simulator and then i'm going to say

command shift p on a macintosh or ctrl

shift p in windows and linux if you're

on visual studio code and then say

flutter select device as you can see in

here and then i'm going to choose my

android phone okay and as you know from

chapters i actually prefer to run my

applications real phones and then run

and then run without debugging

basically kick start our gradle build

processing here and while that is

ongoing i'll go and bring um scr cpy to

the screen so here it is and

nothing actually what happened to our

i think our build somehow crashed so

let's go and build again and see what

okay i can see it says there is a

problem and let's see another expected

caller reference bot got raw string mid

map splash okay so let's have a look at

what we actually did with this mid map

splash i can see i've actually written

incorrectly i've written me map so that

could that could explain it it's a

mid-map so if you've done the same

mistake as me in one place please just

fine okay fair enough and let's now try

to run the application again and see if

it got a raw string again and it's now

did i really type it in correctly did i

this is unbelievable um if i've actually

so no i i think i've actually written it

in two places incorrectly so

it would be very comical if i made a

mistake again while trying to fix my

so let's see now if the android build is

gonna go through successfully so i'll

just wait here until that task is done

okay it's built successfully i was just

gonna go grab some coffee so

and it's connecting now so that actually

went really fast i would say gradle

builds in here are surprisingly fast

when running with flutter for instance

compared to the ios xcode build system

so i'm going to bring up scrcpy in here

and i can see the application running

without a problem but we didn't actually

what i'm going to do is i'm going to

processing here which kills the

application and then i'm gonna find our

application here and then open it and

then i can see our beautiful splash

screen on the screen when the

application starts so that's also

working as expected no problems at all

and remember we've done quite a lot of

work now we've done like icons from the

previous chapters and we've also worked

there's lots that we've done but we

haven't really committed any of these

because the work wasn't complete

both icons and splash screens on both

ios and android i think it's time that

we do as we usually do at the end of

every chapter is to commit our work and

make sure that we're not going to lose

so i'm going to do some reshuffling on

the screen right here and i'm going to

increase the size here as well so i'm

going to go to terminal then like this

and let's then have a look at the status

and you can see that we've done a lot of

there are many files that have been

changed as you can see in here modified

a tremendous amount of work so

let's just say get at all and then let's

is it step 28 yes step 28 okay

so if you look at our logs so we have

step 27 and then we have step 28 as well

so i'm gonna push all these changes and

this push is actually quite a big push

because we have a lot of resources that

we're pushing to github so or wherever

you're hosting your git repository it

could be bitbucket or somewhere else but

depending on your connection and the

ability of your host to receive these

files this operation could actually take

some time so and after we've done that

let's also tag our work at step 28

like that and push our tags

all right so if i say now git tag we

27 and 28 line up right there so perfect

and we should have no status right now

as it's tradition after our tagging and

committing everything at the end of

every chapter we'll talk about what we

need to discuss in the chapter that is

i can't believe we're actually getting

to this point in this course it is such

a huge moment both both for me and i

hope it is for you as well because we

are actually going to submit our ios

so without further ado if you want to

get some refreshments please do and i'll

hello and welcome to chapter 47 of the

uh we've been waiting for this moment

for a very long time now at least i have

so that we have been developing our

application using block we've been doing

a lot of work with widgets we've

prepared splash screens icons etc etc

we've even got our hands dirty with

figma a task that maybe many of you

what is left now well we're gonna send

our application to the ios app store and

it gives me really a lot of pressure

pleasure to actually announce that that

what do we need to do in order to be

able to interact with the app store and

in order to be able to create your

application of course you you're going

to need to have a macintosh and that is

as i've mentioned an unfortunate fact

when you're dealing with ios development

but if you don't have a macintosh you

can always contact a friend or maybe you

use a service on the internet that can

for instance take your source code and

build your application for you i don't

know if those services exist however

let's just accept the fact the

unfortunate fact that you'll need to

have a macintosh in order to build your

application and send it to the ios app

what do we actually need you see when

you create your application for um for

apple you need to bundle it up inside a

file which is pretty much just a zip

file but its extension is called ipa

and this zip file in essence contains

your entire application bundle all the

signed binaries from your side and then

you'll just need to submit it to apple

then this submission is going to go to

something called app store connect and

we're going to now talk about app store

connect actually and what that is so you

when when you're developing your flutter

application for instance and you're

talking with firebase then inside of

your code you're talking with the

firebase sdk but on the backend side of

firebase then there's an entire console

so there's in the console.firebase

google.com i think it's called

or if you just google it and say

firebase console you'll get to that

the firebase console for ios developers

so it is where you basically manage your

the reviews that are submitted to your

applications you can respond to those

reviews so it's like the back end

is kind of like a front end for app

you could say so it's your portal

basically to to the app store as a

and google also has something similar

which is the google developer console

me so what we need to do now in order to

be able to continue we need to actually

create our applications on the app store

connect so what i'm going to do in here

is i'm going to bring up app store

connect and i've already logged in with

and let's go in here as you can see

these are some of the apps that i'd

submitted to apple previously

if i can increase the size of this let's

so what we need to do is in order to be

able to submit our application if we

haven't done that before for this

particular application which we haven't

we need to create an application here on

app store connect okay so please go to

and then you'll be presented with a

screen that asks you okay what do you

want to do with app store connect and it

kind of looks like this my apps app

i'm assuming that you have admin access

to app store connect because apps are

permission it's like permission based so

if you're for instance working with a

company and that company has invited you

to their own app store connect account

and depending on the permissions that

they set for you you may or may not have

access to either one or all the apps so

it is also app-based the permission so

like and i can invite you to my app

store connect and only give you access

for instance to this application and

only give you a very limited access or

so if you don't have access to this app

sections because you're invited as

um as a user to someone else's app store

connect account and they haven't given

you the access to access their

application so you need to ask them for

permission basically to increase the

so let's go ahead and press this plus

button and this is in here we're going

to say new app and in here it's going to

ask you okay what kind of app is it it's

an ios app it's not a mac os like we

haven't really worked on a native mac os

m1 processors on macintosh with

macintosh which are arm based they can

actually install ios applications as

you'll soon see so this application that

we're developing flutter we didn't

actually create a macintosh target for

it but even though it's an ios

application you can still install it

with test flight or later when it's

actually released on the ios app store

you can install it with the mac app

store on your macintosh so it's

okay so here one you need to do in the

you need to find a unique name in the

entire app store there are millions of

applications on the i'm actually making

up this statistic i don't know if it's

like hundreds of thousands of

applications or millions but let's just

let's just say millions because easier

all these applications are in the app

store you have to find a unique name for

your application and remember you can't

use reserved words so if you look in

if i cancel this if you look in here

this is not an accepted application name

so i just i've prepared this in here

just to demonstrate it for you that

if you use for instance a name like

probably apple is going to reject your

application and definitely google is not

even going to allow you to go to the

google play store with a name

with a part of your application name

being a reserved word like a product

you have to find a unique name that is

not reserved so let's just say ios and

what should we call this i mean in our

application we call it now my notes

i'm pretty sure if you say my notes that

awesome notes something like that

as you can see it says it is the name

that will appear in the app store okay

and in here in this box the primary

language we're going to choose english

and we're going to choose us because we

our language like how we actually

interact with the user with our strings

in the application to make sure that

it's like british english or us english

so let's just go with the international

and in this box you're going to be asked

to actually choose your bundle

identifier and app store connect has

then after you log in with app store

connect it's going to hook into the

developer account for this user that you

logged in with and it's going to pull

all your bundle identifiers into the app

store connect so you don't have to type

it by hand so let's go find our my notes

application as you can see in here it's

as epic salty my notes and for you it

so i chose that and then sku is a unique

id for your app that is not visible on

the app store so this is mainly for you

it kind of comes from like um

old school when you had a normal

physical store and your products had

kind of like an identifier so this is an

identifier for you it may appear some

places like when you're extracting some

reports from apple to see okay how many

unique users do i have how many unique

so this sku is mainly for you it's an

identifier so you could just go with

something that makes sense to you and in

here i'm just gonna say zero one zero

this and then one one one one

and user access in here you can say you

you can limit which user see this app in

the app store connect if you select full

access all your users will have access

to the app so this is like you limiting

who can in your app store connect

account who can have access to this

application and since i don't have any

guest users in my private company's

account i'm just gonna go with full

access but if you're working with like

if you're if you're the account owner

and then you have some other people

invited to app store connect that don't

want that shouldn't get access to this

account you could just go in here and

basically say limit the access to this

application to these accounts but i'm

just going to go with full access okay

i'm going to say create and in here is

the place that you may actually get a

problem with the name of the application

so let's just try it out and see if my

awesome notes is some name that somebody

else has taken and we'll get to know

and from from the looks of it it seems

like that my awesome notes was such a

lame name that nobody has taken so

so that's great for us so um now we've

created the application and um

so as you can see in here the first

thing that you have to enter in this

screen let me actually increase the size

and let me change the screen layout a

so the first thing that we see on the

screen here is that uh there's a version

information and also there's app

previews and screenshots and this is the

place that we're gonna upload our

screenshots to the app store

as you can see at the bottom of the

screen it's very important that you take

your screenshots first on an iphone 13

the iphone with a six and a half inch

display and you may be tempted to just

try to take your screenshots on an

iphone 13 pro but if you do that then

you'll understand after uploading them

you'll get an error from app store

connect saying that the resolution isn't

according to what is expected so what we

need to do here is to go to our iphone

um simulator so and i have quite a few

so this is our iphone 13 pro

and also we have our iphone 13 pro max

so now our responsibility is to actually

take the screenshots on this simulator

however you'll notice that we have a

well problem problem but for taking

screenshots this is a little bit of a

problem in that we have this debug

manner here that i am that flutter

creates by default so if i zoom in a

little bit here you'll see that it's

it's just saying debug right here and we

need to make sure that we remove that

before taking our screenshots so what

i'm going to do is i'm going to go back

and you can see at the moment the

application's running on iphone 8 plus

which is the simulator to the left hand

side so in order to remove that debug

banner what you'll have to do is to go

to your main um dart file as you can see

and go to the main function where you've

created the material application right

after the title or even before you can

just say banner which is debug show

check mode banner and set that parameter

to false and then i'm just going to do a

hot reload actually hot restart we have

oh i'm not even running it so let's just

go flutter select device 8 plus and then

i'm going to say run without debugging

so you need to ensure that you remove

that um debug show checked mode banner

and i started not remove it you have to

remove the banner by setting this

parameter to false and now it's going to

basically run the application on iphone

8 plus and it's going to show us the

results so this debug banner is going to

after doing that when we see that it's

working on iphone 8 plus for instance

then we're going to do the same thing do

a flutter select device and run the

application on iphone 13 pro max so

this process depending on your machine

depending on your settings etc it could

take a while so i'll just wait here and

now it's running okay that's eight plus

that's great so now that's done now i'm

going to close this and stop the debug

process and say flutter select device

and choose iphone 13 from max

and do the same thing run without

again depending on the machine that

you're running this command on this

process could take anywhere between a

few seconds to maybe even a minute or

i'm just gonna wait here for this

process to go through and um

while that is actually happening you'll

also need to know that you need to take

your screenshots on iphone 13 pro max

and iphone 8 plus in order to be able to

cover all the required screenshots for

app store connect so since we don't need

iphone 13 pro i'm just going to minimize

it right now into the taskbar and here

so let's go ahead in here and take some

screenshots so i'm going to minimize

iphone 8 plus as well so we have this in

focus so what i'm going to do in here is

i'm going to go to this login field and

at the moment as you can see i can type

in this field because this is a

simulator but i don't see the keyboard

but in real life when users actually

download your application and run it on

their iphones they're gonna see a

keyboard so it is a lot more realistic

if we bring the software keyboard as

well on the screen so to do that on your

macintosh we'll just have to do command

k for keyboard and that will just bring

up the keyboard just like this so

what i'm going to do since i don't like

this carrot that at the moment is

i'm going to do is just wait until that

carrot appears and just take a

screenshot of this iphone 13 pro max

simulator and the way to take a

screenshot on a macintosh on an iphone

simulator is to press command s as in

so i'm just going to wait for this care

and sorry about that i'll just go also

here in desktop and remove everything

here's the simulator and here's the

desktop then i'll wait for the care

and it went away i took a screenshot so

let's go ahead and do the same thing in

forgot password screen for instance

and i'm just going to wait for care to

then let's go back to the login screen

and right here as the care disappears

i'm going to take a screenshot as well

so this is going to be our third

screenshot okay so we have a screenshot

of the login screen the register screen

i forgot my password sorry okay so now

i'm going to log in with a user that

already exists in the application so

that we can take a screenshot of the

main interface of the application as

well so i'm going to take a screenshot

of this with command s on my macintosh

and maybe for the fifth screenshot we're

also gonna take one from where you're in

the screen and editing your notes with

the keyboard up as well okay gonna wait

for the chara to go away and i just took

a screenshot right there as well so now

you should end up with five screenshots

for your application so if you have a

look at them they should kind of look

like this this this this this and ensure

that also you don't have that debug

manner by removing the debug show check

mode banner and after doing that if

you're already running a debug session

on your simulator for instance you have

to do a hot restart remember hot reload

is not going to take it's not going to

take the code in your main function into

effect all right so now we have five

screenshots in here so i'm going to go

back to app store connect and let's then

tap here or click here and view all

and let's go to choose file in here and

then choose all these screenshots and

all right so now in here you have

basically the chance to reorder these

screenshots so i think i'm gonna put

maybe the login screen first then i'm

gonna go to the register and then forgot

password and i'm gonna then put the main

interface of the application

here and then the actual new node screen

okay so you can see at the moment when

uploading the six and a half inch

display screenshots the five and five

and eight inch display screen is also

inch display screenshots so they're the

same screenshots so you don't have to

upload them again however then you have

this five and a half inch display and

which you also have to upload your

screenshots for and that is what we need

we i'm just going to minimize this and

then i'm going to bring up iphone 8 plus

and we're going to do the exact same

process here so bring up the keyboard as

the carrot goes away take a screenshot

carrot goes away take a screenshot then

i'm going to go to a register screen

carrot goes away screenshot and in the

login screen i'm going to log in with a

user that already exists in the system

it's my keyboard by the way i can't see

the keyboard so i can see it's been

switched to unfortunately swedish so i'm

it's not helping me really so let's see

for some reason it's still showing the

swedish stuff in here and i don't really

know why so i'm just going to say

gmail.com and foo barbados okay

an iphone simulator is also software so

it could be buggy okay so then i'm gonna

let's see what screenshots we've taken

so three screenshots so far and let's go

to the main ui of the application take

another one with command s as i've

mentioned before and let's go here as

oh is this screenshot gonna go away

please go away okay i think iphone 8

plus is having some problems so what i'm

gonna do is i'm just going to close it

and then say open simulator and let's go

to 8 plus and i can see after i close

the 8 plus simulator it actually saved

the screenshot so that's great all we

have to do is just to go back to our

application and right here in the screen

as the keyboard is displayed on the

screen after the carrot has disappeared

i'm going to take a screenshot

did it at the right time without the

carrot on the screen so let's have a

so this is the screenshot so now we have

five screenshots on iphone 8 plus as

well so i'm gonna basically delete these

screenshots that we took from the iphone

13 pro max right there and let's go to

the five and a half inch display section

here in app store connect and say choose

file and i'm then going to choose all

those screenshots that we took from

iphone 8 plus and reorder them so let's

say log in first then we have register

forgot password and then main interface

of the application and then new nodes

and this is exactly in line with what

we've done in here so it's just a good

idea usually to make sure that your

screenshots are lined up in the same

order for different devices okay so now

three other screens screen types are

plus i think simulators screenshots so

yes iphone 8 plus so now we've uploaded

those so as you can see more screenshots

are already there now so iphone 8 plus

is also uploaded and we're done

so what we need to do now is to bring up

the ipad pro 12 inch simulator as well

so i'm going to go here to this

simulator and say file open simulator

as you can see we have to bring ipad pro

12 inch so i'm just gonna click on it

let's go to um visual studio code and

say select device and then i'm gonna

choose that ipad pro as it is there and

then i'm going to stop the debug process

on the iphone 13 pro max and then say

and if you're lucky then this process is

actually going to go quite fast because

the application binary has already been

compiled and it should pretty much be

again depending on your machine this

process could take anywhere between a

few seconds to a few minutes even

let's see here so let's go in here and

you can see the first section in app

store connect for ipad is asking you to

for ipad pro third gen which doesn't

necessarily have to be third gen any

ipad pro of 12 and a nine inch display

so here's our application it this screen

is obviously ginormous so i'm gonna go

here bring up the keyboard and

take a screenshot and then go to forgot

my password take a screenshot then go to

back to login and in the register screen

take a screenshot all where the carrot

has disappeared let's just double check

this and i'm going to remove the iphone

8 plus screenshot so now we have three

on the ipad pro no carrot no carrot no

carrot and let's go now to the login

screen and i'm going to log in with an

existing user in here okay foo barbat

login and now you can see the main

interface of the application let's take

a screenshot of it and then go to the

first note bring the keyboard up like

this and without the carrot take a

screenshot i actually think i

i um captured the carrot unfortunately

in this last screenshot and i can see a

little bit of glimpse of it there so i'm

i think i did it actually again to take

of the same screen with the carrot

if the ipad's going to help us soon

where's the screenshot there

i can see the carrot again a little bit

so this is a tough one now all right i

so let's just wait for the screenshot to

and there is no carrot so that's great

so now we have basically our screenshots

12 and a nine inch display let's go in

here and say choose file and i'm gonna

select all the screenshots for that ipad

and put them in order so i'm just going

to say the login screen first then

register then forgot password the main

interface of the application and then

the note screen okay so as you can see

the 11 inch display is using the 12 and

a 9 inch display so that's really great

however the ipad pro here the second gen

to 12.9 inch display um is

is i mean these it's not using this 12

and a 9 inch display of this ipad so

what could we do here can we go in here

and say choose file and upload the same

screenshots again and it seems like we

can so that's not a problem let's just

reuse the same because it's the same

screen size so it's a bit strange that i

app store connect is not automatically

ipad screenshots for also this 12 and a

9 inch display even though they're the

same so i'm going to bring login to the

left then i'm going to bring register

here for god password like that and then

the notes and then the new note so now

you can see all your screens are now set

all the snap all this screenshots are

set for both iphone and ipad

so after uploading all our screenshots

then we can actually go and set the

so let's go in here inside our app

and you can see here there is a note and

sorry there's a name inside the app

information section then we have the

name of our application okay and then

the subtitle as you can see it says the

subtitle will be reviewed before it's

made available on the app store

unfortunately it doesn't tell you so

much information but every application

can have a short subtitle up to 30k up

to and including 30 characters so when

people search for my awesome notes for

instance in app store then they can

actually see both the name of the

application and a short subtitle so

your notes securely with an asterisk at

so that's already set i can see so um

and then we could then after making

the app store connect expects you to

press the save button so that's also

so let's go here in this section and go

to content rights and then set up

content rights information click on it

so it says apps that continue or access

third-party content must have all the

necessary rights to that content or be

otherwise permitted to use it under the

laws of each app store country or region

so we don't have third-party content

like we're not actually displaying any

videos that's coming from a third party

service so here we can just say no it

doesn't contain show or access third

and after pressing the down button we

can also press the save button just to

ensure that everything is as saved

so what we need to do in here also um

a privacy we also have and then we have

set age rating across all platforms so

let's go ahead and do that and say as

you can see here it says select the

level of frequency for each content

description that best describes your

application so we don't have any

violence so we say no realistic violence

uh prolonged graphic or sadistic

realistic violence i don't even wanna i

don't even to say say these things out

loud to be honest with you but what you

have to do is just to say none to all of

these because we don't have any like

medical information alcohol related

stuff so let's just say none to all of

contests and we don't have that either

so let's just say next does your app

contain unrestricted web access it

doesn't does your app contain instance

of gambling no and then we're saying

rate rating result is that people of age

four plus can use the application and

make sure that your app is not made for

kids because remember applications that

are made for kids that have to actually

conform to specific standards in order

to make sure that eight kids of age four

plus are actually safe in the

um what we could do let's see in here if

your app rates 12 plus or lower and you

believe it contents may not be suitable

for children under 17 you can manually

set the age rating to 17 plus so i'm not

sure about this to be honest with you

but i'm just going to leave it blank at

the moment and press the down button

okay and then we can press the save

so the next thing that we need to talk

about now is something called a support

url and support url is actually very

important and that actually appears i

i think it is somewhere around here

ratings and reviews app privacy

we haven't really come there yet but i

believe we have to submit that anyway

somewhere and it is here as you can see

so support url is actually very very

important as you can see marketing url

optional sorry marketing url is optional

support url isn't a support url it's

that needs to be hosted on your website

that users of your application if they

have any problem with it then they can

go to the support url and get some more

so i have previously created a support

url for one of my other applications in

my website so let's just say pixel sc

and then we're going to say support

chords library text okay and as you can

see here it's a little text document and

says if you have any questions about

this app you can drop us a line at

so you need to just ensure that you have

a support document that you can um

place in a website and then you can send

let's now go ahead and create a support

document so what i'm going to do in here

i'm just going to bring up literally

text edit on my macintosh you can bring

your um favorite hex editor um um

actually my tech favorite text editor is

visual studio code but in this case it's

just a simple text document so i'm just

going to use um normal text edit on

macintosh even if you're linux for

instance you can just use vim and create

or vi you can create a simple document

and let's i'm just going to basically

copy this and paste it in here and i say

contact support and thank you for using

because that's the name of our

application right it is my awesome notes

so i'm going to save this document and

i'm just going to say in here let's call

notes txt and i'm going to save it on

it is a little bit strange that it

let me go back to this text now it saved

yeah it is right here okay so this is a

document now text file simple and i'm

going to go to my website control panel

as you can see here there's a support

so i'm going to go into the support

folder and as you can see i already have

four text files in this pixelity se

website and i'm just going to

hopefully be able to drag a file in

there or maybe even upload so i'm going

and i can see it has uploaded now

seems to be it to be honest

so let me just go back and see i'm my

awesomenotes text file right there and

i'm then going to go in here and see

and i can actually see it is uploaded

if you don't have a website which you

should if you're developing applications

for ios and android or even if you're

developing any applications and putting

it out for customers you should have

your own website and they're like very

a website with cheap hosting i don't

sponsor various services and i'm even

not even gonna name what i'm using but

just search online for a cheap hosting

and creating a website of your own okay

but since this is the outside that's

outside the scope of this course i'm not

going to talk so much about that okay so

now we have this my awesome notes and

is to go ahead and add this support url

so i'm going to copy it here and go to

app store connect and in the support url

i'm just gonna save it there i'm gonna

press the save button okay

that's that and we also need to make

sure that we add some other information

in here promotional text description and

also keywords and etc okay so

these things are very important and we

need to make sure that we fill these out

so um let's see actually here okay

so in the promotional text let's just

enter in some information here as you

can see this commercial text lets you

inform your app store visitors of any

current app features without requiring

an updated submission okay so let's just

store your notes in the cloud

all right and description and this app

sim this free app allows you

store your notes securely on the cloud

and that's it i mean they're very

similar to each other but that's okay

and for the keywords in here you have to

it doesn't really say how many yes 100

characters you have and you have to like

comma separate your keywords in here so

i'm just going to say and notes and

and make sure you don't have to actually

i don't think you have to have space

between them and i'm just going to leave

it like a notes secure cloud okay these

i'm going to save this and remember

we're in here in the ios prepare for

and our app version is right there

copyright we can just say 2022 pixelity

okay these are just big words don't

and that is pretty much it so

i don't think we need to do so much more

to be honest with you in here

and uh we don't even have to have the

let's see and also need to go to contact

information in here so let's say

and then i'm going to enter some

fake phone number right now

something like that and here's my

and here where we have the version

release as you can see it says this app

version can be automatically released

right after it has been approved so

how you want to actually release your

application so after you send your

binary to apple you can choose for apple

to either automatically release this

to all your users in the app store or

you can say manually release this

version meaning that after your

accepted by apple and approved by apple

you can go manually press the release

button wherever whenever it suits you

or you can say automatically release

this version after app review no earlier

now so you can set a date for it but

we're gonna say manually release this

and after all of this i'm just gonna

save this information right there and

let's now go to app privacy so this is

also very important to remember to do

yeah i actually believe here now that

i can see that i've prepared some

information about this in the upcoming

we're going to take care of privacy

policy in the next chapter so but know

that it exists right there and we have

so then what we need to do is to

actually make a build for apple because

this is like the most important part and

and you need to make sure that you

followed like the first chapters of this

course where i talked about preparing

our application for ios there is a

chapter in the beginning of this course

where we actually talk about creating

our certificates and profiles and all of

for ios distribution so i'm assuming

you've already gone through that so we

don't have to take care of that now all

right so let's go now to our application

in xcode let's see if i can bring up

it is somewhere around here

so there is our application and i'm just

going to go into runner and have a look

at signing and capabilities and release

and i can see that there is absolutely

no problem with this production

certificate and profile so what we need

to do in here to make a release for app

store is just to have a look at our

runner and here change the target to for

and then we go to product and then we

this archiving is then in turn gonna

create an ipa file for us and as i

mentioned in the beginning of this

chapter and this is the ipa file that

we're going to submit to apple

xcode is going to help you a lot with

i'm not sure if i'm a fan of that to be

honest with you i think xcode hides a

lot of details and usually i'm used to

like doing things in the command line

and doing things simply from visual

but it is still a good thing that xcode

is going to help you submit your

in the previous versions of xcode like

many many years ago xcode couldn't do

this so you had a separate application

to actually upload your ipa files to app

and that in itself was also quite

i wouldn't say a negative body was

something that you have to go through

it is a plus and a minus that xcode is

going to take care of all of these in my

i'm just going to wait here for xcode to

work and it is very possible that if

this is the first time that you're

archiving your application with the

basically created in the beginning of

this course it's very possible that

when the time comes for xcode to

actually sign your binary and all its

it's possible that your macintosh is

for the password to this certificate and

actually it's going to ask you for the

in which on your computer this

certificate is stored so this is usually

the login keychain so if i go to

keychain access in here you'll see that

i have my login keychain and i have

certificates in here as you can see

this is the sort that i'm at the moment

using for duplication and um after

assigning this as you can see it's

archiving right hasn't really signed

things it's very possible that my

macintosh is going to ask me for the

password to that keychain so

finishing the archiving process so

so let's see basically how it goes after

after doing that after actually creating

our application ipa file we're going to

submit it to apple and that app is going

to be displayed then first inside here

in the build section of your

so let's see if we get this password for

signing as i've mentioned here

at the bottom of the screen so 4660

or 70 files out of 5039 files to

creating our binary so it's very very

close let's just see if it can succeed

and i can hear my macintosh um

and fans going full speed right now and

that's usually something you don't hear

max or macbook pros because they're

usually so silent like the fan almost

but this is apparently such a heavy

process for this macintosh to perform

the faster googling full speed so

all right and here is where we're seeing

that dialogue that i was talking about

as you can see it says code sign wants

to sign using your van.hawa nippor in

your keychain to allow this enter the

login keychains password so it has

nothing to do with your certificate it's

just actually has everything to do with

your certificate but the password itself

is the login keychains password so

it's usually your computer's password so

i'm just going to enter that

and then i'm going to say always allow

after doing that hopefully xcode is not

going to bother me with this password

again however i know in some older

it doesn't really understand when you

say always allow so when it comes to

signing your application you may have to

password up to like 20 times depending

on how many libraries your application

i remember this vividly when i was

working at a company and a tester i was

compile an archive an application for

ios and we both thought that he's

entering his password for his

certificate incorrectly so and here now

module shareplus not found and

what could that be because shareplus is

basically something that we're using in

and it's continuing to archive even

though it it says that something's

failed so all right so now we got an

issue here with pods runner framework

and this could seem i mean i'm actually

quite glad that we're getting these

errors and that could some and be

because we haven't done a proper pod

install so what i'm gonna do is go to

visual studio code here and in the

terminal then let me actually change the

screen layout a little bit so you see

so i'm gonna bring this up so you see

better what i'm doing and i'm going to

okay and then in here you could just say

basically pod the integrate it's going

to remove all your ios dependencies from

your workspace and then you could just

and this is gonna reinstall all your

dependencies from scratch so

let's see and i can see share plus is

actually installed now so it's

generating the pods project

great so that seems to be fine so let's

go in here and see if we can

uh do a clean so i'm gonna go to debug

sra product clean build folder and let's

see if we can make a fresh build and

this could actually take some time

uh cleaned the build art artifact so

it's gonna basically start the archiving

process from absolute beginning so

i'm just gonna be quiet for a while and

let us do its work and let's see if the

archiving process succeeds

okay so here's the result of actually

archiving our application again and

we're seeing the exact same problem now

after doing a podly integrate and also

doing a completely new pod install so

we're seeing the exact same problem with

share plus say module share plus not

found and this could be a problem with

how we've done for instance our

and to be honest with you i could cut

this out of this whole video but i'm so

so glad that we're seeing these problems

archiving an ios application and simply

not always going to go fine even just

doing the same thing for android it's

not always going to go fine and

if i cut this out of this video you you

will be thinking that everything is

going fine for me but things are not

working for you and then you'll start

blaming yourself but i really want to

keep these stuff in this course so you

see that well a person like me trying to

tell you how to do things also needs to

understand himself how and why these

in my guess in this case since we've

already done a pod install it would be

build folder for our entire flutter

flutter pop get from scratch so

let's go ahead in our flutter

application in here and at the bottom

i'm just going to say fluffer clean

and that's going to clean the artifacts

and then you're going to get a lot of

errors in your application because then

it doesn't understand anything so we

so that's gonna do its work and get all

your dependencies from scratch basically

and install them in your application

all right then what i'm gonna do in here

yeah we could just leave it like that

now and go back to our xcode and then

try to archive the application from

scratch let's see let's see if this time

it goes a little bit better and

hopefully it shouldn't take so much time

this time but you never know with xcode

with ios development it has its own

antiques so let's just wait and see

after doing a pop get if this process is

going to go through or not so after

xcode has compiled the application again

i could see the same problems as as we

had before so meaning that our pod the

integrate and flutter clean really

didn't have so much effect on the

application itself now since i've been

doing ios development for a very long

time i still have some tools in my in my

belt that i can drag out and use

and one of the first things i would use

as a software engineer and an ios

developer is just to first have a look

our deployment ios version and here

we're supporting ios 9 and it's very

sharing capability that is built into

the plugin that we're dragging into our

application isn't compatible with this

ios version so first i'm going to bump

at the moment at the their ios 13 14 and

50 are very popular so there are the

latest versions of ios at the time of

recording this um course so first i'm

the next thing that i'm going to do is

to from our project in here so i'm

having a look here as you can see i'm in

the ios folder of this notes project so

then the first thing i'm going to do is

to perhaps remove the um i wonder if i

should actually remove the pod file as

maybe let's just remove the podfile.lock

and remove also all the pots from the

project okay so then i'm gonna do

that removed really all the pots from

and then after undoing that i'm going to

have actually a look at our pot file to

have a look at all our ios dependencies

and see how they look like so i'm going

to stop the execution of the program and

then i'm going to open a file called pod

file and this is where all your ios

dependencies basically are stored as you

can see the platform is ios 13. so it

was strange that our deployment target

was ios 9 so this could be a potential

and after doing that then we have our

pod file and yeah this this looks fine

um let's then go after into the terminal

and after flats are clean let's just say

our dependencies into our flutter

project and ios project for instance

then and we can then go back i'm

actually going to kill xcode and open

project workspace again and i can see

here at the moment the pods aren't

really installed so let's go and do the

installation of pods ourselves so i'm

going to say pod install this is going

to install all the dependencies and

let's have a look in here and say what

cloud fire support as far as store using

firebase is defining okay those all look

fine here says coco pods didn't see the

base configuration of your project

because your project already has a

custom config set in order for cocoapods

integration to work at all please either

set the base configuration of the target

runner to target support files blah blah

blah or include the target support files

in your build configuration so this

could actually be very important as we

there was a problem in setting up our

project with flutter create when we said

we created our application to begin with

but let's just keep this in mind and try

go in here and open our workspace one

more time and now i can see all the pods

share plus is right there pod okay

and the pod spec what is the pod spec

says it actually says the platform

should be ios 8 so it supports ios 8 so

that's not a problem so what i'm going

to do now is after doing all these

things i'm going to basically try to

build this project again so i'm going to

do a clean here clean build folder with

command shift k so blink basically clean

all while all of this is going on

editor functionality that's that's fine

so i'm going to basically start doing a

product and archive again and then i'll

see you on the other side either this

succeeds or fails and if it fails we're

gonna fix it so let's have a look

after doing all the gymnastics that i

then our application has finally

compiled without a problem and to be

honest with you this is one of the

things that i believe many courses are

when you go through distributing your

application you actually go through a

lot it's not just that you press a

button and submit your application and

you're done well usually if everything

is set up correctly then that is the

case however you have to set up

so what happened in here is that we have

to issue a few things what i did

just to name them step by step is that i

deployment target of our application

from 9 to 13. so you can find that by

clicking on your workspace in xcode then

clicking on your runner target general

tab in here and then the deployment

information i bumped it to ios 13 so

that's the first thing that i that i did

however i don't think that that

necessarily had anything to do with

the other thing that we did from

all our pots and i did that by saying

now we issued that command from the ios

folder if i open this ios folder you'll

see that there is a folder in here

called pods what are pods pods are

basically your applications dependencies

for ios that's how flutter manages your

ios application dependencies so all

these libraries for instance like

firebase and this sharing library that

we just dragged in they're using

basically they are dependencies that

flutter manages using cocoapods which is

a third-party software and you have to

have cocoapods installed on your

computer in order to even be able to

interact with pods so there's lots of

information on the internet on how to

install cocoapods but it's usually

pseudo jam install cocoapods and i think

maybe you can even use homebrew to

install cocoapods but i usually use

or jam in this case but you need sudo

usually to install cocoapods so

so what we did we removed the pots

folder we removed the podfile lock which

for you who are like comfortable with

backing the web development with npm

this is this is like your package lock

file and if you're not comfortable with

back-end development basically a pod

file lock is a file that stores

information about all your dependencies

which are currently installed

whereas the pod file stores information

about which dependencies you need and

pod file log stores information about

the ones that are integrated right now

into your application so we remove that

just to ensure that on the next pod

all our dependencies will be freshly

installed and regardless of what is

there were a few steps that we had to

take but finally we manage oh also we

don't forget flutter clean we also

after all these steps we finally managed

to build our application and as you saw

in this screen we came to this archive

i want to have a look a little bit here

so yeah we've done the password signing

etc etc and now we basically

ipa file in here so one you need to do

in here then you press the distribute

app button and say app store connect and

and this is going to do some analysis on

and it's this is going to connect to app

and some of you in here may immediately

get an error saying that well i don't

know how to connect and that's because

profile information in xcode if you go

to xcode preferences there is a section

called accounts and you need to ensure

that you basically add your app apple id

with your account in xcode for any of

for the distribution to actually work at

all so i'm going to say app store

connect here and next upload to app

and it says okay upload your app symbols

manage version and build number i don't

really like that so we're gonna take

that off so we're not gonna use that

and let me just make the screen a little

bit bigger and press next in here and

here you have to select your uh profile

press the next button in there and this

is going to contact app store connect

and depending on your application size

this could actually take quite a long

time for some of the applications that

not personally but for various companies

even with my thousand thousand download

internet connection this process could

take a long time so let's see how long

it takes because you see during the

upload process it's not just uploading

your binary it's actually contacting

even validating a lot of your assets

like your images it's valuing your icons

it's valid validating even if you have

other resources in your application and

i believe it even checks like if you're

api calls which you shouldn't be making

and i'm not talking about network api

calls but i'm actually talking about ios

sdk api calls for instance if you've

hidden some work in your application

which is making uh calls to some um

private apis at the ios sdk level so

now we're just gonna let it do its thing

and um we'll just wait until it's done

okay well the upload process seems to

actually a lot better this time and um

and i actually have to really confess to

the upload process for me took a very

very very long time i'm talking about

upwards of 30 minutes even though i'm on

download the upload speed um for my

internet connection this still took a

long time and this could either be a

temporary bug a glitch on apple on

apple's app store connect website or it

could just be something that well from

now on things are gonna take a long time

you never know what apple so

that's unfortunate but at the moment

it's gone through and i can see that um

you will get this message telling you

that your app was uploaded successfully

a push notification email that you'll

receive from apple that will look like

this after submitting your application

you will probably receive an email from

apple that looks kind of like this

and in here as you'll see it says we i i

want more issues with recent delivery of

your application my awesome notes your

delivery was successful but you

mentioned you may wish to correct the

following issues in your next lorry

missing push notification entitlements

troubling for some developers but this

is simply because we're at the moment

using firebase in our application on

able to handle push notifications so

that you can send a push notification

from firebase console to your

users however our application isn't

taking advantage of push notifications

you can just disregard this email and

don't try to even fix anything because

all this email is saying is that we've

analyzed your binary it looks like you

are accessing some push notification

apis however you forgot to enable push

notifications for applications so and

this is simply because when you bundle

your application and send it to apple as

which is something you probably didn't

actually look at but if you go to visual

studio code sorry if you go to xcode in

this archive browser right click on your

and here and say show in finder you'll

see this xcode archive file and say show

package contents and in here you'll

probably see some products and

applications run our app so this whole

thing is like your ipa file that apple

has received now in this runner

application there is information about

what kind of like libraries it has

included in itself and you can actually

right click on run or app and say show

package contents and in here you'll see

all the frameworks that your application

most probably one of the firebase

frameworks is internally using it has it

is using some apis related to push

notifications but that doesn't

necessarily mean that it is active and

so that's just an email that apple tells

you that hey you may have forgotten to

do something but you can just disregard

from this email and say no i didn't

forget anything because we don't have

push notifications in our application

so that seems to be fine and after that

email you'll probably also receive an

email that looks like this telling you

that hey your application with this sku

has now been submitted and has completed

processing and this this email literally

this application's finished processing

you're able to install it on your ios or

mac device and you can test it as you'll

we usually do in every chapter at the

end of every chapter we commit to what

we've done and we make sure that we

commit and tag those changes so

let me do some reshuffling on the screen

and let's go to and i'm going to close

xcode here like that go to our

application my notes to terminal and

a few things change so i'm going to go

get status in the main folder of our

application my notes because i was in

the ios folder so i just did cd dot dot

like this so now i'm in the main folder

grid status shows this and i'm just

going to say git add all right and let's

just have a look at our logs the last

commit was step 28 so let's just think

step 29 as a caption at the bottom

screen indicates and we just push our

after that is now let's just tag our

changes as well and say step 29

all right so that is now working as

what uh we usually at the end of it at

the end of every chapter is that we talk

about what we when we are going to

discuss in the following chapter and

what we need to do in the next chapter

is actually release our ios application

we've sent it now to apple and apple has

finally finished processing that and

build meaning that it's ready now to be

actually submitted to apple and that's

what we're going to do in the next

for release to the app store so i'll see

you there hello everyone and welcome to

chapter 48 of this flutter course in

previous chapters we've been working

creating an ipa file and sending it to

apple and in this chapter we're going to

make sure that we're releasing that ipa

file meaning that we're going to tell

apple that hey we're ready with this ipa

this file for us and the review process

for apple and and google are a little

bit different in that for instance with

apple sometimes uh there's an actual

user looking at your application and

sometimes if you for instance request a

um a fast review from apple they may not

even look at it and they may just say

okay it just works it's it doesn't crash

and then they it just goes through

um and for google it could also be a

completely different process but

we're right now in this chapter we're

going to focus on how ios app app

submission basically works okay

when you send an ipa file like we've

done to apple it will be available in a

place called test flight so let me bring

our web browser to the screen and let's

go and see if we can if you can actually

views as we had before so let's see app

store connect and i've restarted my

computer since last time so i may have

log in again and thank god i didn't

actually have to restart the whole

process and actually grab my security

it just allowed me to log in so let's go

to my awesome apps in app store connect

and then you'll see a tab up here called

and test flight as you'll see now our

build then is available in here

and it's ready to be tested basically

what we need to also do is to go in here

in the missing compliance and then tap

on this manage and it says does your app

and and it says export logs require that

products containing encryption must be

uh properly authorized so in here we

and it says export compliance does your

qualify for any of the exams provided in

the category make sure that your app

meets the criteria actually we could go

previous and just say no in here because

we're not directly using um

if you it is your responsibility to

comply with export regulation and you

should revisit this question if your

encryption exists i'll just say blah

now okay and then we say start internal

testing okay so now that compliance

so now that we've done that you'll see

that here in app store connect there is

a section called test flight and in here

for instance invite third-party testers

to test your application and you are

give access to your application to users

who you've invited to app store connect

so it is very very important to

understand the difference one is

internal testing and the other one is

like if you want to submit your

application to be tested by third

parties like someone who doesn't work

for your company for instance so in this

case we're just going to use internal

testing in this chapter but just know

is on ios and mac os an application that

you can actually download on those

and you can use test flight in order to

test your own ios applications or mac

you submit them to app store okay

so that's where test flight

now that we're talking all about all

these let's just also make sure that we

know we have a little bit of a security

um we haven't really talked about it so

much yet but i i built this um with uh

uh in swedish you say midfield and that

is like intentionally intentionally i

built this into this course so you'll

see how the resubmission process also

if if we bring our code let's let's

bring our mynotes code in here

um i believe was one of our services

no service is completely oh because that

let's have a look at the service and

crowd cloud storage cloud firebase cloud

storage it's called okay i'd forgotten

the name and we had this little all

so what this all field at the moment is

doing is saying that go get all the

all the notes in the notes collection

so that's doing that and then from all

the notes remember all the notes not

it's taking and creating a cloud note

and then it's filtering them out by who

you are that is a huge security problem

by doing this subscription and getting

this stream you're pretty much reading

everyone else's notes as well what we

want soon we're gonna fix that don't

worry about it what we want is to not

even allow any user to read someone

else's notes okay and then we're going

implementation of all notes and resubmit

i didn't want us to submit an app to

apple and then to google and then have

to resubmit it in both platforms because

as i said planned this so i just wanted

us to submit something only to one

platform and then draw it back and then

send it again but don't worry about this

yet i'm just giving you some preparation

what we need to do now first is to as

the caption at the bottom of the screen

in the case we need to install test

flight for both ios and you also have to

your mac on on the mac you can just go

to app store on your macintosh so app

store app and then search for test

search for test flight you can install

it with this install button i have it

installed already on my computer so i

don't see a install button in here i can

and after you've done that um for your

macintosh you'll also need to install it

i actually have my iphone my little

mirroring that iphone here on the screen

as you can see so what you can see on

the screen is actually my iphone right

and test flight is an application which

is available right here so this is the

test flight application on ios so at the

moment you can see that i don't have

access to my nodes application but we're

going to fix that soon or my awesome

so let's go ahead in here and have a

look at the next thing we need to talk

about and that's adding a user to to

test light so how do i get access to um

this build that we've submitted so that

i can test it with test flight well the

user that i've used for testing in here

gmail.com so what i'm going to do now is

to invite that user to test this build

so let's go to internal testing and

press the plus button and in here i'm

just going to say my users okay

and then press the create button

and in here you'll see a plus button

tester 0 and i'm just going to say plus

and in here i'm just going to use a

pixel to switch so i'm just going to say

okay and it says one tester has been

added to this group and that's pretty

much it so i don't have to do anything

so what i'm gonna do then is going to

wait for um an email to be sent by app

store connect to my user and it's just

been sent i'm gonna open it so you can

also see it how it looks like here's the

email that i just received so app store

connect is telling me that hey you've

now been invited to and test this

application and you can just go ahead

and do it so i'm just gonna tap on view

in test flight and this is just gonna

work because i already have um

basically a test light installed on my

macintosh so let me just tap on that and

i can see test flight open on a separate

screen i'll bring it to the screen here

and i can accept in basically installing

this application so as the bottom

as the bottom captioning indicates we've

already looked at the email

it looked like this and now we're going

to install this application which is a

but we're installing it on a macintosh

and that's just great so let's just

accept this and you can see now i can

either say install or done so i'm just

gonna say done so you see it so this is

our application here and i'm just gonna

press the install button and this is

just gonna go to app store connect and

grab that binary and bring it down

so and i can just press the open button

and if everything goes well this is our

flutter application running on this

but it is an ios app we didn't actually

compile this to be running on a

macintosh so everything is just working

as it should i can even log in here

and then in here it's a foo bar bass

and i can see my note so it's working as

expected so i'm just going to close the

what we need to do now is to submit this

build we've looked at it it seems to be

working fine so i'm just going to close

test flight here and close this email

let's then go to app store connect and

let's go to this app store section in

here and in this ios app section here

1.0 prepare for submission let's scroll

down to the place that says build and we

need to then say select a build before

you submit your app okay now

if you don't see this blue button in

here that's because you've probably just

submitted your bill to apple

apple usually takes up to 30 minutes or

sometimes even more to validate your

build so they may not have even appeared

in here especially if it's the first

sending to apple it may take a while for

them to process it so you may not see

this button simply because there is no

valid build yet but you can test you can

check the status of your builds by just

going to this test flight section and

just having a look at the version that

you've submitted and if there is if that

build is still processing it will just

say uh paranthesis processing and the

icon will just be a little bit grayed

out okay so don't worry it's not there's

nothing wrong you just have to wait a

so in here i'm just going to say select

a bill before you submit your app and

then say one that build that i'd

submitted all right so and then i'm just

gonna press the save button

build so age rating in app store connect

go to app information and fill in age

rating and i believe we've already done

this so if if you've not done that

before please go ahead and take care of

that but i explained this in one of the

previous chapters so you may have to go

and edit your age rating if you want to

but if you have followed the chapters

chronologically you should have done

we also need to take care of our app

privacy so we need to go to app privacy

as the caption at the bottom of the

screen indicates and here we have to get

as you can see in here if you have an

application that collects a lot of data

you i don't want to scare you but you

may kind of be in trouble because you

will have to inform apple about all

those things what you're collecting from

so let's let's in here let's say do you

or third party partners collect data

from this app then we should say yes in

here right because we are collecting

the user's for instance email address

password and notes so let's just say yes

in here's a data types that meet all of

the following criteria are optional to

disclosure the data is not used for

we're not using it for tracking the data

is not used for third party we're not

doing that collection of data occurs

only in infrequent cases okay so we

doing any of those tracking stuff that

let's go in here and say data collection

yeah we're collecting your email address

we're not collecting any financial

photos audio gameplay none of that

any other user generated contents yes

browsing history no search history no

screen name handle account id

diagnosis crash data we're not doing

and other data so yeah this seems fine

so for now we can just say identifier to

user id we also said other user content

because we're collecting the users

generated notes and we're also

collecting their email address so let's

okay and it says additional setup

required so let's go ahead and fix those

now in email address let's go set up

email address so i'm going to click

there and are we using it for third

developer advertising no analytics no

customizing what the user sees such as a

list of recommended products for no

app functionality yes that's what we're

and are the email addresses collected

from this app linked to the user's

link to the yes email address collector

link to the user's identity

are there i mean this is this is a

little bit of a legal question so i'm

answer this but i mean an email isn't

necessarily connected to someone's

identity as a person because i can just

go create like a private email and no

one knows about so i'm just gonna answer

doesn't seem like okay do you or

third-party partners use email addresses

for tracking purposes nope okay

the email address stuff is saved now

let's go to other user content which is

the user generated notes okay so

indicate how other user content

collected from this app is being used

um advertising no analytics no

customization no and app functionality

so let's then go and say is user content

collected from the sub link to the

they're used they're linked to the

user's email and since we said email is

not linked to the user's identity i'm

just gonna reason to say no in here

do you or third-party partners use other

user content for tracking purposes nope

okay so that part is done as well then

let's go to identifiers for user id so

i'm just going to click there

and remember user id in here is that uid

that firebase creates okay remember that

are the user ids collected from this app

linked to the user's identity

i would say yes it is quite obvious so

do you or third party partners use user

ids for tracking purposes nope

all right so saved and that's that now

you've gone through the privacy policy

display this to users when they try to

download your application this is very

important that you fill in to the best

of your knowledge and ability this is

not the place that you go and fake

anything and say try to hide the

information that you're collecting from

the users it is in the in your best

interest in your product's best interest

and in your company's best interest to

make sure that you fill these in as best

as you can okay usually in bigger

companies you'd want to probably um

consult with a lawyer or somebody who's

um good at making sure you're not

missing anything so in a big company you

usually don't do this on your own but

since we're now assuming that you're a

simple like a single entity even if

you're behind an organization like me

but you're a single entity and trying to

do this to the best of your ability okay

so now what we need to do is also fill

let's see here privacy policy so

what this is as you can see in here a

url that links to the privacy policy

privacy policy is required for all apps

and as you can see at the bottom of the

screen i've actually included a little

privacy policy for my own website and

i've included that let's see

let's see if i can do it on a separate

window so you don't have to be bothered

because i've actually included that um

you know what i will actually do it on a

separate screen so you don't have to be

i'll go to my hosting website and i'll

take care of that and then i'll bring it

to the screen so you can actually see it

let's see if i can go to my hosting in

well all my file files are residing

and i'll bring it in here so let's have

a look at this url that i provided at

the bottom of the screen you can see

pixel dsc privacy policy so i'm going to

dub dub up there and i have a look at

this text file which is right there

privacy policy so if i type pixelity

excuse me privacy policy you see that

there is a generic privacy policy that

and you will need to do the same thing

so you'll need to basically grab a

privacy policy from somewhere and look

at that privacy policy and make sure

that it works for you so what i did is i

and i'm not just going to go advertising

here but you can find free privacy

policy written by a very good and smart

people and you can have a look at those

adjust them to make sure that they make

sense for you and your company and for

instance in here i've just taken a

let's see if i can find it here

so i put my company name in there and i

just ensure that it makes sense for my

company and i've just basically put it

inside that url that you can see at the

bottom of the screen so i'm going to go

in here at privacy and app store connect

and say privacy policy edit and in the

privacy policy url i'm just going to say

dot se and then i'm just going to say

policy.txt but for you this should be

something else okay and i'm just going

to copy that open it and make sure that

it exists and then i'm going to press

so after we've done that we also need to

make sure that we've taken care of our

categories the categories to which our

application belongs so let's go to app

information at the bottom of the screen

indicates i'm going here in the category

and the primary category we're going to

say our app belongs to productivity and

then it belongs to utilities okay

here utilities all right then i'm gonna

okay then what we need to also do before

we submit our app for review is that

just remember this application is going

to be reviewed by an actual human so

this person is literally going to get

this information in the queue of their

work they're going to say oh an

application called my awesome notes

and then they're going to say okay

they're going to have some control panel

on their screen i don't know really how

it's formed on apple's site but they're

going to then download this application

on various devices automatically perhaps

and then they're gonna open the app and

then like how am i supposed to use this

it is in your best interest to ensure

that you provide all information

possible to that person so that they can

review your application so what you need

to do then is to go inside app

here prepare for submission in here app

review information and then under notes

what your how your application works and

how they need to register so in here

what we're going to say is um

steps to register now i'm gonna say um

open the register view and register

and password of your choosing

wait for a confirmation email

wait for a confirmation email from

to be to be sent to your email address

on the link to confirm your email

okay and then step three is go back

to the app and in the login screen

we've done that now so i'm gonna

actually then provide a valid phone

number in here and since i don't want to

really share my like phone number

everywhere on the internet i'm just

go on to a separate screen here and

write my valid phone number in here

but that's my phone number great and

go here and then i'm going to press save

and then bring the screen here perfect

so now i've saved that information

including my phone number and everything

should be ready at this point

so what you need to do then is to

go and grab some popcorn while you're

doing this hopefully and then you'll

just need to say submit for review

it says the items below need to be okay

we haven't really done the price pricing

and then it saw it says an admin must

provide information about the app's

privacy practices in app privacy section

it seems like we missed some stuff so

let's go to pricing and availability and

fix that this application is going to be

free so i'm just going to say it doesn't

cost anything and save that so that's

and let's go to app privacy and see if

we've actually missed anything doesn't

seem like it but what we've forgotten is

to actually press the publish button so

okay then we go back in here and then we

that's great so now your application is

submitted to app store and a reviewer

from the app store connecting is going

to have a look at your application so

confirm that it works according to the

information that you've provided and i

can see that i actually got an email

from apple that looks like this and it

says the status of your application has

changed to waiting for review so it's

um but before before we actually do all

whether apple has had the time to review

or they found some bugs in it and

whichever case we need to draw back this

build and i will show you how in the

upcoming chapters because we have the

security bug that i told you about so

for now we can just be happy that we've

gone through this chapter we've done

pat yourself on the back just great job

and we can get start to actually get

ready for the next chapter and i'll tell

you actually what we need to talk about

in the next chapter and that is this

problem that we had in the all notes and

we need to fix this before we can go

live with android as well so

now you know what's coming in the

i'll see you there hello everyone and

welcome to chapter 49 of this flutter

course in previous chapters we've

submitted our application to um

we also briefly talked about the fact

that we have a little bit of a security

problem in our firebase firestore

so let's have a look at what the actual

problem is so i explained this briefly

in the previous chapters but i'll do it

again in here so let's have a look

um so if this is our code i'm going to

increase the size so we'll see it better

and you'll see that when we are working

with displaying all the notes on the

screen for a user so for instance user a

has signed into the application

if you go there we'll see that we're

subscribing to all nodes in here in our

stream builder so we're saying we're

basically building our entire list view

which is here now it's list view and

we're building it on top of the data

that comes from this all nodes function

which is at the moment inside our

firebase cloud storage okay

however if you look at this code you'll

see that what it is doing is referring

or this node's local variable and which

is right here and this notes at the

pointing to the notes collection

and what it does it literally takes all

the notes from the notes collection so

this look this essentially means any

user logged into our application is

truly retrieving all the nodes in the

at the end of that code what we're doing

is saying we're okay after we retrieve

all the nodes from the database

then we're mapping them here to cloud

nodes so we can consume them locally

right at the end we're saying hey but

we're only interested in notes that are

even though the current login user is

not going to see all the notes in the

database but the current user is reading

all the notes in the database and if you

perform a man in the middle attack for

instance if you're using charles proxy

on a computer and then you're

using your phone and you're using for

instance let's say you have charles

proxy on your computer and then you're

sharing your wi-fi connection from an

ethernet connection through wi-fi with

an iphone that is running your

application if i don't sit in the middle

with charles proxy and look at all the

traffic that's going from your flutter

application to firebase then i can

actually see you requesting information

about all those notes and then those

notes coming back to the application so

a man in the middle attack could

potentially then expose all data in our

database or in the notes collection at

what we're going to do is by is to start

by removing our application from app

store connect if you remember in the

previous chapters we sent our

application to apple for review and what

i've done in here i've developer

rejected this application essentially so

let me have a look and see if i can

increase the size of the screen so we

submitted our application to app store

connect for review from the apple um

team review team but right before it

actually went to review i refreshed the

screen in here and you didn't see this

but i said remove this application from

review if you remove your own

application from review basically it

will become this it will go to the state

developer rejected so this is basically

informing you that hey it's not apple

basically rejecting your application it

is you yourself who's done this so

so i can show you an example how

confirmation email from apple will look

like so i'll open it in a separate

and it kind of looks like this i'll

bring it to this main screen so you see

so there we go so then i received an

email from apple that said that status

of your app has changed to developer

rejected app name blah blah okay so

this is the email that you'll receive so

i need you to basically reject your

the version one zero that you sent to

apple because we have security problems

with that application okay and again

i've mentioned this in the previous

chapters i did this in on purpose so

that we can understand like someone

because this is the kind of stuff that

you're going to go through as a software

developer sometimes you're going to

submit something to apple or google and

then you understand you made a mistake

so how do you how do you fix that and i

really wanted this to be a part of this

course so you understand how you reject

your application how you fix the problem

and how you resubmit the application

okay but i didn't want to do it for both

ios and android because it just gets

boring if you have to submit first go

through the entire submission from two

platforms and then to submit again so

that's why we first submitted for ios

and then we're gonna fix it and then

once that's fixed we're also gonna

so after rejecting your application you

also need to basically remove your build

from this at 1.0 so i i believe i've

already done that oh no i haven't so

it's actually good i haven't done that

so let's go ahead and here in 1.0 and

just remove this build okay so we say we

don't want to submit anything and then

all right um and also as you can see at

the bottom of the screen we're going to

update this 1.0 version now to 1.1 so

let's go and see if he can find that

i also saw that i got an email from

apple and here says okay now it's

prepared for submission meaning that

it's not developed or rejected anymore

and let's just bump this version in here

0.0 okay and then i'm going to save it

well and here i mean this is kind of

like a it depends on your taste if you

want to resubmit 1.0 you're more than

welcome to do that but it's usually

if you change something in your code

then it is usual for you to go and

minor version and it's called so because

this first version is the major version

so if there's a huge future in the

application and this is the

minor version and here is a patch i mean

you could argue that we could i

essentially maybe change our application

version to one zero one because this is

a patch but i just choose to do one one

so let's go ahead and i'm assuming that

you're doing the same thing because

there's some information i'm gonna

provide to you a little bit later in

this chapter that relies on you having

actually changed your app version to one

so that's that part is done what we need

to do now is to go as a caption in case

all the notes and users in our firestore

database so let's go ahead and see if we

my notes flutter project so that's in

firebase console and i'm going to go

first to authentication to users there's

just one user in here i'm just going to

delete that account okay then i'm going

to go to firestore database and there's

probably two notes in the notes

collection and i'm going to delete them

as well so delete documents there and

then delete this document as well okay

so we have a clean slate no users and no

so you may be wondering well if we have

security problems with our database

shouldn't firebase be intelligent enough

to know that and firebase is actually

intelligent enough to know that and

sometimes you will receive emails from i

mean depending on the security holes in

your database you will receive emails

from at firebase telling you that hey

there is something wrong with your

security rules and i've prepared some

email that that kind of indicates that i

just wanted to show you how that kind of

so you can see if you have security

issues with your fire firebase and

firestore database you may receive

something like this you see it says

we've detected the following issues with

your security rules any user can read

it kind of looks like this okay so just

know that if you receive an email like

that then you know at least the reason

and if you're wondering more about like

how you have to configure them although

i'm going to tell you how we're going to

configure our security rules in this

chapter but if you're wondering how to

do that on your own and you're curious

about reading more about it i've

prepared a little link here so let me

see if i can actually bring it

a link and it kind of looks like this so

you see firebase google.com docs first

and so you can read about this and i did

that and i got a lot of inspiration from

fix our security uh problem in our

firestore database so i strongly suggest

documentation you don't have to do it

right now but please just at least um

bookmark this page so you can come back

okay so now to the point let's go and

fix our security issue in our firestore

database okay so i've also prepared here

how we have to actually do it and you

can see the let me actually bring up our

security rules so go to firestore

database tab in your firebase console

and then go to rules okay let's have a

look at all roles at the moment and how

they're set up so the way it's set up at

the moment you can see it says match any

database and any documents okay and

that's what we're doing here as well and

it says match any document in there so

at the moment we're allowing read and

authenticated so okay so let's just for

now say we are allowing create

if you're authenticated so we say you

should be able to create a node as long

as you're authenticated so let's say

create and you can see we get some help

from firebase as well in here okay

so that's that so creation and then we

okay and this is the rules that we're

going to write in here you can see read

update actually read update and delete

so read updates and delete and the way

we have to set it up is of course as you

can see in here what i preferred is we

first need to make sure anyone tries to

read from our database or update the

database or delete the document should

let's go in here and say okay if

we'll bring that code up here okay

but we're also going to add some more

information to it and the information

should like look like this you can see

you may be like okay but how do i know

because okay before i actually say that

what we want is for the currently

to only be able to access his or her

documents that have the same user id

remember in our code we have this user

id field let me bring it up here

so if you go to our storage here we have

these constants and we have this user id

field so every node that we store in our

firestore database has a user id field

so what we want in here is to basically

grab the user id from the request so if

you say in here request you'll see we

have off path resource so let's go off

and then you'll see there's something

called a uid and that is the user id

okay so if we have a look how we have to

actually do that so we're saying user

request rtu id should be equal to

resource data user id and this resource

is the current resource that the user is

trying to access okay and if you read

the documentation that i provided to you

earlier you'll you would know this so

let's go in here and say okay the

request auth uid should be equal to

beta dot user id because that's the

field that we provided um as you saw in

the code here so let's then um

yeah i think this is good to go so we

could then publish these changes and it

says publish changes can take up to a

minute to propagate and that's

completely fine because we're actually

going to take some time in order to

our code as well okay so that's our

security rule so let's just make sure

that they look like this and i'm gonna

actually bring it to two lines so you

um if you need to get some um

inspiration from this you can also build

on top of this tomorrow so you can add

more security to this so you're more

start cleaning up our code on the dart

site so on the dart side so

let's have a look at this code that

we've written in here i'm going to

change the screen layout a little bit so

so let's go to this function gets notes

and you may have noticed it but gets

notes at the moment we're not using this

function at the moment so we're only

using all nodes so let's go ahead and

just remove this gets notes from

i'm running the application at the

moment so let's just command s and i can

see there's no problems because no one

is actually using get notes and there's

errors in our code you can see there's

no files or folders that are marked as

um so that's that one that was one of

the things that we have to do just to

and then what we need to do in here is

to ensure that our when we're actually

saying all notes that we are filtering

the snapshots before we actually read

them so let's just go in here and say

notes and before snapshots f like this

and you can see it says okay which field

are you looking for then we say owner

and that should actually be is equal to

so that's that one and then after that

we say snapshot and snapshots map

that's also fine actually so

in to be honest with you we could clean

this code up as well so let's just say

and we take this and we say this is our

the final notes is equal to that

and we could just return it

all right so now we have this and you

could basically argue saying that okay

we have a where clause in here so we

don't have to have this word clause in

here and i would actually say yeah that

does make sense because yeah why would

we have two word clauses so let's just

remove that word clause and put the

okay so we filter before we read all the

snapshots all right we're getting an

error in here let me see what the

problem could be because there's a map

so your code basically should look like

and what we can do now is to actually

put this to test to make sure

everything's working as expected so i'm

gonna bring our ios simulator in here

which the application is running on

already gonna do a hot restart and let's

just register a user so i'm just gonna

gmail.com foo barbeaus and please don't

use this uh password say register and

then it says verify email okay

and let me go ahead and bring up my

and have a look at my email and see if a

verification email has been sent to me

and we've sent an email verification

please open it to verify your account

and i hope i actually entered my email

correctly because i haven't yet received

so perhaps i could open up gmail in a

separate tab because i'm using gmail at

the moment for that particular user

and see if that email has appeared in my

and this is i'm doing this on a separate

screen so that's why you're not seeing

um i can't see really any email at the

moment so um let me go ahead in our

firebase console in here so

and let's go then to authentication and

i can see that there is a user here and

that is actually correct but i don't see

any verification email being sent to me

so let's go ahead and have a look at our

and let's have a look at the button

implementation if we actually forgot to

do something so when we pass this

register event you can see auth event

register then we have to go to our off

and have a look at how we've implemented

implemented that i can see that we say

create user and then we're awaiting on

the provider send email verification so

it seems to be working fine however i

still haven't received any verification

email and that's why i'm just going to

say send email verification here on this

and by pressing that i'm just going to

refresh my emails and now i can see i

received a verification email i'm going

to bring it here tap on the link and i

can see that i saw this um i can see

your email has been verified was

that's great let's go ahead now and um

go to the application and i'm going to

restart here go to the login page and

i'm going to log in with that user

log in with the user and no problems i

can log into the application press the

plus button and i'm going to say my

that's saved and then i'm going to save

all right and that is also saved then

and try to log back in with another user

so let's register a new user because

remember we deleted all our users from

firestore database so who are about

again please don't use this password

and i'm going to have a look at my

verification email was sent to me so

that's perfect i'm going to bring it

if i can open that email it looks like

this i'm going to verify my user great

then i'm going to restart the process

and try to log in with that user

log in with the user and i can't see van

notes so i'm going to say another first

create a new note say another second

note all right so after these two users

have created their own two individual

notes let's go ahead in our database

refresh the users we can see there are

two users in here one starting with pg

which is this pixelity and then there's

a 9v which is the other user okay

let's go to our database and see how

many nodes we have and we can see we

9v which is for default.user and then we

the pixelity email which start with the

user id of pg as you can see in here and

they they have full access to their own

documents so now this user you can

actually go and delete this document for

instance another first note so he can go

and say okay i want to delete this note

and you can see it just immediately got

deleted from firebase as well so

they have full access to their own notes

but they have absolutely no access to

anybody else's notes alright so that's

if that's even a word fantastically

so the next thing we need to do now that

we fix this is to go ahead and update

the build number in our pop spec yaml

file so now i'll show you this let's go

to visual studio code to our code right

camel and you'll see on top of this file

somewhere around here we have this

version at the moment is one zero zero

plus one but what we want to do in here

is just is to say it's one one zero plus

one so we're updating our build number

so after doing that since it's such a

big change you could perhaps look at

your terminal and see and do a git

status and you can see by updating that

it didn't immediately update the build

number for our application because had

it done that it should have also been

updated for our ios application in the

info plist file so that unfortunately

wasn't updated and because of this it's

probably a good idea to issue flutter

clean so i'm going to bring the

code like that let's just say flutter

all right that's doing is we're going to

say git status let's have a look at our

status and there's still nothing changed

so let's just say flutter run ios

and see if that's gonna listen okay

flutter run because that's our default

target at the moment is an ios simulator

so maybe flutter rom will just accept

show us the list of devices please

it's having oh now it found it please

choose one okay i want to choose the

iphone 13 pro so i'm gonna choose um

iphone 13 pro number two in here okay

so now it's gonna build the project with

xcode build and in my experience these

i'm basically gonna stay quiet now let

it do its work and when it's done we

will continue with the video

all right as i suspected this process

actually took a very long time and i

think we could actually see in here that

it is well i'm not going to go into that

it's a long time um so let's have a look

now if the version was actually updated

correctly so i'm going to go another

into another shell in here and let's say

git status and i still don't see any

info plist files have been getting

changed on the ios side so i'm just

gonna be curious here and then go to the

ios file in here and have a look at the

and let's have a look at the version in

here well the version does seem to have

been updated so it's 1 1 0 that's

exactly what we specified in our pop

spec yaml so that's you making sure that

this file is updated and if you don't

have xcode so if you're for instance

ubuntu or something and you want to

still check whether the version number

was updated for the ios application you

can always do that by opening up this

file info plist inside ios runner

and then you can have i believe you

your flutter build number in here and

let's see if flutter build number is set

i don't actually see the flutter build

so if we search for one one zero

actually let's search for one one zero

in the entire application and the only

thing i can see in here are like some of

unfortunately that's not gonna work so

i don't really know the magic behind how

the flutter team has actually injected

it's probably some sort of a build

variable so if you want to get into

details about that perhaps we could just

and have a look at that application

let's go in here into build settings and

um and see if there's any one one zero

in here flutter build name exactly so

that's that's how they're injecting it

they have a user defined variable called

slots are built and flutter build the

name is then being injected for our info

if you go here you can see oh this is

flutter build number so yeah but anyway

it's this this must be a variable that

the flutter team has injected into the

xcode build somehow all right

but bringing up xcode could confirm that

the version number is set to 110

correctly so that's all we needed to do

then the next step for this chapter for

make a build and send it to apple this

not this time we did it the previous

time as well we sent it to apple so what

i'm going to do is i need to bring up

xcode again i shouldn't have closed it

maybe let's go in here and while we're

in there we could just go and say we're

building for any ios device and then i'm

just going to say product archive as

we've done in the previous chapters as

okay now our build has been um created

by xcode and in here it's very important

that you actually check that the version

corresponds to the version number that

you've created in app store connect and

just a reminder in app store connect if

you go back there you can see that the

version that we prepared is 110 and

that's why i said in the beginning of

this chapter it's actually important for

you to follow the same versioning that

i'm doing in in the current chapter so

let's say 110 and i'm going to say

distribute to apple or distribute app

analyzing app version fetching app store

and i'm going to uncheck manage version

and build number because i want flutter

to be able to do that and then i'm going

to choose the production profile that

we've created for application press the

and then depending on your network

connection and your and different

configurations that you have for your

network this process could actually take

previously when i tried this even even

though i'm on a fiber optic net network

with a thousand upload a thousand

download it still took about 30 minutes

for a simple application to be sent to

apple and it was literally stuck in this

requesting app information for more than

that's an unfortunate fact that we just

have to accept and let it do its work

i will see you then once it's

finally sent the application to apple

all right so now i can see that our

application has been submitted to apple

and i have to confess that this time it

took only about a minute for this

process to go through so that was very

fast much much faster than the previous

chapters we'd have to submit our

application which took upwards of 30

so now that it's done after you've done

this you will receive an email from

apple that kind of looks like this if i

it will look like this and it will tell

the following build has completed

processing only after this email has

been sent you can go to app store

go and we also have to fix our missing

compliance so let's just say manage and

start internal testing after you've done

that you need to go to the app store

and in that tab let's just select a new

bill and it's our 110 build and i'm

going to say done in there okay after

you've done that you can press the save

button and then you can submit your

then in turn concludes the submission of

our app to app store and um if there's

any complications with this application

like if apple for some reason can't

register a user or something they're

going to send you an email telling you

then you need to go through that process

review team in order to get started with

your application but if you remember

from the previous chapters we've

actually left some information in there

and told the review team how to register

user in our application so that

information should be sufficient for

them to understand how to use the app

fantastic we're done with the origin

with the submission of our ios app to

app store so as usual since we've now

changed our code let's go into

i'm going to close all these tabs

because it's just extremely populated on

get rid of the explorer and go to

my terminal in here and have a look at

art status and i can see there's only

two files changed so i'm going to add

them and let's commit as step 30 as you

can see at the bottom of the screen okay

so if you look at our logs we have step

29 and then we have step 30 so i'm going

that's going to push our commit

and less than a tag v so step 30 and

let's just say get push tags so

that is done now and our tag of 30 is

what we need to do now as usual is

tradition where we talk about what we

need to discuss in the upcoming chapters

and in the next chapter we're going to

talk about sending our app also to

google play store we've done it for ios

we have to do the same process for

google play store so get some

refreshments if you want to and i'll see

you in the next chapter hello everyone

and welcome to chapter 50 of the slotted

course in previous chapters we've been

working quite a lot with submitting our

application for the ios app store using

app store connect and in this chapter

we're going to focus on doing the same

google and play store so whereas you

have app store and at the back of app

um app store connect which allows you as

a developer to go and interact with the

your product that's going to be

submitted to the app store google has

something similar for your product for

your android app in this case our

flutter application to be available in

which is where users download your

applications you you as a developer will

have to go to the google play console so

we're going to take care of that and for

that we're going to create something

called an app bundle where whereas if

you remember when we created our ios

application we went to xcode and archive

our application and that created

something called an xc archive file and

that was kind of like a zip file

and all your files were all your

binaries at least all your like linked

libraries all your pods the application

itself binary was signed with your

production certificate and profile an

your um android devices as well is a

signed bundle so it is the equivalent of

your um xc archive kind of and we're

going to take care of that as well soon

i mean there's something that i i

actually prefer this but i didn't want

to mention it before because we were so

close to actually raising our ios

application we have to make just some

small adjustments to our code as well as

start for instance working with

taking screenshots of our android of our

flutter app running on various android

devices and that's um a scrolling issue

that we have generally on our

screens where we display the keyboard

login view and i believe there's

and where else do we display a keyword i

log in register for a got password view

because we asked the user for

her email address there as well and also

actually we don't have the problem on

the edit notes view so that's not a

we have this problem in verify email

view login view register view and forgot

actually verify email view you could

argue that yeah it's it's not a problem

so the issue that we have at the moment

is that imagine that your application

application is being run on a very small

and then the user for instance has a

very very small screen and then they're

on the login view and then we displayed

the keyboard where at where for instance

they tap on the email field and they try

to write their email and then the

keyboard pops up blocking like half the

screen and depending on the size of the

screen the rest of the half that is

remaining might not actually be able to

display the entire contents of your

this is a little problem and we have to

fix it but it is so simple to fix and

you may then decide to say well the ios

application we've done already is sent

to apple it's um it's already accepted

and i'm going to release it and you

could definitely do that so it's

actually good practice if you want to

release your is application as is just

go ahead and do that and then you can do

a patch later and release another

application to fix that issue

and i think the more you release

applications the better because then you

learn the process of updating things and

sending release notes etc it's just good

often so let's go ahead now and talk a

little bit about the documentation for

creating an app bundle so i'll bring it

and it's as you can see at the bottom of

the screen it's in distribute console

there's a lot of documentation here that

you can go and read more about it so i

thought just to um explain like the

google play console in here a little bit

to you so that you can sign in here

and then you can read more about all

these topics so i think it's just a good

bookmark if you want to be able to

release your application in the future

as well with google and play store

otherwise if you're like me and you

sometimes just want to jump into things

um logging into google play console so

let me bring you to the next url as you

can see the url is played at google.com

console about so i'm just gonna say um

play.google.com slash console slash

and that's our google play console okay

and i'm just going to log in here with

a user account and i have this user

account here which i can log in with

let's see if i can log in successfully

all right and then it says choose

developer again and if you haven't done

this before you may have to go and

create a developer account first but i

in the beginning of this chapter we

talked quite a lot about creating a

developer account both for ios and

android so i'm assuming you've already

done that but if you haven't you can go

and create a developer account it is

free you don't have to pay for anything

so just go ahead and create your

so now here i'm going to choose my

developer account and just go in here

play console as you can see in here this

is the console url for me at least and

what we need to do in here is to go

let's go ahead as you can see at the

bottom of the screen let's go ahead and

tap on create app in here and now in

here it's asking us for some information

um and also i just saw that i have a

action so i'll bring the right caption

up in here and you'll see that we have

to go through these steps in order to

create our application all right so i'm

gonna go in here and let's just say my

the default language let's just leave it

as english us and and it asks you is it

an app or a game then we're gonna say

it's an application and it's a free

and and and we're going to say it it

meets the developer policies and accept

us export laws okay and then we create

the application this may take some

what we need to do now is to go through

app access in here so i'm going to bring

so we need to go through let's see if

you can actually find the provided

information about your app and as you

can see it's right here provide

information about your app and set up

your store listening okay so i'm gonna

have a look at that and these are the

things you have to go through and we're

actually gonna go through this together

to in order to be able to create a

listing for your application so it's a

good check checklist basically um and

i have to say i mean i'm more used to

the app store connect interface it's a

little bit like less cluttered i find

google play console a little bit more

cluttered to be honest with you and

there are so much in your face but once

you get used to it i think you'll

understand the purpose and

and then you'll just as as long as you

know where to find things so in the

dashboard and for your application just

scroll down to set up your app provide

information here about your app instead

of your store listing and let's go to

app access and set that up okay

and then here is asking us okay is there

any restricted content that we're going

all functionalities available without

special access press the save button

and you can see for instance i saved it

and now i have to manually go back to

the dashboard it could have just saved

it and sent me back but no it doesn't do

that so app access is now crossed out as

let's go to the ad section so for the

ads we're gonna say no my app does not

contain ads okay press the save button

and let's go ahead and take care of

content rating and this is kind of like

what we have to do for app store connect

as well in order to for instance say our

application doesn't contain violence it

mature content etc so let's go to

content rating and say start

and let's just fill in our email address

provide if i can spell support

i have some problems right now

ab.sc and i believe yeah that's my

so i think that's that's the email i've

been using in app store connect as well

just double check that in my notes so

i'm gonna bring this into a separate

website just i'm gonna check this in my

it is actually so i'm not using this

anymore so let's just pick some of the

appointments and here you just have to

enter your own email so don't enter my

email here so this is in case they need

as you can see if in case they need to

contact you so the category of our

application we say all other app types

because it's not a game or social or a

communication application so next

does the app contain any rating

ratings relevant content downloaded as

and user accountant does the app

natively allow users to interact or

exchange content with other users

through the voice communication text no

online content does the app feature

promote content that isn't part of the

initial app download but can be accessed

promotion or sale of age restricted

products no miscellaneous does the app

share the user's current and precise

um does the app allow users to purchase

purchase digital goods no is the app a

web browser or search engine

is he a primarily a news or educational

product no okay so we save this

and we go to the next page summary and

you can see it says rating of 30 in

everyone can use this application rate

not sure to be honest with you with that

seems like it and then we can we can

okay and then let's go and take out our

and we say in here we choose 13

to 15 16 to 17 18 and over can also use

our application okay and this is kind of

like something you may decide on your

own whether like you you must add a

privacy policy target audience inclusion

or under 13 and that's why we're not

like targeting anybody under 13. and to

basically you may say oh my app's only

suitable for 18 and plus and that's

that's that's completely up to you and

you're more than welcome to do that but

i think our app is suitable even for 13

or even maybe less a 13 is quite a

basically like the sweet spot i would

say yeah because if you go lower than

that then you'll have to provide like

your privacy policy for those specific

and then we're gonna press the next

button and let's have a look in here

what's asking us to do appeal to

children could your store listing

appear to children and we say yes

um we may not want this app to be

appearing for children but it may appear

nonetheless so let's just say yes there

and in here you can see the target group

is 13 to 18. so that's great now we

saved it and let's go back to our

dashboard and you can see here a target

so let's go to the new section in here

news app is our app and news app and we

all right and then we save and go back

and you can see that the news app stuff

so let's now have a look at this covet

19 contact application and we say um

my app is not a publicly available code

with 19 contact tracing or status app so

save it and we say go back to dashboard

so that part of the application process

now we have to fill in the data safety

stuff so let's go through all of these

and this might take some time but that's

okay does your app collector share any

of the required user data types required

does your app collect or share any of

user data types what do they mean

personal information yeah we will

collect email addresses so yes of course

let's remove that is all of the user

data collected about your app encrypted

in transit yes and that's because we're

using firebase and that's using https so

that's encrypt in transit do you provide

a way for users to request that their

data is deleted no we don't do that and

i actually believe that it will be

so if you are curious about this and if

you want to allow the user for instance

to be able to do that you could you

could check that out and see how you can

their data to be deleted you can create

a separate view for that for instance

and from there you can you can basically

make an api call to firebase and delete

this user so you could do that if you

want to okay and i may actually provide

for that i don't know but at the moment

data types okay and let's have a look in

a quite a long time so let's have a look

data types you must select any user data

that's are collected okay we're not

personal information and we're

personal identifier that relates to an

identifiable person for example an

account id account number or account

name yeah personal identifiers yeah

and other personal info we're not

collecting so we only have a user id and

an email address and that's it

and we're not even asking for their

let's see what messages uh entails in

where do you go here messages

photos and videos audio files files and

a user's files or documents or any

information about a user's files or

documents for example file names yes

because we're storing actually their

files their notes so app activity no

contacts calendar no web browsing no

app info and performance no device or

other identifiers no so let's just then

not started so let's have a look at

process in here and we say select all

that apply is this data collected shared

or both it's only collected okay

and data collected in this way must

still be disclosed but will not be shown

to users on your store listing

ephemerally process family means that

the data is only stored in memory and is

retained for no longer than necessary so

no it is it is not stored only in the

and we say is this data required for

your application and in this case i

believe that we're talking about email

address and yes this data is required so

i'm just going to say yes it's required

why is the user data collected it's for

use for the setup and management of user

accounts actually yeah account

management so let's just say account

and then press the save button so now

we've submitted the email address and

while we're why we're using that so

let's go to personal identifiers now and

start that process so we say we are only

and because it's a user id and we're not

processing it ephemerally i think that's

and we say the data collection is

required and we say um it is used for

app functionality okay because we're

using the user identifier remember when

we store their notes so it's more for

app functionality than it is for

so that's why we do that and that is

completed now so let's go to files and

docs and have a look at this process

it is only collected but it is not

shared remember we are not sharing the

user's data even though we added that

sharing sheet for the user to share

their own information with someone else

but then that is their choice it is not

something that we are doing okay

is it then is this data processed

ephemerally then we say no and again i

don't know if that's the correct

and then is this data required for your

app and remember we're talking about

files and docs users can choose

whether this data is collected okay

because it is not something that we

collected then we say it is for

should i recommend it no account

management no so it is app functionality

we would say and we save it and that's

it so after you've done that we can just

go to the next screen and have a look at

this how it looks like you can actually

read about all the information that you

um and in here you can see at the bottom

of the screen says provide a link to

your privacy policy and and i have

already a privacy policy so i've um i

believe i have it in privacy policy text

so i'm gonna copy that and go to

privacy policy in here actually leave

so we may have to actually provide that

privacy policy i haven't yet done that

but we will have to do that

on the privacy policy page so yes we

need to we need to actually do that so

i actually don't want let's save this as

and then enter the privacy policy in

here and i'm just going to say https

let's just make sure it's https yes and

save that okay then i'm going to go back

to the dashboard in here where we were

for data safety we were at the end of

this so let's go to uh next um

next next next at the bottom of this now

we have our privacy policy so now we can

save this and let's see if there's

anything that we have to do in order to

it doesn't seem like it so it is

saved successfully so if we go back to

the dashboard and then have a look at

our data safety now we should be able to

see that it is crossed out so

so um data safety is done and now we

have to have a look at this app category

and provide contact details okay

so let's go in here to app category and

we say it is an app and it's category

let's just say utilities if they're if

communication education events food

house library blah blah medical news

personalization productivity perhaps

okay and then tags let's just say

notebook yeah let's just keep that okay

and you can choose more tags if you want

let's see store listing contact details

and email address i'm just going to say

pixelity.se phone number and i'm going

to enter some phone number in here

okay just a fake phone number for now

you may choose to advertise your

application outside of google play if

you want to and that's okay perhaps and

um before i save this i'm going to bring

the screen to another screen and

actually enter my real phone number okay

so i'm going to do that here let's see

it doesn't really seem to like the fact

that i dragged it to another screen now

it really doesn't like that i'm dragging

it to my ipad so i'm gonna bring it to

yes and so all i'm doing here is just to

enter that information so let me bring

and then let's see if you can press the

save button okay so all i did is just

move the screen to another

physical screen enter my real phone

stay safe your changes couldn't be saved

why not let me go and see if i

enter a valid oh i entered my phone

number incorrectly so i'm just gonna

and scroll to the top of the screen

and then let's go to all apps okay

oops i want to go back to my app here

so in here we're done with the select

app category so that's fantastic

now it's the juicy part we have to set

this is also actually going to be quite

a an important part of the setup process

so this may actually take some time but

that's okay and we're gonna take care of

that in due time so now we have to look

at setting up our store listening and

the store listening um is one of the

absolute core components or and the core

things we have to do in order to be able

to release our applications so let's go

to set up your store listing in here and

let's put a short description and say

okay and a full description with this

and you can store your notes in the

cloud okay so and also i strongly

suggest that you write some proper

description for these things and it is

also very important if you remember that

we used an icon for our application and

brought it from stock io so if you go in

here stock io and we use the sticky note

icon so it is important that in your

store description in both ios and

um app icon provided by and just give

some attribution to that okay so it's

very very important that you read these

things and also give attributions where

so now we come to the application icon

section and you can see in here that

says the application icon should be five

twelve by five twelve and we don't have

that unfortunately at the moment what we

have is a thousand twenty four by

thousand twenty four so if we go back to

our downloads for instance in here

you'll see that we downloaded our app

icons in one of the earlier chapters and

we have this app store image in here

which i believe is thousand twenty four

thousand twenty four at the moment so

what i'm gonna do is i'm gonna duplicate

this file command d on my macintosh on

windows and linux you may have to do

something else and if you have for

plus plus it's called paint.net or

something on windows you can also resize

your image but all you need to do is

just in your host operating system you

need to make sure that this image is

512512 so on the mac i'm just going to

it open on a separate screen and then

i'm going to go to tools and say adjust

size and i'm just going to say it is 5

these are the guidelines so in here i'm

just going to drop that file right there

okay so that's for your application icon

now we also need a it's a required feel

as you can see it is marked with an

asterisk in here and it's a future

graphing and future graphic is something

that a google play store can sometimes

use in for instance if your application

is featured on play store um

and they are going to use this image in

do an advertisement for applications so

guidelines for this and it should be you

can see it should be 1024x500

and since we don't have that we are

going to use our application icon in

order to create that future image so

what i think we should do is just to

and after our figma document is open

what we can do in here is to go and

create a little rectangle which was

1024x500 i believe the guidelines were

telling us to create it by so 1024 by

500 so i'm going to select this

rectangle and i say its width is 1024 by

and then height is 500 and what i like

to do is to go my trusty color palette

let's go to tokyo knight in here in

github as we've seen in previous

chapters i'm going to go scroll down a

little bit here and say that i have i

want the editor background color so it's

2428 3b and then i'm going to copy that

close the tab come here to figma and

change the fill color of this layer to

that so we're going to use this as our

background and what i'm going to do is

i'm going to go to our downloads folder

1024024 which we've downloaded in one of

the previous chapters so i'm gonna bring

then it is huge i'm gonna hold down the

shift key and then resize this

proportionally so kind of reset it to

something like this okay so i'm gonna

place it in the middle now i'm gonna

change the name of this to bg change the

name of this to icon by double clicking

on it and then i'm gonna create a text

field in here and save my awesome

bring these into three separate lines

like that and let's also make sure that

the fill color of this is white also

ensure as you can see like mine

it is right aligned then i'm gonna place

it somewhere here okay in the middle as

well and perhaps we could even increase

the size of the font so let's see what

we have here we have about 200 let's say

120 and it is a little bit bigger a

little bit bolder in your face kind of

stuff so and this is our text so this is

our text what i'm going to do in here

basically take these like bg icon and

text and then duplicate this bg in here

because this is going to be our mask i'm

going to grab grab it and bring it at

the bottom then i'm going to right click

it and say use as mask and now it has

its own group then i'm going to grab all

of these three layers and then drag them

here and now you can see that that mask

is basically masking off this entire

content so it's masking off our icon as

well so it looks pretty good to me it's

kind of proportional it's nice so then

and then in figma go to the bottom so if

um in here so you can see better perhaps

then scroll so make sure your mask group

is selected then go to export and then

we're gonna export it as one x and then

that is exported now so now we have our

image looking like this and it is

our play console google play console and

right where we have to uh throw this

feature graphic i'm going to go to

downloads and the image that we just

downloaded which is right here i'm gonna

so then that is working fine as well and

save my changes and something is wrong

with our changes some languages have

that's probably because we haven't

really uploaded any screenshots yet and

we're gonna take care of that soon so it

strange that it doesn't let me just let

me save my changes as a draft i have to

save this entire screen and since i

haven't entered some of the information

in the screen which is required it's not

allowing me to actually save it so but

we're gonna take care of that soon so um

what we need to do in here is to ensure

that we're first running our latest

application on the correct phone as well

let's see in here i'm going to bring our

source code in here and then i'm going

to say select the device and then i'm

going to choose my android phone all

that's that then i'm going to actually

grab my android phone let's see if i can

do it without causing too much problem

here on the screen like that

make sure it is connected to wi-fi as

my android phone is now set up

and let's then go ahead in our source

in our source code then i'm going to go

to main dark file if i can spell

dart file and in here in our terminal

i have two terminals so one i usually

scr cpy so i'm just going to say scr cpy

and that's going to bring up the android

phone up right there and since we've

selected that we can now just say run

without debugging so the goal in here is

to run the application on this

and have sdrcpy take screenshots for us

as you'll soon see so there's a really

good command called adb and adb is like

the low level and low level android

and by using adb you can actually

you know for instance your emulators

android emulators and your android

if you don't have adb you will actually

have to install it so if i say which adb

on my computer you can see that it says

it's homebrew bin adb basically telling

you that i've installed adb using

if you haven't a if you don't have adb

on your computer you may need to install

it if if what you're also doing is

following along with the steps that i'm

providing you meaning that you're taking

trying to take a screenshot with

from an actual device that is connected

to your computer okay so i can see now

that our application is running in scr

cpy looking like this so what we could

do is to issue the command as you saw so

exec out screen cap key and then we save

it into for instance file1.png

and if i have a look in visual studio

code you'll soon see now there is a file

stored here file1png and that is that

file with the screenshot of our

and then we can go to another screen for

instance the i forgot my password screen

and we could also send our keyboard down

kind of look like this and then we can

file to png so that's stored as well

let's go to the registration screen and

send the keyboard down and then let's

say file three png and also sending the

keyboard down or up or leaving it up it

is it is a it is a taste thing it is

completely up to you how you want to do

it okay so in here i'm going to go here

and actually log in with a real user

and go to the main screen of the

application i'm gonna take file for png

and then i'm going to go to one of my

notes in here with the keyboard up

perhaps in this case and then say file

and then i'm gonna say open so i'll see

all my png files in here then i'm going

to take those files and bring them to

desktop so they're not polluting the

workspace here in visual studio code

let's go back in here and you can see

that you can just drop drop

two phone or tablet screenshots in there

let's go ahead to my desktop folder

where i stored all those screenshots and

just drop all those images in here okay

and i can see them populated here i'm

gonna grab the login screen and see if

it can actually bring it first and

unfortunately here it's not allowing me

to drop things at the right order so

unfortunately i have to delete them and

like drop them at the right order so

and then i have to upload file too so it

is a little bit um strange that it

but perhaps there is a functionality for

that that i don't know about

so let's then say file four

and then we have to upload file five as

so that's that then what we need to take

care of now is to create a five inch

tablet and since i don't have a five

inch tablet here sitting around as a

physical device then we have to go and

create one so if we look at um here

visual studio code and go to flutter

select device you'll see that there are

tablets that i've created with

android studio so if you have android

studio you can always open it and

oh it did open it anyway so it's right

here you can always go i believe into um

avd manager which is the virtual device

manager and then create your virtual

device as you can see you need to create

a file is this seven inch and a 10.1

inch tablet because we're going to take

screenshots with these so what i'm going

to do actually is to launch both of

these tablets so that they're ready to

go when we need them so that's the first

tablet and i'm actually going to

turn it around so it is in the portrait

mode so that's that one and then i'm

avd manager here to run a second tablet

in here and that was extremely fast i

saw i don't even know how it did that

how could it run this tablet so fast a

little bit scary to be honest so

now that's sitting there um

let's see if it's gonna do its work

correctly though i can see the seven

inch tablet is not doing so well let's

see if i can close it and i'm gonna say

yes close so perhaps i should have i'm

and don't know if we're going to

actually be better off first running the

7-inch tablet and see if that is

maybe something happened in the

processing of the 10 inch as well as the

and i can see that this device isn't

really doing so well so i press the

power button on it here and i can see

now it is running so i'm going to press

and um orientation isn't really working

now maybe it's working a little bit

better so let's just leave it at that so

that's the seven inch display and it is

up and running then what i'm going to do

and the flutter daemon has terminated

that's completely fine reload it

then what we're going to do is to say

flutter select the vibe and that's

probably because the flutter demon

actually crashed on us here so i'm gonna

try one more time and if it doesn't work

then i'm going to quit visual studio

let me start visual studio code and

okay now that visual studio started

fresh let's just try again and say

flutter select device and this time i'm

android tablet then i'm going to say run

without debugging so let's see if we're

going to have any success running this

application in this tablet

is working well for us today then it's

going to allow us to do lse performing

stream install failed to install

launching application and sdk g phone 64

rm64 so there could be some problem with

this android tablet in here so i'm going

and i'm going to go back to android

studio if i can't find it somewhere here

and let's go in here then i'm going to

and let's have a look if we can close

these and kill these two tablets

completely like that like that

and while i'm at it i'm also going to

kill this one so i don't have any use

for that so i'm going to create a new

virtual device then i'm going to say

excuse me a tablet that is nexus 7 and 7

that is fine and it's thousand 200 by

nineteen twenty so what is required here

seven inch tablet screenshots okay

that's fantastic so it doesn't have

specific size requirements and then i'm

that is fine as well on portrait and

then let's see if he can run this

and if everything goes fine we're going

to see the welcome screen here i can see

google's logo so that's a great sign

always and i'm going to keep the screen

and while that is doing its work we're

flutter and i can see the emulator is up

now and i'm going to say select device

and i'm going to choose it here let's

then say run run without debugging and

see hopefully this time we have better

luck in running that application in the

given emulator so let's see

wow that went really fast actually it

went surprisingly fast so now it's

running in there and i can see our

application running in the emulator so

what we need to do in here is to

actually take some screenshots so um

when we need all you see here actually

we all have to provide 7-inch tablet

screenshots and we also have to fix the

10-inch tablet screenshot but what i

depending on the size of the screen at

the moment you can see everything is

working fine there's not a problem you

can go to register screen i also forgot

my password and all of these are working

we have a scrolling problem

and i can see in here that the seven

inch display i've mentioned at the

bottom of the screen that the seven inch

display could actually block the view

and that could be for instance because

um now in in this case is not actually

blocking the view but if you had a

smaller screen it could block the view

in that this screen as you can see is

not scrollable so if you had a smaller

screen then this keyboard could pop on

top of the content that you have in here

blocking the content so what we need to

do before we start taking some

screenshots from our android um tablet

let's go and fix these things up

let's first go to our verify email view

in our application oops i press the

launch button again by mistake sorry

about that i'm going to stop this

let's go to and verify email view and

you'll see in the code that the verify

email view state at the moment's return

is scaffold and it has a column in order

for this column to be vertically

scrollable all you have to do is just

wrap it with a widget and just say

world view as the notes indicate at the

bottom of the screen okay so that's the

scrolling down for that let's now go to

the login view so login view and wrap

the entire content in here in this

column and let's say wrap it with

a widget okay and i'm going to say

scroll view just like that okay

and i changed the screen layout a little

bit so you see the code better let's

then go to our register view as well so

register view and on top of the screen

we have the scaffold and a column so

let's also in this column say wrap it

with a widget of single child scroll

view alright and last but not least

we're gonna go to our forgot password

view and have a look at how we're

creating the screen we have a scaffold

padding column just like a standard

we've done in other places as well wrap

with widget in a single child

scroll view all right so that's that now

that we've done that we're actually

ready to launch this application again

so select device to nexus and then i'm

going to say run without debugging all

right so what we need to do now is to

use adb again the low level debugger for

android but this time we want to take

screenshots of an emulator as you saw in

section when we talked about taking

screenshots of an actual android phone

running in scr cpy we had to use adb as

well but we didn't have to tell it that

it is an emulator as you can see at the

bottom of the screen now if you specify

an e flag to adb then that indicates the

adb that you want to take a screenshot

here's that device running

and what we need to do now is to go to

command line and let me just do some

scrcpy and i'm gonna just do some screen

shuffling here so get rid of this

let's issue the command as you can see

at the bottom of the screen so

adb exit out but before that i'm just

gonna say dash e and screen cap

and if i now go to the project structure

i can see there is a file called file

one png and it is a screenshot from our

emulator okay so i'm gonna re

do the same thing i'm gonna go to forgot

my password screen and um let's get up

and get rid of the keyboard in here and

let's remove that space that i just

entered and then take the second

and then let's go to the login page and

the register page get rid of this

file free png okay so now that we have

i press the back button i'm going to

log into our application with my email

horrible password of foo barb ads now

we're in the application let's take a

fourth screenshot called file for png

and in here while this is up with the

and then take screen shot 5 or file 5

png so now we have 5 screenshots from

our 7 inch display as well

excuse me let's go and collect those

screenshots file one two five and then

i'm gonna delete the ones on desktop and

just cut and paste the ones from

our application then let's go to

our google play console in here in the

seven inch display i'm gonna drop these

and then let's drop file two right after

that and then we can say file three four

so i uh so that you know how um i'm

thinking about the ordering of the

so that's file four and then we have

file five right there and what we need

to do is we need to basically do the

a 10 inch display as you can see here it

says 10 inch tablet screenshot so let's

now we can close this emulator that is

right there then we can go back to

android studio so if i can find android

okay let's go to avd manager and in here

we're going to create a new virtual

device in this case it's going gonna say

is a 10 inch display i'm going to press

next and then sdk s that's fine as well

and just run it ooh landscape not sure

that's that may be fine but you know

what i'm actually going to delete it and

create a new one because we had some

problem before with the landscape mode

so i'm going to say nexus 10 again next

next portrait and then finish okay so

hopefully this starts it in the portrait

mode so then i'm gonna press the play

button right there and unfortunately it

started in the landscape mode but that's

okay hopefully we're gonna be able to

and i can see now it is running

and we should see now the home screen

let's see if we can rotate this uh

and unfortunately it doesn't actually

rotate so i want to see if there's any

properties in here that allows us to

from landscape to portrait so

snapshots recording settings enabled

nope nothing in there that allows us to

directional pad no it doesn't change the

landscape to portrait and i am now

basically trying anything i can so even

if i go to chrome in here for instance

and say no thanks and then if i rotate

this i can see that it's unfortunately

not rotating the actual application so

take a screenshot in landscape mode so

let's see if if you can actually do that

so if there's anybody out there who

knows how to fix this issue i'd be

because at the moment even doing the

command right and left it's not

listening to my commands it's not

basically rotating so how about this

um well that didn't help so so much to

it didn't really i mean i can go here

and then here oh now it's portrait okay

i did something so i just clicked on a

little icon on the top left after

rotating so it rotated to portrait so

let's go to visual studio code and say

command shift p on a macintosh or ctrl

shift p in linux and windows and save

flash or select device choose our 10

then i'm going to say run run without

everything is working correctly and

gradle's working in our favor then then

the gradle task is going to go by really

fast and i'm very grateful actually for

so gradle is working a lot better now

than xcode build process so here's our

application and displayed on a 10 inch

display and let's go ahead and start

taking some screenshots so i'm going to

go to terminal here and then start

file one in the login view then let's go

file two i'm gonna get rid of the

keyboard and take the screenshot without

the keyboard i'm gonna go here to the

register view get rid of the

keyboard and then say file three so

that's that let's not log in with a user

um like this and say foobar baz

log in with that user oh wrong

and after logging in we're going to take

another screenshot which is our

screenshot 4 and then we're going to

take another screenshot with the

that is also that then i'm going to open

the current folder i can see five

screenshots in here go to my desktop get

rid of the old ones and paste the new

okay now that we have those we can clean

emulator we don't have it and i'm also

going to close avd i can see it's

already closed so let's go back to

console so i'm gonna upload

this new um png file file one then file

two for the ten inch tablet so all of

these five screenshots are for the ten

and then we're gonna go to four here

and then last but not least we're gonna

upload screenshot five and then right

after the upload is done i'm just going

to delete all those files to keep my

desktop clean so after doing that let's

just then save this and now you can see

it says your changes have been saved

we need to create a release app so if i

just bring my notes up a little bit here

what we need to do we need to have a

look at a little url here as you can see

at the bottom of the screen it's called

docslatter dev deployment android it is

a very important document and here i

strongly suggest anybody who's trying to

create a release application to go

through this it has information for

windows and macintosh and linux users

and these commands are absolutely um

you may have to google these otherwise

around but this document has really put

all of that together in the same place

so as you can see in here the first

thing that we need to do is to create a

signing key for our application

and you need to follow these um

commands in here that have been created

for you so you can see and if i bring a

terminal and i'll bring it up here and

if i go to this folder dot android on my

computer like this and i already have

some keys as you can see in here so i

have some keys already set up but in

be able to follow along with this

and guide we need to go and create these

keys for us as well okay so what i'm

going to do is i'm going to do

let's see if i can bring up the command

for you as you can see at the bottom of

the screen so i'm going to actually copy

that command that i provided for you at

the bottom of the screen okay

so and i'm going to go to terminal and

um let's just go to desktop for instance

and then i'm going to issue that command

exactly as you can see at the bottom of

the screen so let's see what happens in

here now it says enter a key store

password so this is a password that you

need to then provide inside a property

file i'll tell you soon about it so

remember this password up until this

point for this course we've been using

foobar baz as a password is an

absolutely horrible password so please

don't use that but since we've used it

consistently in this course and since

the password in this sense has no

meaning for this course i'm just going

to say foo bar pass but please don't use

a password as weak as that so

and let's see what it said java as a

keystore was tampered with or password

um it this could perhaps be because i'm

actually trying to create an upload key

store like this and i already have one

from before so what i'm going to do is

to actually delete this file so i'm

going to say remove that file okay

upload keystore like that and i'm going

to issue this command again and i'm

and fubarba so if you if you've already

had a key store from before then you

could just use it but i'm assuming that

you didn't have one however when i did

issue this command i already had one so

chances are you didn't have a keystore

from before you didn't you didn't have

to delete it but in my case i actually

have to delete it first and then issue

the command that you can see in the

caption at the bottom of the screen so

what is your first and last name i'm

just going to save and i have andy poor

and your organization unit i'm just

and then name of your organization is

pixelity a b okay city or locality okay

i can just say stockholm okay

and state or okay stockholm again let's

see uh two letter country code i'm gonna

say s e and it is saying is it correct

then i'm gonna press the enter button

uh i've already entered all of that

maybe i made a mistake in here so let's

just say what was the question

correct no do i have to type yes i'm

you have to provide yes at the end of

that and then what is the same return if

same as keystore password yes just enter

okay so now it's created a key store

for us in here you can see in the

android folder upload keystore jks okay

so that's very very important

now that that has been created what we

need to do is to have if you had

followed this you can see that what we

need to do now is to go to our flutter

project in here you see it says go to

and go to the android folder and create

a file called key dot properties okay so

let's go ahead and create that so i'm

going to open visual studio code in here

and then i'm going to go to cd

and let's see where we are at the moment

root folder of our project standard

project i'm gonna go to the android

folder as it was suggested there and

then i'm gonna create a new file as it

was called here key dot properties okay

so key dot properties like this and then

paste that content that was mentioned

so maybe the entire content so i'm just

gonna paste it in here okay so it says

password for previous step from previous

step and we just said fubar bass

like that and the key password as well

and again that is foo bar bass the key

alias we're going to leave it as upload

and in here we're going to say the file

was stored in let's see if you can get

the entire path for this so it's right

here so i'm going to copy that path path

sorry and then i'm going to delete this

information in here and then paste it

so that should be good to go so i'm just

gonna double check in my notes as well

that that is how we've done it before as

well and that seems to be completely

then after doing that with an empty line

at the end i'm going to close this file

and save its contents right there so now

if you go to the main folder of your

application and say git status then you

have only these things basically

committing to your project because your

key properties are not going to be

and that's that's why i'm mentioning

here that you always need to make sure

that that particular file is not going

to be committed with your project into

github so you could always go to your

git ignore file and actually add that

particular file to your ignore so let's

not get ignore and in here we're just

going to add a new file and say any

key.properties file should not be

committed and then we do a good status

again that our get ignore is changed if

you're paranoid like me you will do it

so after doing that what we need to do

is to in fact create basically

sorry we have to update our build gradle

i provide a link which i'm going to go

configure signing in gradle and that is

and it is telling us exactly what to do

it says add the keystore information

from your properties file before the

android block you see this android block

in here so what we need to do is to go

to this file in our project android app

build gradle so visual studio code

let's go to um build.gradle in android

app all right so we're there and what

did it say that we have to find this

so let's find the android block right

there it's just one so right there then

let's copy this text as it is mentioned

there and paste it right before android

okay boom and i'm going to bring it one

basically formatted correctly okay so

that's that part and it says then load

the key.properties file into the

keystore properties object and that's

what this guy is doing okay then what we

need to do it says find the build types

block so let's go and find that you can

see the release we're gonna basically

edit that as well so i'm gonna go to my

notes as well build gradle uh sorry

about that just to ensure that i'm

following all the steps correctly

and in here it says release to do add

your own signing config for the release

build signing with the debug key for now

so flutter run release works and it says

then replace that with this so you just

have to grab this information here and

just completely replace this build types

with that thing that was provided i'm

gonna fix the uh indentation a little

bit as well so here the key alias

password are being read from the correct

place and then the release is signed

with the release key in here

and that is it really so you don't have

to do so much more and what we're gonna

do now is to as you can see at the

bottom of the screen we're gonna do some

cleaning up of the um of the build

artifact so in your project you need to

now go to terminal here as you can see

for on my screen so i'm just going to go

and we're then going to say flutter

and after doing that we're actually

um create our app bundle so after doing

flutter pop get then you have to issue

so by issuing this command you can see

now it is going to start building your

application with griddle using all those

properties that you've specified in

those various files so there was a lot

of work that we have to do but

thankfully it's been documented so well

that it makes the whole process so much

easier had it not been for all those

documentation bits and pieces it would

have been such a difficult process to go

through so let's just wait for this

build gradle process to now do its work

and all right now you can see that the

process has gone through it has created

our little app bundle which is this aab

and what we need to do is to be able to

then upload this app bundle to google

play store so let's go back to our play

store and here i'm going to close this

and let's now go back to our dashboard

and you can see my awesome notes and

going on in here and what we need to do

is to go to our production in here and

and then create a new release okay so

press the create new new release in

there and you can see now it asks you to

upload your app bundle so what i'm going

to do is to go back to visual studio

code and see where this file is located

so i'm going to open that folder and i

can see the aab here and i'm going to

then drag it in here and place it there

after this upload is done it may take

some time i can see it's 25 megabytes

although i'm at a thousand thousand line

um fiber optic network in here it's

taking like a while to upload i don't

but in the release name as you can see

it says that well this is not something

um that we actually share with anybody

so let's just say um first we call it

first version okay so and in here for

your release notes you will basically

copy from a previous release well we

don't have that listen here just say um

and then we can save this information

so now we have that um we have the first

that should be it so let's just go to

the review release in here and we have

one error that's probably because we

haven't provided the countries

and add at least one country or region

and that's fine we're gonna we're gonna

add that so let's go and see

overview where we have to add these

countries if we can't figure it out

let's click in there android okay

we need to go to under production and

all the countries or release as you can

see in google play a console under

production so i believe we're already

under production so if i click under

production now we can see countries and

regions so let's go in there and say add

countries and regions and i believe we

hopefully select all countries

sell such good make sure your price for

the countries well can we not sell oh

if i click here i can select all the

countries so let's do that and say add

countries and regions and then press the

then we're gonna go to our releases

we have this release so let's go to the

okay that's fine and then i'm gonna

and i'm gonna press the review release

now that we've selected all those

countries we have one warning the app

bundle contains native code and if

you've not uploaded debug symbols okay

and these debug symbols is something

that i actually encourage you to go read

about because these are gonna allow you

to see when whenever and if there is any

crashes in your application occurring

where your users are using your

i would really suggest that you do this

and upload your d box symbols although

that's something that i believe is

outside the scope of this course but it

should be quite straightforward for you

to figure it out and there's link in

here that you can read more about it

so now we can start the rollout to

production and then say rollout

and you'll see now this is going to go

and google uh cons like at the play

console could take some while some time

to rel to review the first version of

our application some people said it

takes upwards of a week and for me it's

some sometimes actually taking about

depending on what you've done like that

your track record from before if you

release any applications from before you

may actually be able to be placed

somewhere first in the queue or maybe

last i don't know i don't know their

um and that that was really in that was

like the releasing of our android

application and we went through quite a

lot even figma design in the middle of

everything so congratulations for going

through this together with me

since we've changed some code let's go

um actually commits all our changes so

i'm going to say good status

properties file the key properties file

is not added so let's just say git add

and then i'm going to say git commit

and if you have a look at our logs we

have step 30 and 31 so let's push those

changes to our remote and then i'm going

to say get a tag also step 31

that was it now you've released your

application for ios and android and um

this this could perhaps be the last

thing that you will um learn about in

this course right now as it is if you're

one of the early adopters of this course

but i'm planning on putting out a lot

more videos that i'm going to append to

this course with a lot more material so

stay tuned and i may actually see you in

the next chapter hello everyone and

welcome to this chapter in the previous

chapters as you've been following along

course you know that we've created our

application and we've also released it

for ios and also google's play store

i mean any application or any software

is not something that you will do and

it's just finished every application has

to live on and there will be you will

add new functionalities to it and then

um you kind of have to keep it alive

just as i will keep this course live

you'll also have to keep your

application alive so one of the things

that you might want to add to your

i mean if you haven't done software

development before you may not know what

localization in um short form is the

process of you making your application

more accessible to other people in

than the one for instance that um

up until this point we've been creating

our application with a user interface

but you may not be even from england you

may not be from australia or us you may

just speak the language english

and um for instance i live in sweden so

the application that we have developed

right now isn't really accessible to

even though most people in sweden speak

very fluent english however it's not

localization is um the process of making

your application more accessible to

those people who don't speak the

language that you've designed for your

about the language and the text that

you're using it also entails a lot of

includes many other things for instance

currency and values in your application

now we don't have like a shopping basket

or anything we don't have an e-commerce

application and that we've developed so

far so there's nothing for the user to

purchase in the application but

if you were developing an application

where the user could for instance buy

your shopping basket would need to for

the amount um for um like the product

currency so if you're for instance

presenting the ui to a person in sweden

that person doesn't expect to see for

instance prices in dollars they would

expect to see prices in the swedish

and um or if for instance you're doing

this application for someone in

england you'd probably want to do

british pound i think or just pound

localization is a lot more than just

changing the text of our application but

since our application doesn't have any

of those things we're not presenting any

dates for instance at the moment we're

any currencies or values like that then

for us it in it basically means only

changing the text of our application

so what we're going to do in this

we're going to do it in two languages so

for english which we've already done so

far which is the text that we've

provided for the user interface of the

application to this point and we're also

going to do it in swedish now you don't

have to know swedish in order to be able

to go through this chapter i'm going to

help you with that and there's a github

repository for this project that you can

the swedish text for instance

you don't have to even write swedish at

all you don't even have to follow along

writing the exact text that i'm writing

for instance in swedish you can just put

some gibberish in there because

all you have to do really is just to

understand the concepts of what

localization entails for your

application how you can do it with

flutter and then when it comes to

actually localizing your own

applications then you can for instance

choose um bangladeshi or if you want to

choose any language in india for

instance or um or do if in pakistan or

language you choose to basically go for

so you don't have to really know swedish

that's what i'm that's what i'm saying

um also as you can see at the bottom of

the screen localization could also be

for languages that are not traditionally

um arabic so those languages are written

there will need to be some special

considerations made into um

code for you if you're trying to support

right to left languages like for c

so for instance a name of a person

you may want to be able for instance if

you're presenting a list of famous

that for instance the user can read

about those names may not have to

um presented in arabic names like

they're like their spelling doesn't

necessarily have to be arabic it could

for instance an age of a person like if

you were saying bill gates you could

write the name in english even though

the language of user user interface is

arabic but the age of that person if

you're presenting then it might need to

be translated in like um numerical

values that are under understood by

whoever speaks that language

what i'm trying to say is that if you're

trying to support right-to-left

languages you may have to take into

consideration those points that i just

mentioned but in this chapter we're not

going to do that we're just going to

cover english and swedish and those both

the documentation because the

documentation for localization of a

fluster application is very thorough

and i highly suggest that after watching

this chapter and learning about it

from my perspective i think it is very

very important that you actually have a

the official become documentation i'll

try to open with a tab in here so um

i'll bring it to the screen so you'll

screen a little bit like this sorry i

have to do some rearrangement so you see

the screen better so as you can see here

it's an official documentation for

accessibility localization and

international internationalization

you'll see some terms sometimes for

instance and during internationalization

and localization you'll see some terms

and sometimes you'll also see l 10 n and

you'll be wondering like what are these

things what does it even mean l 10 n

and the reason for like what i 18n

and then if you take 1 2 3 4 5 6 7 8 9

one two three four five six seven eight

so 18 total number of characters between

so it is known then to write i 18 n just

to refer to internationalization

and the same thing is true for

localization because let's let's bring

up for instance visual studio code

maybe we can actually see in visual

studio code a little bit better

increase the size of the font

international non-lineation

okay and then write localization so that

was one two three four five six seven

eight nine ten one two three four five

six seven eight so it's 18 total and if

we look at localization between l and n

if you count it one two three four five

six seven eight nine ten characters so

a lot of people refer to these things as

i18n and l10n i18n basically means

internationalization and l10n means

localization so now you know the reason

for that it's just it's just programmers

being lazy and trying to like shorten

everything as much as they can so now if

you see these two terms then you know

okay so what i was saying basically in

the beginning is to please after

watching this video go ahead and read

the official documentation because it is

very important it's very thorough it

talks about things that we don't even

highly recommend that you read this

so that was that and now what we need to

do is to basically get started by adding

um internationalization localization

support to our flutter application so

i'm gonna bring bring a visual studio

code in here and maybe decrease the size

i'm gonna change the screen layout all

um this is how we've left our

application to this point so what we

need to do is i'm just gonna close all

the tabs and then i'm going to press

command and command p in visual studio

and then we're going to look at our pop

if you go there and what we need to do

is to add flutter localizations to our

let's have a look in here and you can

see and you may be actually wondering

what am i even talking about what is

localizations and i didn't make that up

it is basically documented right here

as you can see it says the first thing

that we need to do is to go to our pop

spec yaml file and add flutter

what this basically does for our

application is that it allows

localized and it also adds uh like

auto-generated code for our application

it is a little bit difficult to explain

exactly what it does before you've seen

the results so what we need to do for

now is just to find the dependencies

section of our pop specky ammo here and

i found it here and what we need to do

in as you can see it says you just need

to add flutter localizations and i'm

going to do that right after flutter

and then we're going to say sdk flutter

all right so that's that and this

application at the moment is not running

so what i'm gonna do is just to say

um select device and then i'm going to

use my android phone okay as you follow

along with the with the course you know

real devices running so right now i have

um scr cpy i think somewhere let's see

if we can bring it up actually let's go

and then on the side i also have an

actual iphone running here so

basically there are two devices and that

have our app installed um so an iphone

and an android and we're going to work

so um what we're gonna do is to run our

application uh on the android phone for

instance i'm gonna say command shift p

on mac and then ctrl shift b on a linux

machine or windows and then say select

device and i'm going to select this

android phone then i'm going to go to

the main dart file and then just say run

without debugging so let that do its job

i'm going to decrease the font a little

bit because it's just humongous at the

moment so after doing that after adding

the pop specky ammo in here we also need

to make sure that we follow the

as you can see in here it says yeah you

have to do these things and we're going

but what we're also going to do is to

add this internationalization package to

our application so let me remove that

screen from there make sure that our

android application is running and this

is the state i've left the application

i'm logged in at the moment so what i'm

going to do is just to log out

all right so that up until this point

the only thing we did really was to add

flutter localization sdk true sorry sdk

flutter here then what we need to do is

to add the internationalization package

to our application okay so let's go and

i'm going to open a new terminal in here

in visual studio code and change the

layout a little bit so you see it better

and let's just go ahead and say flutter

and you can read more about this intel

package on popdev so if we for instance

go to create a new tab in here and i

bring it here and we just say puff.dev

and let me increase the size

to a little bit more ginormous size

and let's just say intl okay and you can

see here's the intl package

and it is from darkdev so it is actually

an official package that you can include

in your application and there's

documentations about how to use it okay

so you can also see how you can for

instance um handle date formatting in

different languages all right so now

we've added that and if i bring this

screen like this so you can see the

results of adding that package to our

it says got dependencies all right so

that was the result of saying flutter

fantastic the other thing that we need

in our pop spec if i change the screen

um we need to go as you can see at the

bottom of the screen we need to add a

generate true under the flutter section

and it is right here so this generates

true that we add just like this it is um

very very important basically for how

code generation is gonna work

so i'm gonna basically have a look here

generate and add space here okay so if

you add this generate true in here it

allows the localization packages and

like the localization code that is

running in your application to generate

code for you what i mean by that is as

file called a file type called marb

and these arb files are kind of like key

files and very i mean kind of like json

and in the keys um you specify some

names for instance you say login screen

and the value would then be the actual

value you've translated in that specific

and you will have multiple of these arb

and i think actually i'm going to

explain it rb more soon but it stands

for application resource bundle

i mean i don't want to go too much into

details about arb files right now

because there's a section coming up

where i'll explain that but what you

need to know right now is that this

generate true flag under your flutter

section in pop special allows

the auto generated code to basically

hook itself into your project and when

you add new keys and values to your arb

files as you'll soon see how

then up then the code generation will

kick in every time you do a hot restart

or you run your application fresh and it

will go through your arb files and it

and this dart source code will be

something that you can literally import

into your application and like use the

keys you added to the json as just like

dart code inside your application

so this is a lot of talking just like

abstract talking but you will soon see

exactly how these things work so don't

so what we need to do now is after we've

done all this work we need to basically

add support for localization into our

ios application as you can see at the

bottom of the screen in the caption now

android works just automatically in that

when we start adding localization to our

application new languages the android

app just completely understands then

okay here's a new language i can handle

that and i will just refresh my

ui in order to display all the values

that you entered but ios is a little bit

more old-fashioned you have to help it

understand that this application

actually supports various languages

so and i'm actually glad to say that you

don't have to have xcode in order to go

but we need to as you can see at the

bottom of the screen we have to go to

our info plist file and update a special

section or create a special section

called core foundation bundle

localizations okay so let's go ahead and

actually take care of that right now so

i'm gonna also bring up my notes to

ensure that i'm telling you all

everything that i plan to tell you

see if i can find that section

so what i'm going to do in here i'm

going to close that file i'm also going

to close the main dar file and then i'm

going to press command p in visual

studio code and i'm going to look for a

file called info.plist it should be

under the ios folder slash runner and in

there there's an info p list and if

you're curious exactly where that is you

will be able to for instance go to

terminal and i'm gonna clean the

terminal and i'm just gonna say open you

can see this is the folder where

this entire course source code is based

okay so we're gonna open as you can see

this is the source code where we we are

at the moment and there is a folder

called ios and in there there's a a

folder called runner and in there

there's a file called info plist so

that's the file that we have to open

so i'm going to say command p again and

then info plist let's open that and

these are like key values as you can see

it's it's a strange like p list kind of

like an xml format kind of thing

but you will need to look for cf bundle

and if you don't have cf bundle

localizations then you'll have to create

it just like in here so as soon as you

see this dict which is dictionary let's

go ahead and create a new key so let's

just say key and we're going to say core

foundation bundle localizations

and then we end the key right there

and what you have to do this the value

of this key is not just a string but

it's actually an array an array meaning

of things it's a list of languages or

localizations that your application

as you see all the other things in here

there they have like these keys and then

values but for us we have to do

something like this you see there's a

bundle localization and localizations

and we have to then create an array so

let's go up here right after this say

and then we close the array just like

that you see this is how they were doing

and then we need to add two strings in

here so one string and we close that

and another one okay so because we're

supporting english and swedish so every

string in your arraylist is gonna then

indicate the language code that your

application supports okay so first we're

gonna support english and then we're

gonna sweet and support swedish and

swedish language code is suv because in

and sweden itself we don't call the

country sweden we call it sevaria

and that's what that's where sv comes

from but you can also google this and

you can like look for localization

country codes and you will get to a list

on wikipedia or something that tells you

exactly what you have to use for

instance if you want to write um

a special language in india or pakistan

like urdu or whatever you'll have to

find the correct language code for that

so but you can google that easily so um

i'm not gonna present all those

languages code language codes in this

chapter but i'm just giving you the

tools necessary to find out on your own

okay and that is it really that's all we

have to do for the ios app so we've

added the cf bundle localizations in

here and we're good to go for the info p

then what we need to do in here is we

need to go into our root folder of our

application and then we need to add a

file as you can see on the bottom of the

screen called l10n and as i told you

it means a localization that's the 10

thing meaning that there's 10 letters

between l and n in localization so let's

go ahead in here and i'm just going to

right click on this folder in here and

and then let's add a new file and call

in here then we have to write some stuff

and i'll bring the official

documentation because it is very very

helpful in this case so let's go and

have a look at the documentation what we

have to enter in this ltn file

let's see if we can find it somewhere

and it is an arb file so l10n

and it looks like this so this is this

is like the contents that we kind of

need to place in our l10 file

arb directory and it's called lib el

tenen all right and we'll soon have a

look at what this actually means

and then we have something called a

template arb file and then something

called an output localization file okay

so um i'm going to explain to you what

this what these all actually mean

what this arb directory means is it is

an indication for you you're telling um

flutters auto generated localization

files where to find your localizations

when you create localizations for a new

language then you have to create a an

arb file so and you're basically telling

dart in this case or flutter in this

case that these arb files i'm going to

create are going to reside under this

folder so if you look at visual studio

code here we have now a folder from all

when we created basically our project

which was called lib as you can see in

in this lib then we're going to create a

folder as it's indicated in here called

l10n well you don't actually have to

call it altenent and that's why you have

this configuration so you could call it

something else you could call it

localization if you want to or my

strings whatever you want to it's just

an indication to flutter and the

localization engine where you're

replacing those files okay

so that's that so that's you're telling

dart where it f it where to find your

localization information then in here

the template arv file is a file in that

basically choosing as the main language

of the application so if for instance it

can't find a key for swedish in the

swedish file arb file it's going to fall

back to the english one and this is like

setting the ground for or setting the

foundation for how you're localizing

you can think of it as the default

language that your application supports

in our case that language is going to be

english so we're going to leave this

file name as it is indicated here

the other thing output localization file

it is a file for that auto generation to

basically create for you so as you'll

soon see auto generation is very special

so um but you have some control over it

and this is like one of those things

that you can control you can actually

control where that auto generated dart

code is going to be generated and in

it is a little bit abstract so i'm not

going to go too much into it and you'll

soon see how we can configure this and

what this actually means so what we need

to do in this internationalization

documentation let's just copy this

and i'm going to then go in this l10 and

yaml file that we created and just paste

what we need to do in here we're going

to leave the arb directory directory as

lib l10 because that kind of makes sense

uh but in here app instead of app ian

i'm just going to say intel yeah it's

just for me it makes more sense to

the intl underscore en as the default

file so we're going to create intl en

sv for swedish okay and then we're just

going to leave this as it is so i'm just

going to save this file right there and

now remember hot restarting is something

in internationalization it's very

important flutter because hot reload

won't trigger auto generation of your

internationalization code meaning that

if you've added some new strings for

instance to your arb files as we'll talk

about it soon those things won't be auto

injected and generated into your code

until you do a hot restart hot reload

won't cut it so you have to either do a

hot restart or just completely stop the

application and build it from scratch

and that's a huge overhead so you may

not want to do that but a hot restart is

so let's have a look now at um

arb files are as i mentioned before now

arb files are application resource

bundles and they're pretty much json

files they are key values in there and

your keys are basically how a handle for

your application to then reach into your

localization and grab for instance a

string and the values of those keys are

the actual strings that will be

displayed in your user interface

they are more than just key values

because you can actually put logic in

your arb files in that for instance as

inside this screen let me bring it up in

scr cpy and if you log in with a valid

and we have foobarbas as our

um in this screen at the moment on the

top of the screen we're seeing your

notes but what we're going to do in this

chapter just to demonstrate how arp

files work we're gonna say if you have

you have one note something like that or

if you have more than one note then it's

gonna say for instance if you have three

notes it's gonna say three notes

or if you have zero notes no notes at

which is the title on top of the screen

we can actually put logic into the arb

this isn't a title however i wanted to

if this particular count is zero i

wanted to say you have no notes

if the account is one i want it to say

you have one note or if the count is

more than one i wanted to say you have

amount of notes and that x is the actual

number that we will provide to it

so rb files are more than just json they

can actually have logic in them and they

stand as you can see at the bottom of

the screen they stand for application

all right and now what we need to do is

to actually go and create these um files

so let's go into this lib folder

and let's go and create our the folder

that we mentioned in this l10 and you

see we said that under lib we're gonna

have a folder called l10n and under that

l10n we're gonna have a file called intl

en arb okay so let's go ahead and see if

we can get that to work so in lib let's

go and say new file and then i'm going

and you can see that it creates the

folder as well lib l10n and intl enarb

and that is the file that we said we're

let's then go ahead and say new file

intl and then we're going to say sv arv

and as i mentioned before these are very

simple jsons to begin with so we can

just create a json for instance here and

so like this and in here i'm just going

and then a value of my title goes here

okay and let's just copy and paste this

in the swedish one as well just for now

so and i'm just going to do a hot

all right so what this all did since

we've added our auto generation

in our pop speaking ammo if you remember

from before we added this generate true

inside here now what you should be able

to do is to have a look at the structure

of your project and now all of a sudden

you should be able to see a folder

called dot dart tool and if you drill

down in there you should be able to see

something called a flutter gen and if

you drill down in there you'll see gen

l10n and in there you'll see now three

files app localizations app localization

sv and applicalizations en now

what is this app localizations well if

l10n we actually told the generation to

generate generated code to be named app

basically it that's that file we said

that it needs to be called that so we

can open that and you'll see now there's

some information in here and

there is a locale name for instance and

then there are some delegate stuff and

i'll explain all these but what you'll

see here now is something called my

title and is a string and this is

exactly what we wrote in this my title

and you can see then if you go to the

your string is there my title goes here

and the swedish one is also saying my

title goes here so it's not so it's not

so impressive since we actually chose to

have the exact same string in the

english and the swedish version so what

we could do is to go to the english one

intel en arb and put eng at the end of

it and go to the swedish one and say

okay and then i now get a a save on this

file and then if you go in here you'll

see nothing has changed and that's what

reload doesn't cut it you have to do a

hot restart and if you do a hot restart

then this code should basically get

updated let's go ahead and see if it did

you can see here's the english one oops

i didn't mean to change it and here's

now you know what those things actually

we now have a really good ground to

stand on because we've created our

localization yaml a configuration file

we have our english and swedish

localization files right here in lib

ltn and under those we have intel en and

internationalization english and

international nationalization swedish

now all we really have to do is to

basically go ahead now and start

strings in our application and um kind

sorry populating them in the in these

arb files and then where in our

text hard-coded then we're going to

strings which are in our l10n

and in order for our application to

we have localized in inside our arb

files we have to actually tell the

application which locales we support

mention sorry in order to explain that

we have to go back to the main dart file

let's go to main dart file and have a

look at how we've created our

application and you can see we have this

code right here that at the moment says

run app and then we're creating a

and there are two important properties

in the creation of material app which we

haven't used so far because in the

previous chapters we haven't done any

localization of the application so far

so these two properties are namely

localizations delegate and supported

let me bring up the caption for this

section um the way flutter localization

communicates with the ios app and

android app or for instance a web

application or desktop whatever you're

running flatter on it needs to tell the

underlying operating system what locales

so basically that's telling your

material application which languages

your application is built to work with

so that's the locale so you could say

swedish english persian and arabic or

what have you so those are the locales

but you also have the concept of

localization of your widgets

you see at the moment we've created some

strings and and also we're then gonna

soon go and place those strings on our

ui but also flutter itself has

localization support for various

languages there are so many languages

that flutter at the moment supports and

it can internally also localize its own

widgets for instance if you bring up a

date picker for instance in your flutter

application for user to select the date

that day picker itself can have

localization based on the system's

language or your application's language

so if you've chosen arabic career

applications language versus at the os

then and if you bring up a date picker

then that date picker is going to be

localized for that language by default

you need to tell material app both about

the locales that your application

supports also how it should localize for

instance internal widgets and also your

what we need to do is to actually go and

add these two properties here

and what we want to do is to refer to

this app localization file so if you go

to dart tools and you can see there's

this app localizations right here

and you can see there is a pop speaking

ammo and and then this is basically a

package so it is a package that was

created for you you haven't done

anything it's just generated for you so

how do we go ahead and import this in

our application and that is by going to

the top of your main file for instance

and say import and then you say package

and then in here we just say flutter

and this is like the generated code for

you and then gen l10n and in there

applicabilization's dark files so i need

you to please go ahead and import this

after having done that we need to go to

the material app and right before we do

anything else we're first going to say

supported locales this is a property and

that allows us to tell flutter which

lookouts our application supports

now you may be wondering okay what data

type this is this is actually a list as

you can see it's an iterable of locale

and some people go and incorrectly

create a custom list of accounts and

then put that in here but you don't have

to do that and i actually suggest that

you don't do that even if you can

because if you go inside this

applicalization start file you see that

it is created for you calls supported

so it is already understanding what

locales your application supports based

on the arb files that you've provided to

please don't go and create the same list

in your main dart file in here what

you'll need to do is just to say

and then you just say supported locales

okay so this goes and uses your arb

files as like a guide let's see lib

ltn and ar b fast it just knows that

you're supporting english and swedish at

so that's the first thing that we have

to do the other thing that we have to do

it's called localizations delegates as

you can see it says the delegates for

this apps localizations widget

a way for you to tell flutter that hey i

support for instance swedish and english

please localize your own widgets as well

so in here you don't have to create

custom delegates because those are also

provided inside your applicalizations so

if you go in there you'll see

localizations delegates all right so

what we need to do now is just to say

and then localizations delegates so then

that is provided and i'm going to do a

hot restart just because we've changed

the main function in our application and

those changes aren't going to take

effect until you do a hot restart okay

and what we can do now is to go ahead

what would be really great is actually

if you could extract that little title

that we've written in our intel en arb

and and put it somewhere on some sort of

widget just to see that it is working in

english and in swedish so what i'm going

to do is i'm going to bring scr cpy on

right here at the moment you can see

we're on the login page so let's go to

the login page and you don't have to do

this so i'm just going to do this myself

just to demonstrate something and while

we're in the login page let's also clean

up these two unused imports okay and

let's go ahead into our code here to the

login and you can see there's a cons

text login but in here we want to use

that title and again you don't have to

do this and i actually suggest you don't

do it it's just for me demonstrating to

you that hey it's working as expected

okay so just follow along and look at

this part without having to do it

yourself so what we need to do in here

let's go and import the same

localization so i'm just going to say

and then we had flutter lock

what was it called let's go to main dart

file and and exactly copy and paste that

flutter gen okay and i'm gonna bring it

i'm gonna paste it there so we also have

access to our localizations and the way

to grab your localizations is with this

code so if i write this for instance

just in here i'm going to remove

actually let cons be there i just want

you to see why we have to remove const

in the future so for us to be able to

grab this string which is my title in

our login view we have to say app

context and then we can say my title and

then we have to explicitly on wrapless

okay so this is how you grab a

localization out of your um supported

localizations basically the stuff that

so now we have my title and in here as

it says hey a value of type null can't

basically this is an issue with having

constant here because in in the previous

i mean up until this point the way we've

created our app bar was that we said

that is a constant string it's a

constant text that says login but now

that all of a sudden we're saying we're

retrieving this text from our

applicalizations these properties

constants so if you go in here you can

see it's just a string getter and that's

the reason you can't have cons in here

so i'm just going to remove that cons

it's going to be very happy and the

reason we have this exclamation mark in

here is that the app localization is off

function and you can see it returns an

optional application it is a bit

unfortunate i don't really like the

syntax that everywhere we have to go on

an exclamation mark in here and we're

actually going to fix that soon right

after this demonstration and because

as you'll see soon it is soon gonna get

quite annoying to have to always say

applicalizations of context exclamation

mark dot and then the name of your

property but so hang on we'll fix that

soon so now we have the login in here

and i'm going to do a hot restart

and let's see what we get i'm going to

bring scrcpy and now you can see i see

my title goes here swedish all right

and that's the title that we put in the

swedish you see right here okay

so we have that english one let me bring

the swedish one next to the english one

so we have the english one and the

swedish one here and you can see at the

moment we're seeing the swedish one and

the way to actually change the language

of your um phone on android is a little

bit different from ios so here i'm just

install nina and that's settings and in

here i believe it is somewhere

and then spirowak which means language

and then i'm going to go to language and

at the moment spirowak here is swedish

i'm just going to bring english on top

and you can see now english is on top so

let's go back to our application and see

if its title is going to change and now

all of a sudden you see that it's

displaying the english title so it's

working very very well on android i'm

gonna get rid of the scr cpy on the

device which i've created with um

so it's an iphone 12 pro that is sitting

on my desk right here and i have

quicktime which is mirroring that iphone

screen here so let's go ahead and in

here stop the process on android and

then command shift b on macintosh to

select the device or control should be

on windows and linux and say select

device and then i'm going to choose that

iphone 12 pro and i'm going to go to the

main dart file because that's how we

should run the application because if

you try to run the application when

you're on this file it's just going to

give you an error telling you hey i

don't know how to run an arb file so

that's the reason you always have to go

in your application so that visual

studio code at least knows how to run

quicktime here and let's wait basically

for this running xcode build process to

and as i've mentioned before sometimes

much slower than building with gradle so

that is quite annoying um so i'm just

gonna wait here until this process is

done let's see how long it takes

oh it's installing that so i don't

actually have to do anything so

installing and launching it says at the

let's see how long that takes and i can

see now that it's going to install the

application right here we should see

now it is launching the application and

we can see that at the moment the user

and face is english and um so i'm gonna

and then bring visual studio code here

as well all right fantastic so um

an iphone a real iphone on your computer

screen with quicktime isn't going to

allow you to interact with that iphone

at all and scr cpy is very special in

that it connects with adb and at the low

level it allows you to interact with the

however the same thing isn't true when

you're mirroring an iphone screen so

right now i have to go and interact with

i'm going to grab this phone

and it is right here i don't know if the

cable is long enough for me to show you

so here is the phone right there

and i'm going to then go to system

and i'm then going to go to general

and then let's go to language and region

and in there i'm going to choose swedish

the the thing that is a bit

disappointing in ios is that the

language that you choose for your system

is for the entire system and when you do

that it's going to kill all the running

applications because ios applications

don't have the possibility to change

their language on the fly that's

like android does very very well in that

you can change the language of the

entire system and nothing has to restart

the applications keep running you could

even see when we changed the language

the um like here we couldn't we didn't

basically see the application

what we need to do now is to ensure that

we don't change the entire system's

language instead i'm going to show you a

way that you can choose to do in ios

that changes only your applications

language so let's go back in here and

let's go and find our application which

is called my notes i believe somewhere

and let's see if you can find it and

it's right there my notes and now you

can see that there's a menu at the

bottom of the screen that says language

and then i'm going to tap on that and

then i'm going to choose swedish and the

reason that you're seeing these two

options in here because the change we

made in our info p list so if i say main

we can see that we said english and

swedish in this order and that's why

they are displayed here also in that

order so i'm going to then choose

swedish and as soon as i do this you'll

see up here that our application will

terminate because ios can't handle that

and there we go the application's

but that's okay so i'm gonna go back

here and then open the application on

ios oh now we have to debug it as well

okay because we're in debug mode so

let's go ahead and main dark file and

then run the application again

and you can see it says in ios 14 plus

debug mode flatter apps can only be

launched from flutter tooling ids with

flutter plugins or from xcode

so this is a little bit unfortunate as

because then you have to basically run

over and over again just while you're

i would say it's one of the shortcomings

of running applications on ios as well

like there are so many things i feel

like android is ahead of ios

that it's just android is a little bit

more developer friendly i would say

the whole operating system is a little

bit more friendly so let's see

um i can see now at the bottom of the

screen it says installing and launching

so let's have a look here now our user

interface should be in swedish

if everything goes well of course

if things are going well then on ios we

don't have to do this process over and

over again so it's just just to make

sure that it's working for the first

time as you can see now after changing

our applications into language to

swedish now we can see the swedish title

being displayed on top all right

so i'm going to close the widget

and i'm going to stop this process and

i'm going to get rid of this and now we

should be focusing only then on

deploying on android because it's just

so let's go and do a flaster select and

then i'm going to say i'm choosing to

run my application on my android device

then i'm gonna put away my iphone

so that is that and and the thing that

we need to talk about now is at the

optionality of this app localizations so

if you go back to our login view you saw

applicalizations of context is an

optional value because this function

returns an optional app localizations

and there is a way to make this better

it's one of my favorite ways it's like

the shortest extension that we can write

in our flutter career progress

but it's one of the most powerful as

in order not to have to repeat this code

what we could do is to create an

extension on build context that grabs

its applicalizations and returns it as a

non-optional value so here we have

applicalizations being returned by

passing the context in but what we are

going to do is to grab the applications

from the context itself all right

how we can actually do that in order in

order to get started let's leave this

code as it is right there we don't have

to do anything special but what we're

going to do is to go as you can see at

the bottom of the screen we have to go

and create a new file under lib

extensions and then we're going to

create a new folder as well called build

context lock dot dart and lock as in

localization in this file we're going to

create our extension on build contacts

return our localizations to the caller

so let's go ahead and do that

i'm going to go to lib in here and then

we have um as the bottom at the bottom

of the screen says extensions we already

have the extensions folder but we only

have list folder in there with a filter

file so in extensions i'm just going to

right click and say new file then let's

go ahead and create build context slash

and in here what we're going to do is to

after gen as we did in the other places

and then gen l10n applicalization starts

so that's the first import and in here

we don't we only need a few symbols or

actually one symbol which is the

applicalizations but we'll talk about

that soon so let's go ahead and say

extension um and we're gonna say

localization on build context as you'll

see it says i have to also import this

because it is in material so i'm gonna

and i really don't like as if as you

follow along with this course i don't

like to import everything in material

like if i only need build context i only

need build context so i'm not going to

import everything so let's just go ahead

and that only brings build context in

what we need to do in here we're going

to create basically a getter which

applocalizations we're going to say this

is a getter and it's called lock

and what it does is is returns

an exclamation mark at the end of it so

and also you'll see that we've imported

applications as a whole but we only need

app localizations from that file so i'm

just gonna say show this okay

so that's that file now it's created and

and while this all is going on i'm gonna

select that and also i'm gonna say run

because it is always good to have the

application running as we're doing hot

restarts and hot reload so we can see

the results on the screen so with this

extension now you're soon gonna be able

and then you can get your localizations

so let's go back now to this login view

what we wrote here as you can see is

this syntax at the moment but what you

can replace the syntax with is if we

remove this and we just say context

which is our build context and then you

say dot lock and you'll see here it says

oh i don't know what lock is and that's

correct it doesn't know what lock is

because we haven't imported that

sorry about that i'll just close the

so it doesn't know what that is so i'm

just going to say command dot and it's

going to auto import it for me great and

now we can just say my title

i mean tell me this isn't better this is

for me 100 times better like if you

compare this with what we had before

which was this i mean come on

it's a lot shorter a lot more is the

same and i personally think it is it is

let me go back all right so let's leave

this here for now okay just my title

let's leave it there and let's go to our

android application which is scrcpy in

here and we can see that it's displaying

the correct title so if i do a hot

restart as well it's still going to work

and display the string from our

we actually have to talk about

all right how are we going to go about

well this is the important part you see

localizing is in a lot of places quite a

boring work in that you have to

literally go for instance if if you're i

mean it is boring if you're doing it the

way we are doing it in this chapter and

that you have to go and collect all

excuse me and then you have to go and

place them in your arb files and then

you have to also place them in the

swedish arab file and then you have to

etc so you have to create keys for all

this is quite a boring work and it is

not something that we're gonna do in

this chapter because i've already

prepared all those for you so you don't

have to go and write them by your by

what i'm going to do here is i'm going

to literally go and bring all those

strings that i've prepared for you

and let me see if i can find them

okay i found them right here

and what i'm going to do then is i'm

going to just bring all those strings

arabi file so here you see at the moment

we have my title and i'm just going to

leave my title in there because we're

using it right now but we're going to

and i'm going to paste all these strings

that i've prepared for us okay so there

we go all of those are here now and

there is a github repository for this uh

uh course of course and you can go after

chapter is done you can go to that

github repository and retrieve all these

strings so you don't have to type them

it is nothing n nothing at all special

going on about this as you can see we

have just a logout button that says log

out we have versus a cancel button we

have the verify email which is something

that we're using in the verify email

screen for instance we have the register

button we have the restart button let's

see where the restart is used

oh restart i believe it is inside the

verify email screen so if i created for

if i say pixel to a b gmail foo bar

um oh sorry to register screen so let's

gmail.com foo barbaz i'm gonna register

this user and then we're gonna go into

this screen at the moment it says

restart and that's this key restart okay

so i literally gone to through all our

screens all our dialogues as well and

collected all those strings and placed

international internationalization enarb

file and i've also done the same thing

for swedish so i'm going to go and bring

those files i'm sorry bring those keys

in here so i've done the translation to

swedish and i'm not my mother tongue

isn't swedish so but i've lived in

sweden for a long time so um i can't

actually enough i can speak enough and

i'm gonna paste those string in strings

in here as you can see they're

completely in swedish okay so what i've

done is literally we have the english

ones you can see here and we have the

swedish ones so it's the same keys but

and again don't worry i understand if

you're watching this course you're like

oh but how am i going to get all these

just please go to the github repository

and you can extract these values you

don't have to type them by hand

so now we have these in order for our

localizations to be generated in these

flutter jan and have a look at this gen

gen l10n you can see those strings

aren't here at the moment because only

my title should be here somewhere let's

locale should reload my title you see

nothing else is in here but if we

do a hot restart all those strings

should get generated and then we should

have them all here you can see login

verify email all these are provided

that's that part so now we have all our

strings and we should just be able to do

the coding part which is the fun part so

let's go ahead and take care of that i'm

going to close all these files that are

there at the moment so we have a clean

the first thing that we're going to do

is to localize our um what is it called

cannot share empty note dialogue so

let's go ahead in there and then i'm

going to say command shift p and go to

cannot share empty now dialog

if you remember if you're if the user is

trying to share a dial sharing note that

so sharing in this case we have a key

for it so we're just going to say

this lock is an extension that we've

created we don't have access to it

unless we import it so i'm just going to

say command dot in visual studio code

and it's going to also import that file

just right here as you can see

and now we have access to all our

strings okay so in here we're just going

which is a key i've created remember all

these keys are in the arb file

and you cannot share an empty note so

we're going to say context.log

cannot share empty node prompt

which is a key again i've called an okay

so and now we've localized our show

cannot share empty notes dialog

localize our delete dialogue so i'm

going to say command shift p visual

studio code on mac or control should be

usually code for windows and linux and

this and let's say delete dialog

little uh title in here so let's just

say um context dot lock and remember

we're in a new file we don't have access

and in here i'm just gonna say delete

and prompt we're going to say context

unlock and delete nodes prompt

cancel context dot log cancel

and here context.lock and was it okay or

it's yes so let's just say yes all right

so that's the localization of this file

as well i'm going to say command command

s or just hot restart the whole thing

maybe it's better and i can see a crcy

crashed unfortunately and that's the

problem i've had with this cr cpy for a

long time that's okay it's an open

source software i'm just gonna say

and this and i'm gonna run the

application so we have it running in the

so uh that's the delete dialog now i

have to capture at the bottom of the

screen in case we have to go and

localize pretty much everything in our

application up to this point and now the

next step is to localize the error

dialog so let's say error dialog

and in here let's just you can see it

says an error occurred and we've called

a generic error prompt in our arb file

generic error progresses and error

so let's go ahead and use that here so

i'm just going to say context.lock

auto import i don't have to explain that

anymore and then we say generic error

we have an ok as well so context lock

then we have to go and localize our log

out dialog so let's go to log out dialog

and we're going to do the same thing in

here so let's just go ahead and say that

we're going to use the log out button in

here and you see we have log out in a

few places like if you remember in the

main application interface when you're

logged in with an actual user i'm going

to bring in crcpy so you know what i'm

if you look at this screen if i say

restart and if i log in with a user and

when you log in with an actual user then

you have this little log out in here and

it says log out and at the same time

when you tap on it then there's this

dialog that says logout so we have a

choice in here either you go and define

two log out strings with different keys

in your arb file or you just define one

and that's exactly what i've done so

we're in here i'm just going to say

context.lock that's how to import

and in here we're just going to say log

and it says log out button i understand

it's the title of a dialogue and we're

calling the log out button you may just

go ahead and call this key log out if

you want to i'll just call the log that

logout button remember these are just

keys you can change them easily okay

now that's that's for our title and then

for the content we're going to say

log out and dialog prompt and we have a

cancel button here so let's say let's

just say context log cancel

and again we have another log out button

you can see here so log out here log out

here and then log out in here so there

are three places using the same thing or

log and then we're going to say log out

so that's great so that's that part as

well i'm just gonna do command s to hot

the next thing that we have to do at the

bottom of the screen in the case in the

caption we have to go and localize our

password reset dialogue so i'm going to

remove log out dialog here and close the

tab and let's go to password reset

and in here we have this password reset

and i'm going to go to my notes as well

so let's go in here for the title and

and we're going to call it password

reset it's one of the keys i define and

in here we're going to say context lock

password reset dialog prompt okay

and we have an ok button so you now by

this point that we have an ok key as

so now we've done basically we're done

uh localizing the show password recent

dialogue uh uh show password reset sends

okay the next uh dialog is um

forgot password so let's go to

that sorry this is not a dialogue this

is actually a view so we're going to go

here i mean when it comes to views our

job is a little bit more difficult

because up until this point we've pretty

used constants like if you look at this

is a constant string here's a constant

here is constant so everywhere that

we're going to localize our strings and

we were using const before we have to

remove that cons now because our

localized properties inside arv funds

are unfortunately not defined as const

and i don't really know the reasoning

behind that simply maybe because there

getters and maybe getters can't be

constant or there are some

other problems with the generation maybe

that um the flutter team decided that

well these can't be constants but that's

something that's the truth that we have

to live with at the moment so

let's go ahead and find all our strings

and we're going to start localizing them

one at a time before i got password view

so here in this show error dialog and

i've called this key forgot password

view generic error so let's remove this

and we say forgot password

view generic error and i'm going to put

a comma at the end so it's formatted

nicely so let's go to this forgot

password title itself so i'm gonna

remove the const remember i just

explained that so we're gonna say

context log and we're gonna say forgot

password that's the key i've defined

and you can also see its description

here and you can see it says forgot

in english this message translates to

so this thing i've called it forgot

password view prompt so let's remove the

const remove the string itself and we're

context log forgot password prompt

forgot password view prompt and put a

comma at the end and let's have a look

at the documentation for this as you can

see it says if you forgot your password

simply enter your email and we'll send

you a password recent link okay

so that's one thing and then in your

it says input decoration your email

address because that's a forgot password

screen let's go here and have a look at

here i forgot my password so here's that

i can see i've called it email text

field placeholder so let's remove this

const and in here we're going to say

context log email placeholder text field

let's go ahead and have a look at this

one so let's remove the const it says

send me password recent link and i can

forgot password view send me link so

context log for god password forgot

send me link here and put a comma at the

gets busy with formatting the code and

i can see that i've called it forgot

password view back to login so

back okay so and this is this is a

technique that you can also use like if

you want to get like a property like

this that's quite long name and you want

to get the name immediately right you

could just write a few keywords of that

name for instance i know that for god

and back are quite unique names so if i

say forgot back it it's gonna show me

it has this like partial search kind of

in its intelligence which is very very

the next thing that we have to do is to

go ahead and localize our login view so

i'm going to close the screen forgot

password view and go to login view

login view right here and we're going to

start at the bottom at the top of the

we'll remove this unused import right

and let's go ahead and start by uh

localizing our dialogs so the first one

is cannot find a user with the entered

credentials and i've called it cannot

or login view cannot find user so i'm

just going to say context.log let's auto

or it was already imported okay that's

great and let's just say it is called

login error cannot find user cannot find

the next one i'm going to put some

commas in here get dark formatter to do

its job correctly and i'm going to press

command s to save the file and that's

going to format the file for me for

wrong credentials i've called it login

error wrong credentials so context log

next one is authentication error and we

just call it login error author so

context lock author okay so that's that

one as well now at the top of the login

login view we have this little text that

says please log in your account in order

to interact with and create notes

a login view prompt but i wonder what

happened to our title as you can see we

have this my title now that we're in the

login view it is a good time to actually

go and get rid of that okay so i'm going

and i'm going to kill this basically my

title and i suggest that you also go to

the swedish file which is intel sv and

kill this title as well okay so we've

removed that and i'm gonna get rid of

hot restart so that the code generation

kicks in and as you can see in here my

title isn't valid anymore and in this i

mean this title is called now login if

you can look at the documentation in

here you can see in english it just says

so let's remove this constant here from

the prompt as well and we're just going

to say context lock and let's just say

login prompt so i'm going to do a prompt

text field placeholder here enter your

email here we're gonna remove the const

and let's just say context lock

and we're gonna say email placeholder

and we also have an enter your password

here placeholder so let's remove the

cons in here i'm just gonna say context

placeholder okay password field password

text field placeholder that's the full

and we have this uh login in here so

what we need to do is just to change

this text as well so let's remove the

content here i'm just gonna say context

and i forgot my password so i'm going to

say context lock and i believe it's

login view forgot password okay

it's not a constant anymore and put a

comma here it's just good practice to

put comma at the end of your parameters

even if it's just one argument that

you're passing to a function i mean my

reason this is a little bit of a side

though but my reasoning is that any time

in the future anybody anybody wants to

add new parameters to this text widget

then they will have to go and put that

comma in there but if you as a

programmer who wrote this code in the

beginning you put the comma in there

you're kind of like acknowledging the

fact that hey i appreciate your time you

may be wanting to add now you may be

wanting to add new parameters to this

and i've already prepared this for you

so if you don't do this if i want to as

a programmer add new parameters in here

i have to go and say oh well okay comma

commandments go here blah blah

but if you'd added that already i'll

just say enter and then write my

okay great so what we can do now is to

scroll forward here and localize the

rest of these properties and it can't i

can just see here that we have one

property left here which at the moment

says not registered yet registered here

so let's go ahead and remove the const

as we usually do then and say contacts

and i can see it's called not registered

so let's use that and a comma here so we

prepared for the next programmer so to

and we could just say now that we have

successfully localized our login view at

the moment so we could just close this

the next step is to localize our

register view so the register view also

has quite a few things that we have to

localize so let's go ahead and go to

and while we're here i mean this is what

when i started this course i wanted you

to become a software engineer even if

a designer a ux or whatever or project

manager and you have to put yourself and

your yourself in the shoes of a software

developer software developer you're

always in like time constraint usually

our time concern to deliver but at the

when you stumble upon something that is

quickly fixed please do it on

right there uh at that point because if

you leave these things they're gonna

and many small things that could be

corrected on the fly if you just leave

them they're gonna become a big pile and

then you're not gonna be able to have

enough time to fix them all so while

we're here we have two unused imports

let's just remove them because that's

just good practice not to have unused

now let's go to our register view here

we can see there's quite a lot of errors

there are four errors so the first thing

i'm gonna do is to put commas at the end

right there and i'm going to press

command s on macintosh or control s on

windows linux and that's going to do the

the first one is called weak password so

and this message is register error weak

the next one is called context log and

it's called an email already in use okay

fail to register i've called register

here it's register error generic and

this invalid email is called context

lock and register invalid email okay

so those are our errors we didn't have

to change anything with constant because

these messages weren't constant when

then we have to fix this register's

title and it's just called a register so

i'm going to remove the con const

i'm going to say context log register

and then we have enter your email and

password to see your notes and i've

called that the register view prompt

so context lock register view prompt

we have this input declaration again

we've done this before with the email

and password so it's nothing surprising

block email placeholder and this one is

a password placeholder so let's remove

placeholder all right so that's that

then we have the register button that we

localize and let's remove the constant

and already registered is called already

registered so let's remove the constant

and we say context lock already

all right and a comma at the end as well

and we could do the same thing in here

with a comma at the end just to do the

so this seems to be ready we've now

and the next step is to localize the

verify email view so i'm going to close

this file and let's go ahead to verify

and again we have two unused imports

let's remove those and let's go ahead to

verify email in here and we've just

called it verify email so i'm removing

removing const saying context of lock

let's say verify email okay and this is

one thing that i've also fixed and you

could see that in how we've developed

the application so far we have two

texts on top of the verify email view

and they kind of look like this if i

try to log in with a user who hasn't

and you can see we end up here we've

sent you an email verification please

open it to verify your account

and this is like there are two text

fields but what i've done is i've made

it one text prompt so let's just remove

the second text field and the way i've

created this it's um if we go to our

intel en rb and if you look at the

prompt you can see i've written we've

sent you an email verification please

open it to verify your account and then

the rest of the string it just follows

along so it's just one paragraph

and so that's why we're removing the

so and we're gonna remove this const i'm

then we're going to say context lock

we have this a little text button in

here that says send email verification

let's change that as well and here we're

send email verification put a comma here

and for the restart button we have a

restart text so we're just going to say

and a comma at the end all right

so that's the localization of this

screen as well so we could say we're

pretty much done with the verify email

and while we're here to be honest with

you we could also clean up a little bit

here in this verify email while we're

basically cleaning up the view itself

you can see that this text doesn't have

any padding what we could do is to in

maybe pad this text so we're going to

say this text is padded wrap it with a

padding okay and we could just say

you can see now it is a little bit

cleaner it's just a very little uh

effort to make the the ui look a lot

so we're done with that screen and what

we need to do um we need to actually

localize the create update node view so

let's go ahead to create update note

another unused import let's remove that

and let's have a look at what exactly we

localize in here it's probably the the

views title so if we scroll down to

where we're displaying the new note so

if i log in with the user who has

horrible password please don't use that

password at the moment you can see in

we're basically saying um sorry

we're saying new note and that's this

thing so let's just change that and say

dot lock auto import disk oops how to

import this and then we're just going to

and you can see in the documentation it

says it just in the english one says

note so here we're not saying new notes

and the reason behind that is that up

until this point our application is

being say new notes but what happens if

it still says new note so that's the

reason i've decided to basically change

this text just to say note

and put a comma in here to prepare for

and what we're going to do and is also

to change this text decoration and which

is here it says start typing your note

and then in here we call it start typing

your note so context log start typing

so we're going to save that as well

now we're going to go to localizing our

notes view and this is i would say this

is like the most exciting localization

we need to do some more coding it's not

for just two just to because remember in

the beginning of this chapter i

mentioned that arb files are more than

just normal json in that they can have

logic in them and at the moment if we go

let's see if i bring scr cpy here at the

moment you can see it just says your

and i wanted to kind of demonstrate how

arb files can be quite dynamic and can

have logic in them and i thought okay

how do i demonstrate that to you and

land in this page and you have no notes

like in this case at the moment it says

your notes but what we're gonna do is to

say okay we have some some key in our

localization file that is called your

notes okay or sorry it's called notes

is a key but this key is going to have

some value that has actual logic in it

and this logic has to do with the plural

pluralization of this key if you have no

in english we're going to say no notes

if you have one note it's just gonna say

other number of notes such as two three

four then it's going to say

notes for instance x being three notes

four notes so it's just gonna say four

so no notes yet one note or x notes

so it has pluralization built into it

and how we have to do that is to use

something in arb called placeholders and

i'll show you how to do that right now

so let's go ahead first into our

and at the bottom of the screen here

what we're going to do is to first

create our key so that's the most

important one okay so we're going to

and in here we know that we're going to

have some value and let's see we have

also a semi sorry a colon there okay

so we have notes title how do we put our

we need to have some sort of a

your localization arb file doesn't know

anything about the count because it's

the application that knows how many

nodes are available in the in the fire

somehow we need to pass this count to

sorry to our arb file and you do that

with parameterization so you go ahead

and create curly brackets in here and

you would say okay hey i want to have a

parameter called count this count needs

notes title in order for it to be able

to calculate exactly what it has to

saying that hey application if you want

to get the notes title localized string

you have to pass a parameter to me call

now what we're going to do is to go and

call and basically and create discount

as a parameter so what you have to do is

to go to the next line and just say adds

notes title this is how you tell arb

this notes title key has some extra

then there is a key in here called

so you have to write placeholders okay

and in here basically you say

placeholders and then every key is the

name of the parameter itself so account

all right and then you basically start

that and then what you have to do is you

have to define two keys in here one is a

type and then the other one is an

like this so let's have a look at how

basically what we're telling and

arb is that or dart in this case we're

saying that hey this notes title key in

our arab has a parameter called count

and in in here we're saying hey

these are the placeholders the name it's

count and it's type now you have to

define a type you have to actually tell

what data type is this using is it a

string is it's an integer is it a

boolean what is it so in here you just

say it's an integer and then as you'll

see soon the code generation then has a

look at this and says okay i expect you

to send an integer and it's going to

create a function called node's title

with account a parameter of type integer

so this is very important it's the data

type of that count parameter okay

and an example is just for you to know

okay how is this going to be used so an

example is for instance three nodes okay

so we're just going to say here's an

example of how the result of this thing

so what we need to do now is to tell

this um erb and dart code generator here

that this count actually has a logic

about it being plural so it has

pluralization logic and the way to do

that is you put a comma here and you say

plural and a comma after that because

then you have to specify the logic for

as a side note i completely understand

that this is so weird i mean it is a

strange syntax i don't feel comfortable

with it i sometimes use i sometimes look

at the documentation just to be a

logic but the way i look at it is that

it's the best thing we have let's not

hate on it let's just use it let's

understand that it has power there are

reasons for it being the way it is and

in we weren't involved in the reasoning

of this we don't even know what the

reasoning is but this is what the format

is and this is what we have to basically

so the way to create this is for you to

have your logic in here so we're going

and let's just do it like this and then

we're gonna say equal to one and then

so this is how you create it so you're

saying that if the value of this count

then we are going to do something here

if the value of that count is one we're

gonna do something here and if it's

anything else denoted by other we're

gonna do something in here so let's say

when it's equal to zero we're gonna say

notes yet okay so that's the string

we're gonna display if the count is zero

if it's equal to one we're just going to

and then the important thing is if we

end up in this situation if it's other

then we want to say in this case we

actually want to get the count so if you

pass the value of three we want to say

three notes so the way to get that count

is with another curly bracket pair and

you say count and then you say notes

so that's how you create these things so

um and i think we're actually missing a

the the curly bracket at the end yes

this curly bracket which belongs to like

the other has two curly brackets

it's two curly brackets and here

other one curly bracket there one curly

bracket here one ends here and one ends

here so this last curly bracket here is

for the curly bracket that started here

so again i i don't know what to say this

is the format the way it is we just have

to live with it okay so we've created

the notes title and what we're going to

do is to go ahead and do the same thing

but for swedish and i've already

prepared that so i'm just going to go

ahead and grab that string from the

already made so we don't have to type

so let me go and grab that and bring it

sv which is for swedish and then bring

it at the bottom of the screen

and paste it right there and with a

comma at the end of that line so you can

see plural and it says no notes yet

for one it says one note and for other

so i'm gonna save this i'm gonna save

this and i'm gonna do a hot restart

let's just hope that scr cpy doesn't

so what we're gonna do now is i was as

it was planned we're gonna go to our

and i'm gonna go to my notes as well

here let's go to notes view

and have a look at our title in here

and you see we at the moment we're

seeing your notes but what we really

want is to be able to display the number

inside the nodes provider so if we have

a look at how we're reading the num and

the notes you can see we're using the

note service and then we're saying all

of an i triple of cloud nodes so we kind

of wanted stream builder we want a

stream builder to create our title our

app bar and we're going to exactly do

the same thing so we're going to have a

stream builder that creates our app bar

or actually it's going to create the

text but how do we get the count of

the notes and the way to do that is with

a little handy extension that i'm going

to show you how to create so

let's go in here in our notes view and

we're going to say extension and we're

and we want to create it on a stream so

we're going to say any stream has to be

able to like any stream that has an

that its values are iterable

property called length for instance that

let's go in here and say okay this

stream has some value but we want that

okay so here we're basically saying that

we're extending any stream that contains

uh i troubles as its value is gonna have

then we're gonna say okay the value of

and we're going to call it get links

and what this is basically going to do

say it maps the stream's values so let's

and in here we just say it returns the

event's length so i understand this may

be a little bit cryptic for you to

you have to know that every stream

is a generic function like if you sorry

it's a generic class you can see it's

abstract class it's it has a parameter

called t which is it's generic type so

what we're saying here we're saying that

okay we're creating an extension on any

stream whose parameters or whose types

are and i treble and iterable has a

and that means that we can then extend

and extend any stream that has an i

treble and then we return its property

so what we need to do now is to go ahead

and inside the app bar in here

we have a const text when we need to

remove this const first actually let's

see if we can wrap this with a stream

builder now okay so in here what we're

gonna do is we're saying here's a stream

builder and we don't yet know what it is

like this and we have all notes

and the owner user id is our user id

okay as exactly as we have it here

okay but here the stream we don't

actually want the notes we want the

length of notes so let's just say get

where is it here get length okay

and now we know that snapshot can then

return that uh value for us so

if i press command s in here let's put a

you can see nothing has changed it just

says your notes because we're still

seeing your notes in here okay but what

we want is to grab the data out of our

snapshot and this snapshot is an async

let's see undefined class it's called

async snapshots yeah just like that all

so you either could tell a stream

and then your snapshot i believe

as facing snatch out of it or you could

just say stream builder normal stream

builder and an async snapshot of it so

you could type it in two different ways

and i've just chosen to do it this way

what we need to do in here is to see as

soon as snapshot has data then we grab

that data which means it has the length

so we're going to say if snapshot has

data which means it has length

otherwise we're just going to return

const of text nothing meaning that well

well we don't have anything to display

at the top of the screen if this

snapshot has no text all right

and then in here we're going to say it's

going to say final note count

or zero because it just says yeah i may

just strange because you're actually

saying has data but these two properties

they're different from you i mean

they're not different but they're

separated from each other just because

you're checking something has data

doesn't mean necessarily that the next

line should understand that it has data

of this data property is still final t

so you can't change that okay and that's

why we have this um elvis sign kind of

or a question mark question mark just to

say if this doesn't have any value just

now that we have node count we have to

and we oh we don't have log let's import

and remember the key that we used intel

me and it's called notes title let's say

notes title and now all of a sudden you

can see it is a function that takes in

an integer hello that's the count

integer that we built into our arb and

it returns a string you can see here

that's perfect because then we can pass

a text widget with that text in it just

and then we can save this and as you can

see now as soon as i hit command s it

if i say and if i press the plus button

here you can see i can type something in

here and i go back it says onenote

on top of the screen it says two notes

and that's it pretty much that's the

logic that we built into it so now it

says onenote delete that note and it

says no notes yet perfect so that logic

seems to be working fine for us

so that's that part and we also have

another string at the bottom of this

and we have to change this as well so

and this error is because we it says

invalid constant but you're like oh but

this is not a constant well the problem

is a little bit higher up in that when

we created this array of pop-up menu

items we said that is a constant so

so that's fantastic and that is i mean

now we're pretty much done

in the entire application we don't have

anything any string that is hard coded

and if you look at our problems

section there are no problems to fix for

instance no unused imports so we've

taken care of those as well and just to

test this what we could do is just to go

to the settings screen here and i'm

and let's go back to our application

here and have a look and it says no

notes yet i'm going to press the plus

button and i'm going to write some

go back here it says one note

create a new one and it says two notes

delete this one and all the you see all

the dialogues are now in swedish yes

yes let's try to log out now and it says

and it says look go to add a second by

the way look at it are you sure you want

to log out yes log out and you can see

all our strings here basically are also

everything in this screen is also

localized so that's fantastic

were supposed to do and what we promised

to do and that is great congratulations

if you then and do what we usually do at

the end of every chapter we

commit our work so i'm gonna have a look

at this and let's have a look at our

and have a look at our git log as well

i'm gonna change the screen layout a

little bit sorry about that so you see

remove scr cpy make this full screen

make this a lot larger so you see better

and have a look at git log again and you

can see the last one we did git step

sorry step 31 so let's just say git add

great and then we're also going to get

and let's tag it as well get tagged

all our tags we can see 20 blah blah

let's see if we have 31 30 31 and 32

great and then we have to push our tags

what we've done so far is i mean we've

done a lot of work and in this chapter

even more we've localized our

application we looked at how

localization works how code generation

for localization works and also we had a

important extensions that you can create

in order to make your localizations even

work better for flutter and we also had

a look at adding some logic to our arb

congratulations for going through this

chapter i believe personally that is

very important to localize your

applications you're going to reach a lot

more users if you localize your

applications correctly for your

for like your target markets

and um it should help your users also

feel more connected to your application

um with that said i may actually then

hello everyone i can't say welcome to

this chapter now because this is not

really a chapter on its own rather it is

the outro to this course and i don't

know it's a kind of a bittersweet moment

because uh i've had so much fun putting

this course together for you and now i

i don't want to get emotional but it is

kind of sad uh as it is a great moment

appreciation for you having gone through

this course and also i want to really

congratulate you for having gone through

this course and having learned as

as you've learned because it's it's not

an easy thing to do to go through such a

lengthy course but as i mentioned in the

course if you remember in the

introduction i mentioned that um

a lot of videos basically jump over

quite a lot of information and i didn't

want to do that in this course and

that's why this course has become

we've gone through a lot we've talked

flutter development but we've also

got our hands dirty with some

native ios and not really development

but all actually going to xcode and

fiddling around with some properties in

info plus an excel project we've also

had to open android studio to create our

virtual devices we've worked with

figma and design tool we work with app

store connect and google play store

we've gone through a lot so and i want

to congratulate you for sticking

throughout all this with me and

um hopefully you've also learned a lot

now while designing this course i also

knew that it has to be a living material

it can't just be something that i drop

out on the internet so i'm very much

planning to keep everything up to date

but there's lots and lots that i've

more to be added to this course so

i can't really go into details about

what they are i haven't finalized them

but just as i did with this course i

need to plan them correctly write all my

scripts to know what i'm going to talk

about and plan even the code that i need

to write to tell you all about so

just know that there's a lot more to

you can just subscribe to my youtube

channel if you want to keep up to date

things are moving all the time we've

been working with firebase for instance

and firebase in itself is a moving

product so it's an update like ever

it's just always updating so new

versions come out new versions of

flutter might come up come out and new

versions of dart might come out so even

figma for instance that we've been using

a lot the interface might change

since i put so much effort into creating

this course i don't want it to die and

i'm not going to let it die so it's

always going to be updating every now

and then i will be putting

and not only updated content out like

maybe i need to replace some old content

with some new but i'm also planning on

let's just say that this course is gonna

hopefully always be up to date

as i mentioned in the introduction of

this course i have zero dollars

marketing this course and marketing is

probably the wrong word because i don't

actually earn any money by having this

course the only thing i earn is joy of

um like people like you going through

this course and telling me on social

media perhaps about oh hey i did this

course and i learned this and this and

this and i've released my first

since i have um no budget for that i

would really appreciate it if you could

spread the word about it and tell like

if someone asked okay i need a course

uh it would be lovely and i would really

appreciate it if you could just tell

and um i've mentioned this also in the

introduction but i would really

appreciate it if you could follow me on

social media twitter at van.np and also

on linkedin because i produce quite a

and as infographics for instance also

adds videos related to flutter

javascript python django react native

swift you name it so even typescript now

uh i would really appreciate it if you

could follow me on social media

and uh i've been told in some places

that um by some some of you that

maybe some people can actually support

me and if you want to do that this is

the way to do it just going to

coffee.com but remember it is completely

optional it's only if you can afford it

so with all that said i don't want to

drag on this outro i just want to say

again a huge congratulations to you for

going through this course with me and

spending your life during these so many

hours together with me and i've had a

blast recording all these videos and uh

i'm sure this is not a good buy but

rather an official end basically to this

course and keep an eye out for more

content and i'm sure we'll talk to each

Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.