Let's start with managing the loading state here on the auth screen because obviously I want to give
the user some feedback when we're currently waiting for a response.
For this, we can import the activity indicator which you already know and manage the loading state here
by adding another state here, isLoading and set isLoading which we initialize to false because initially
we aren't loading and now here when we are in this auth handler, I can add async here because of course
sign up here returns a promise, the same for login,
so these actions creator functions return promises. So we can await for the result of dispatch which
ultimately uses these promises which we get and basically kicks off this entire process
and before we await this, I can set isLoading to true,
so when we start this whole process, before we sent a request and thereafter set isLoading to false
once we're done with this request, no matter if it failed or not.
And now isLoading can be used to display a loading spinner,
it's up to you where you display this, for example you could say that you want to replace this sign up
button with the loading spinner.
So here we could say if isLoading is true,
I want to show the activity indicator like that,
otherwise I'll show the button,
so this is the syntax we could use,
set the size here to small and the color to Colors.primary let's say. Now if we give
that a try and we go back, here on iOS if I try logging in, indeed I see the loading spinner and then
I'm back,
so that works, now for the error handling. For the error handling, you also learn how that works.
You can of course manage your error state here as well,
you could again also use use reducer to merge loading and error state into one object but I'll do
it like this,
error and set error with the help of use state which initially doesn't assign a value so that this is
undefined initially and then here, we can wrap try catch around this dispatching here where we get a
potential error and set our error to this
error message we're getting back and before we send the request, I also want to set my error back
to null. So now we're storing a potential error here in set error
and I just want to throw an alert, show an alert to the user if we get an error.
So for this you need to make sure that you import alert from React Native and also use effect from react
because use effect allows us react to changes in the error state and show the error alert if we have
an error. So maybe here after setting up the reducer, we can add use effect and my dependency here is
the error state variable or constant and if we have an error,
so if this is true-ish, then I want to show an alert with the alert API where I say an error occurred
and my message is the error which should be a string and I will add a button where I have a text of
OK and of course you could add more buttons where you do different things.
Now we can simulate this in the action creator by going there and for logging in, let's say we remove
that D here, so that this is an incorrect URL in the end. If we now try logging in here,
I get this error.
Now that's good
but there also are other kind of errors which I want to handle, for example what if I login with an
e-mail address that doesn't exist? Of course I want to show an error to the user too and I do but
I only show something went wrong which is not exactly the error I would like to show.
Now I'm showing this error because in the action creator here, if the response is not OK, I throw something
went wrong.
Now the problem is when we send an incorrect e-mail or an incorrect password, also by the way for signing
up if we send something which isn't an email or a password which is too short, if that happens, then
we'll get back a response with a status code of 400 something and we get some error details as part
of the response
and right now with our error handling, we don't see those,
so we need to change this. Instead of immediately throwing an error here
if the response is not okay, I still want to look into it.
So I will have my error response data which I get by awaiting for response
JSON here. So I do the same as in the success case but I extract it into a different field and now
here I want to console log the error response data
so that we get a feeling for how this looks like.
So now let's try entering an e-mail address which doesn't exist again and now we get our strange error
which you just saw but now we have this interesting output here and you see this is the error object
Firebase returned to me
and of course it depends on the API you're talking to,
which kind of error you're getting and when you're getting it and what details it includes. This as you
see is an object which has an error key which is yet another object which has an error code, some details
about the errors and then this message which is for example email not found and that's the part I'm
interested. In the official docs by the way, you'll find more potential error identifiers
you could be getting. So in the end,
that's what I want to check now. I want to get my error ID let's say from the error response data by
accessing the error field there which is this field which gives me access to this object which then
has this message field.
So therefore here, I then access message to get this message and now we can check this, we can check if
error ID is equal to email not found. If that's the case, I want to set my own customized message,
so here I'll add a variable message which is just something went wrong by default
but then here if we know the problem is that we didn't find an e-mail address, we could say this email
could not be found and I'll add more if checks in a second.
So this is something I want to check here and in the end therefore, I have a message which I now want
to throw,
so now I will throw a new error with my own customized message though. So another check
I want to add with an else/if statement here is whether the error ID is for signing in invalid password
let's say. So I can check for that and set the message equal to this password is not valid and now let's
give this another try.
Let's go back and enter an e-mail address which doesn't exist, quick login and we get this e-mail address
could not be found or this e-mail could not be found.
Now let's try a valid e-mail address but actually a password which is invalid, like this and we get this
password is not valid,
so now we give the user a better feedback.
Now let's implement the same for signing up, so I'll copy that and go to my sign up case here and there
I just have different error codes, there
I have codes like email exists,
if that e-mail address exists already.
So I extract my error ID in the same way but then I check for email exists and if this is the error, I say this email
exists already.
Now this is actually the only thing I want to check here,
there are other errors too which you could get and you can for example simply turn off your validation
here and see which error you're getting if you're sending an invalid e-mail address by logging that error
ID and then you can check for that too,
here I'll just implement this message and therefore now if I try signing up here with an e-mail address
which I already did use, like this, I get this e-mail exists already. On the other hand if I use a valid
e-mail address of course, this just goes through and on Firebase then indeed, if you go to authentication
and refresh this, you will see that second user.
So this is how you can add a loading spinner and error handling with authentication.
That's all nice but now it would finally be nice to also leave that screen and go to our app and then
start working with that token which we're getting.