Now as I mentioned, Firebase has authentication built-in,
wWe just need to go to the authentication area there and then click on setup sign in method and there
choose password and email or e-mail password here. Enable this and click save
and with that, we have it enabled.
Now we can send requests to a Firebase API to create users or to log them in. Now in order to find
out where to send the requests,
you can google for Firebase REST Auth API and you will find these official docs where you'll learn
how to create and sign in users with their API.
Now there are a bunch of endpoints for different things, here in this app we'll focus on signing up and
signing in.
So if we click on sign up with e-mail and password, we learned how that works.
We need to send a HTTP request, a post request with this content type to this URL, enter our own
API key here which I'll show you where you get it from in a second and attach this body to the request,
so e-mail password and then this return secure token field which should basically always be true. As
a response, we'll get back a token, that's that token I mentioned on the slide, the email we used,
a refresh token which is more advanced,
this token here will expire actually after this amount of seconds which we also get back. With a refresh
token, we could recreate it, revalidate it
without having the user to login again, we'll not do that here,
you would have a separate endpoint to which you send the refresh token to get a new ID token,
we'll keep it simple here and just use that token and log the user in again after that expiry time because
that expiry time is also something we get
so that we know when this token will become invalid and can't be used anymore because we'll have to clean
it up in our app by then, so that we don't try attaching this invalid token to future requests to our
database and localId, that's the userId of the user which Firebase created on its servers because
we do not have to do any of that user management, Firebase will do that, we don't need to write any server-side
code.
So what we need to do is send a HTTP request
and since I also will manage this all with Redux, I will create a new action creator for this and I'll
name it auth.
I will also already create a reducer because we will also manage some auth related stuff there, for example
the token and the userId.
Let's start with the action though and let's
hence export an action creator here which could be named sign up,
makes sense to start with that because logging users in will only be possible after we created at least
one user. So here in sign up,
I want to be able to create a new user and for that, we'll need an email and a password
so that should be passed to the sign up action creator from outside.
Now then, this will send a HTTP request and in order to be able to do that, we'll use the Redux Thunk
package again and therefore return async dispatch here,
so we return a function which can use async await which gets that that dispatch function as an argument
passed in by the Redux Thunk middleware we started using in the last HTTP module of this course and
this allows us to run async code before we then dispatch an action that actually reaches our store.
Now for that, we'll also need an action identifier for that action which we later want to handle in our
store and there I'll just use sign up, which also has sign up as a string identifier.
So here in the end, we'll then dispatch this action object where the type is sign up and where we will
probably then also add some extra data but before we do that, we need to send a HTTP request.
Now that can be done with the fetch API as you learned in the last module and definitely go through
that module first
therefore and this is the URL we need to send the request to, so we can copy that. Add it here and
now we have that API key thing.
Now that's something we can get from Firebase by clicking on the gear
icon here, project settings. There
you'll find the web API key and that's exactly what you need,
copy that and replace API key including the square brackets with that key.
This is the URL we will need to send a request to. Now as the official docs tell us, we need to send a post
request,
so as you learned, we need to add this second argument here to fetch
which is an object which allows us to configure that request and there, we can set the method to post
and also add some headers because we'll need to add the application JSON header, so the content type
header which should have a value of application JSON and we'll need to add a body and that body needs
to be in JSON format which we can get with JSON.stringify and the data I want to stringify needs to
be an object with these three keys - email, password and return secure token. So here of course, email refers
to the email we're getting as an argument here, the same for password which refers to the password argument
we're getting and then it's this third and I'll just copy it to not mistype it,
return secure token argument here or key-value pair where the value should just be true. This request
should create a new user.
Now we can wait for its response with the await keyword and then as you learned earlier, we can check
if the response is not okay, if that's the case, I want to throw a new error where I say something went
wrong and we'll have a look at more detailed error handling later, for now that's it and if it is okay
however, I want to get my response data by awaiting for response JSON which will unpack the response
body and automatically transform it from JSON format to Javascript, so to a Javascript object or array
and now we will be able to work with that and for the moment, I'll simply log this response data here.
Now we haven't added the rest of our auth related Redux store, we'll do that later but we have something
that should work, we should be able to dispatch this and therefore send such a sign up request.
So now we can go back to the auth screen and there in the end when we click this login button which
is incorrectly labeled login at the moment when we actually do sign up but let's leave it like this
for the moment,
so when we click this button I want to send this sign up request. So for that, we need to, as before, import
use dispatch from React Redux so that we can dispatch actions
and of course, import everything as auth actions from the store folder data, from the actions folder and
there from the auth file
and with that added, we can add a function here,
either an inline function or like this, a named function stored in a constant
which I'll name sign up
handler, there
I expect no arguments and there I then want to dispatch,
so we need to get access to that dispatch function by executing use dispatch and
then here we can dispatch
this auth actions sign up event or sign up
action.
Now the problem is this requires the email and the password
and right now I'm not storing this.
I get this in my input but here on input change, I'm not storing that data which I of course should.
Now we can have a look at our other form here to see how we did that.
So in the edit product screen, we of course have our form reducer here which manages our entire form related
validity and the values.
So in the end, we can copy that and add it to the auth screen outside of the auth screen component like this
and go back to the edit product screen to then also grab the part down there where we initialize that
with use reducer,
so copy all of this and add it to the auth screen as well,
now inside of the component, maybe here and for that to work, we also need to import use reducer from
React
and with that imported, now we just need to tweak it a little bit. This form reducer is fine
and by the way you could outsource this into a separate file because we're using the same type of reducer
in both the auth screen and the edit product screen,
you could even create a custom hook if you know how that works,
for now I'll just leave it like this.
One thing I need though is the form input update,
let me grab that from the edit product screen as well,
this constant here,
let's move that in auth screen as well.
So now with that,
that's all fine but down there where I call use reducer and initialize this all, that of course looks
differently.
We should have an email which initially is empty and a password which initially is empty and for the
validity, it's the same,
we just have an email which initially is not valid and we have a password which initially is
not valid and the overall form therefore also initially is not valid.
Now dispatch form state should be triggered whenever our input changes here,
so here in on input change, of course you know and you can see it in the edit product screen,
we get three values - we get the input identifier, the input value and the input validity.
So in the end we can just copy this here from edit product screen and move it to the auth screen and
replace this anonymous function with it or actually store this in a new variable here,
input change handler which now holds this function. Now just as in the edit product screen, you
should grab this with use callback to make sure that this doesn't rerender when it shouldn't.
So actually, we should grab it here including the use callback call and the dependencies of use callback,
so this is actually what should be used down there on the input change handler.
Now this input change handler can be bound or can be set here to the on input change props so that
these props target this function
and now with that, we're storing our form values or our input values in our form state which we handled
with use reducer and so on.
So now it's this form state I'm interested in here in my sign up handler because there to sign up,
I need to pass from state input values.email and form state input values.password,
so these two values which were gathered and now the sign up handler here, this function can be bound to
this button down there, to the login button here in onPress because this is the function I want to point at
to execute it when we press this button.
Let's see whether that works as it should. If I start entering values here,
I do get my validation errors but somehow they're not showing up,
that's the case because it's not error message here but error text on the inputs in the auth screen.
So if we change that error message to error text,
now if we test this, so if I click in here, tap out of there, I get my warnings.
Now if I enter a valid e-mail address, this is gone,
if I enter a password that's long enough, that's gone, if I now click login here, let's see whether that
works.
Let's go to Firebase, to authentication and there, you now should see a new user,
this is the user which just was created.
So signing up works,
now let's make sure we can also switch to login mode and make that work as well.
By the way, also note that this here is the data we got back,
so that's the response,
this object with email,
how long
the token is valid in seconds,
then the token itself which is this long cryptic string, then also the ID of the user which was
created and that refresh token.