Firebase Authentication in Unity with REST API

Domenico Rotolo
8 min readJul 3, 2019

--

Before we begin…

If you haven’t already, I strongly recommend reading the story below before we start. It shows how to post and retrieve data from Firebase Database (which we will need in this tutorial).

Alright, let’s start!

These are the functionalities that I will show off today:

  • Ability to sign up and sign in with email and password;
  • Confirmation email on sign up;
  • Database protection with rules.

What we’ll be using

Here’s a recap of the external libraries we will use, in case you haven’t had the chance to read the previous article yet:

The AuthHandler Class

Let’s create the AuthHandler Class, which will take care of all of the operations involving Firebase Auth.

The API Key

First of all, we need to store our project’s API Key. This can be found in your Firebase Project’s settings.

This key must be kept secret because anyone that has access to it will be able to create, delete and manage your users. If you somehow mess up and reveal it to the world, DON’T PANIC:

Go here: https://console.cloud.google.com/home/dashboard
Find your project
Click on APIs & Services -> Credentials (on the sidebar)
Delete the key you have exposed
Click on Create credentials -> API key
$$$ PROFIT $$$

Authentication with Email and Password

For this tutorial, we will be using the Email and Password authentication method.

In order to enable it, go to your Firebase Project Console and click on Authentication, on the sidebar -> Sign-in method.

Enable Email/Password:

The SignUp Function

Once called, this function should:

  1. Sign up a new user with Firebase Auth
  2. Upload the user object to Firebase Database
  3. Send the verification email

Sign up a new user

This is the endpoint we need to connect to in order to create a new user:

(you can find a list of all possible Firebase Auth endpoints here)

As you can see, we need to send a POST request to the endpoint, including the user’s email and password. We can do that using the RestClient library:

And that’s it, a new user has signed up successfully with the given email and password pair.

Upload the user object to Firebase Database

Using RestClient’s .Then() function, we can execute some code after the POST request has finished. This way we can get the response payload as a parameter, which we can deserialize using the FullSerializer library.

The response payload contains a bunch of useful info about the user:

  • Local Id (User Id): An identification string, unique for each user
  • Id Token: A key that proves to Firebase you are authenticated as a specific user

We can use the DatabaseHandler class showcased in my last tutorial to post the user (name, surname, age) onto our Firebase Database. We will store our new user in users/localId/, like this:

This is the result:

Send the verification email

This is the endpoint that triggers the verification email:

In this case, we don’t really care about the response, all we need to worry about is the request body payload, in which we need to include the Id Token of the user. Luckily, as stated above, that can be retrieved from the Sign Up response:

This is the email that the user will receive by default:

It can be easily customized in your Firebase Project’s Console in Authentication -> Templates

This is how the AuthHandler class looks so far:

The SignIn Function

Once called, this function should:

  1. Sign in a user with Firebase Auth
  2. Check if the email is verified
  3. If so, download the user object from Firebase Database

Sign in a user with Firebase Auth

Here’s the endpoint that signs in the user:

The response payload will include the Id Token needed to do authenticated requests.

If the given email/password pair is incorrect, the code in the .Then(response => {}) function won’t run. You can use the .Catch(error => {}) function to, well, catch any errors such as wrong credentials or no internet connection.

Check if the email is verified

Let’s create the CheckEmailVerification() method. Firebase stores whether or not the user has clicked on their verification email link in a boolean (emailVerified). You can retrieve it by calling this endpoint, that will get the user’s general info:

Our CheckEmailVerification() function will take as parameters the Id Token (since it is required in the request payload), a callback (a function to be executed if the user has verified the email) and a fallback (a function to be executed if the user has not verified the email).

So far, we have always deserialized our JSON response data as a Dictionary<string, string>, since all of the data we needed to retrieve were strings. In this case, though, the JSON is composed of an array of users, each containing a emailVerified boolean.

Although for this example, the users array will always have a size of 1, since only one account is associated with the Firebase Id Token, in order to deserialize this JSON we will need to create two new objects.

Now, by deserializing our JSON into a UserData object, we will retrieve all the information we really need (the localId and the emailVerified).

All that’s left to do is check if emailVerified is true or false and if it’s the former, store the Id Token and the User Id in two public variables so other classes can have access to them and authenticate their requests.

If the email is verified, download the user object from Firebase Database

As of right now, the CheckEmailVerification() method is never used. Let’s call it in our SignIn function and set the callback() and the fallback().

If the email is verified, all of the user’s information will be downloaded from the Database (as an example)

If the email is not verified, just simply log an error.

Finally, here is how the entire AuthHandler class looks:

We are now 100% done with the Authentication logic… all that is left to do is to protect our Firebase Database.

Database Protection

Let’s go and take a look at our Firebase Database Rules (You can find them in your Firebase Project Console by clicking on Database on the sidebar -> Rules).

Not going to lie, they don’t look that great. Anyone can read and write whatever they want on your Database! We have to stop them…

These rules, on the other hand, are a good compromise:

Read permissions
Anyone
that is signed in (auth.uid !== null) will be able to read the users branch of the Database (Example: You need to be authenticated in order to scroll through other people’s social network profiles).

Write Permissions
Users, if authenticated, will be able to write only inside the branch users, only inside the subbranch which name is equal to their userId ($uid === auth.uid) (Example: You need to be authenticated and be the owner of your social network profile in order to change it).

Furthermore, if you want to learn about Firebase Rules, you might find this interesting.

Let’s update our DatabaseHandler

Due to the changes we have done to the rules, our precedently made (in our previous tutorial) functions to upload and download data from the Database no longer work (PostUser, GetUser, GetUsers).

This is because, along with the POST/GET request, we have to give Firebase the Id Token so that it understands we are authenticated.

Once we have applied all the changes, this is how the DatabaseHandler class looks:

In particular, we have used the PostUser function in SignUp() to upload the User Object to Firebase Database and the GetUser function in SignIn() to retrieve and log the User Object. Let’s update both method calls so they will execute correctly:

We are done! It’s time to test…

The code inside the OnAppStart() function will run, well, when the application starts. So when we run our app, it will SignUp and SignIn a user.

Let’s run our application
If we go to the Firebase Project’s Console, in Authentication, we can see our user has successfully signed up:

The user object has been also uploaded to Firebase Database:

Finally, the user has also received a verification email.

Unfortunately, the SignIn() function got called too soon, so it simply didn’t work because it didn’t find any users matching the email and password given.

Let’s run the application again:

This time the SignUp() function simply didn’t work, since it already found a user Signed Up with the same email (It returned a 400 Bad Request error code).

The SignIn() function, on the other hand, has successfully been triggered, but the user is yet to verify their email, therefore, they are still not authenticated.

I will click on the verification link in the email I have just received and run the app one more time:

Awesome, it worked!
You can check out all of the code shown in this tutorial on GitHub.

Finally, if you are looking for more content regarding Unity Firebase tutorials, you can take a look at my playlist Firebase Unity Tutorials on my Youtube channel.

--

--

Domenico Rotolo

I am Unity game-maker! Big fan of open source and games!