Hey hey everybody what's going on this is Caleb with Devon Lopes dotcom.
And in this video we're going to set up our authentication service which includes two very critical
functions register user and log in user.
These both are going to be what allow us to actually authenticate users add users to our app and also
it's going to allow us to check to see whether they're logged in or not which is going to be really
important for just monitoring just the authentication status of our app.
All right.
So go ahead and pull open that X code project and we're going to go ahead and create a new file in our
services group called Auth. service.
Right click on services click new file.
And what we're going to do is create a new Swift file doesn't need to subclass anything but we're going
to go ahead and call this auth service.
And this is of course just like the data service going to be a singleton class where we're going to
instantiate an instance of this class inside itself which gives us access to it throughout the entire
life cycle of our app from any class.
It's very cool and very helpful.
But we're also being careful not to abuse the singleton pattern because it's very easy to do that and
we don't want to do that because we want to use this how we need it and that's all.
So let's go ahead and let's begin actually by importing firebase because we're going to need that to
authenticate users.
And I don't want to forget.
So let's go ahead create the class and call it author service then we're going to create a static constant
called instance.
And the reason we're creating a static instance is because it allows the static variable to be alive
for the entire life cycle of the app so as long as the app is running you have access to that instance
of this class.
So go ahead and type static let instance equals auth service put parentheses at the end to instantiate
it.
And we're going to create two functions like I said one is phunk register user.
The other is phunk log in user code and are apps going to be pretty interesting because if a user has
not yet registered they're going to be able to put in their email and password and click sign in if
they're not registered it will register them then log them in if they are registered it will just log
them in.
It's pretty cool.
Kind of adds to the user experience it makes it very simple to get into our app and start using it.
Now there are some important things that we actually need to know and actually need to do in order to
register a user successfully.
Now what we need.
We need their e-mail.
We need their password.
And we also need to know when registration is done.
Because like I said when it's done we should be able to call our log in function to log them in automatically.
So go ahead and we're going to type with e-mail.
So register user with e-mail or use an internal parameter here called e-mail.
Next I'm going to say and password internal parameter called password that's just something I like to
do because if I was to just say and password I would have to use that and password name in here.
But really I'm just talking about the password not an and password or with e-mail.
So internal parameters are kind of cool because they let you set the actual name of what your what kind
of information you're dealing with.
So registry user with email and password.
And we're going to go ahead and also create a completion handler using an escaping closure.
So go ahead and type user creation complete and that's going to be escaping Like I said so that values
can be taken out like in this case we want to be able to send an error to an air handler just in case
there's a problem and we're going to create a function here and we're going to return an empty function
K that means we're returning nothing because we don't need to.
But we do need to pass values out.
So in order to do that we're going to do underscore status is of type bool meaning.
Is it complete or is it not complete then we're going to go ahead and we're going to return or pass
an error if there is one.
But sometimes there's not.
So we're going to set error to actually be optional meaning we can pass nil here and it's OK it's not
going to crash our app because it can except nil.
So very cool once or user creation is complete.
We're going to pass.
True.
If there's an error and it's not we're going to pass false if we get an error from our account creation
like maybe it notices it's not a real email there's no sign there's no dot com dot org we'll send an
error through and we'll print that.
OK.
So that's our function for registry user logon user is actually going to be basically identical because
to log in a user We need an e-mail we need a password and we need to know when it's done.
So I'm going to actually copy this.
I'm being a bad coder but I'm going to paste it in and instead of saying user creation complete Let's
just say log in complete.
OK.
Very cool.
And we'll come back to log in user in a second.
But for now let's go into registry user and let's think about what we need to do.
We need to pass in the e-mail and password and we need to use firebase in order to actually register
a user into our database.
So to do that we're going to use some of the nice built in functions from firebase.
So go ahead and type off dot off and there's a function in here called create user with e-mail password
and it has a completion handler which is pretty cool.
So let's go ahead and let's give it the e-mail that we passed and from our function give it the password
that we passed in from our password.
And for the result callback press enter and you'll see there are two things.
Given user and error go ahead and name them user and error.
And those are the things that are passed back.
So as you can see they're optional meaning sometimes there might not be a user if there's not then it'll
probably throw an error saying this user doesn't exist.
So let's just call it user and error as constants to hold those values.
Now what we need to do is if a user is returned we're going to create a constant to hold all of the
information for that user.
If there is not a user We're going to basically handle any errors that come back.
So we're going to use guard less so that we can safely create a user if there is one returned.
But if there's not then we're going to handle the error.
So go ahead and type guard let user equals user WIPs user.
That means if a user is returned we will do that else.
And I'm actually going to go ahead and inside the brackets here I'm going to handle the error.
So go ahead and type user creation complete.
And this is where we can pass in false.
The user was not created and the error is going to be the error.
We're going to pass the error back to our handlers.
We can use it later on.
That's pretty cool.
Now what we're going to do is we're going to just leave it at that.
And that is what we will do if there is an error.
We're going to say false the user creation was not complete and there was an error.
But what if there was no error.
We get through we have a value in user.
We should create an account for that user so if you remember in our data service let's call data service
instance dot create DB user We need a unique ID.
We need a unique ID and a user dictionary.
That's where all the data gets passed to firebase.
So in order to actually pass that we need to create a user data dictionary.
So let's go ahead and do that by typing.
Let user data.
And that's going to be equal to a dictionary.
And for the first key value pair We're going to go ahead and just call provider now.
If you dive deeply into firebase you will see there are different providers.
One is Facebook.
One is Google one is firebase one is e-mail.
Now we're going to be creating an email user so our firebase provider is just going to be pulled from
user K assuming the user comes through.
And if you put a period there you can see that there is a provider I.D. and that's the information that
comes through to us a provider I.D. can be firebase.
Email Facebook Google et cetera.
Next we're going to go ahead and we're going to send up the e-mail from the user.
So let's give it a key of e-mail and the value is going to be user e-mail.
OK.
If there's a user We're going to get its e-mail and that's awesome.
We now have a dictionary of user data.
Very very cool.
Now to create the database user we need to pass a unique ID but you know what the cool thing is it already
has one.
Let's go ahead and type user you I.D. the user already has a unique ID that it's given.
So that's really easy.
We don't have to generate it.
We don't have to write a function that can generate a random number that's different than all the other
numbers.
We can just pull the ID from firebase so so helpful for user data of course we just created that dictionary
so let's pass it user data and you know what when we call this if everything is here that means that
our user will actually be sent up to firebase will have a user in our database.
Very very cool.
So what we do need to do actually sorry is we need to return.
And that's part of guard led.
I forgot about that.
If if there is a problem.
OK.
We will pass false to our completion handler will handle the error and then we're going to go ahead
and return out of it.
OK.
But if it works then we'll have a value.
We can create this dictionary create the database user then at the end we can go ahead and call user
completion or use your creation complete and we can pass in true and we can pass in nil because there
will be no errors.
Very very cool.
So that's how we're going to register a user We're going to pass up the data to firebase If an email
and password come in.
And if there is a problem right.
If maybe it's not a real e-mail or maybe if the password is not enough characters which will set that
up later it will pass us an error.
All right.
Very cool.
Next up let's go ahead and let's log in the user and we're going to do it pretty much the same way just
with a different function from firebase So go ahead and call off.
Off.
Log in user sign in with e-mail.
You'll see it down there it's like the fifth option.
Very cool.
And for the e-mail of course we'll pass an email for the password will pass in the password.
OK remember email and password from our function and the completion press Enter just like above if we
attempt to sign in.
We should get a user back if we have a problem.
If we have a problem we'll get an error back.
Simple as that.
And what we're going to do is we're going to handle what happens if we get a user.
So go ahead and type garb let.
Just like above user equals user.
Else if we don't.
Right.
If there if we don't get a successful user back go ahead and call log in completion or log in complete
is false we didn't log in and we had an error and we're going to pass it that error that we get from
our closure here.
OK.
That's pretty cool.
Now of course at the end we need to return.
We just need to get out of this function if we don't successfully get a user.
So if we do get a value back for user all we need to do is just type log incomplete and go ahead and
give it a true for its boolean and for the error we can just say nil because there was no problem.
Very very cool and sign in will happen on its own when it's done you'll know that it has been successfully
authenticated.
We have successfully logged in and this is it guys we have now set up the functions to register a user
and to log in a user.
Pretty pretty cool.
In the next video we're going to actually set up so that our log in Visi is presented from our app delegate
that will be monitoring our authentication status.
And as soon as we log out it's going to present that log in B.C. automatically for us.
We're going to also set up how we can present off AVC from the log in VC.
And we're also going to set up Visi so that we can log in with our e-mail.
That's super super cool.
We're going to actually allow it to authenticate us and log into firebase So we'll see in the next video.
Awesome job with this one.
Let's head over there.