Using Firebase API for authentication

To start things off this blog will mainly cover setting up the Firebase API for authentication and not setting up an actual project in firebase.

To kick things off this blog assumes you already created a project in firebase and enabled authentication. For this project we are using authentication with password and email.

The first thing you will want to do is find the api-key in your firebase project and create a variable called API_KEY in your .env file. Once, that is completed we can move on and begin talking about creating a user using the firebase API.

Something to note is that for my project and my auth, I am using a react frontend and a rails API as my back end.

To begin creating a user, let's begin creating a class function in our users model which will look something like this.

def self.create_user(email, password)
end

Great, now that we have our function defined, we can now add the code to call the api. In order to do requests to the firebase API, I recommend installing the HTTParty gem (bundle install 'httparty'). Once we have that installed we can now use that to call a post request to the url that is required via the documentation. Our function should now look like this...

def self.create_user(email, password)
resp = HTTParty.post("https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=#{ENV['API_KEY']}",
        :body => {
            email: email,
            password: password
            }.to_json,
        :headers => {'Content-Type' => 'application/json'}
        )

        if resp.key?('idToken')
            User.create(email: resp["email"], uid: resp["localId"])
            return {message: 'Success', token: resp['idToken']}
        else
            return {message: resp["error"]["errors"][0]}
        end
end

Here we are creating a local variable called resp (short for response) and using the .post to send a post request to "https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=#{ENV['API_KEY']}". Make sure to set the key to the api key you defined in your .env file earlier. We then need to pass in a hash that includes the payload or the data we want to pass to the API which is done in the body key. Make sure to put .to_json at the end of the body to convert it to json. We then also need to set our headers 'Content-Type' to 'application/json' to tell the api that we are sending data in the json format. Once we call this method and pass in valid data, if it works, the firebase API should return a successful response which I am handling with the conditional at the bottom which is specific to my project but you can in reality handle that however you want. Ta-da! We now have a function that connects to the firebase API to create a user! In my application, I am calling it in my users create action and grabbing the email and password from my react frontend which can be found in the params.

Now that we know how to create users, how can we sign in via the firebase API? Well, it's actually very similar to how we created a user. In my backend I created a sessions controller and in my create action I am doing a post request to the API passing the email and password. My create action looks like this.

def create
        resp = HTTParty.post("https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=#{ENV['API_KEY']}",
        :body => {
            email: user_params['email'],
            password: user_params['password'],
            returnSecureToken: true
        }.to_json,
        :headers => {'Content-Type' => 'application/json'}    
        )

        if resp.key?("idToken")
            render json: {message: "Successfully logged in!", token: resp['idToken'], localId: resp['localId']}
        else
            render json: {message: "Error logging in!", error: resp["error"]}
        end
    end

As you can see the format is very similar to how we created a user. Somethings to notice however, is that when you successfully sign in the API will then send back a token. You have to enable this token by adding "returnSecureToken: true" to our body in the hash we are sending to the API. Another thing to note is the url that we are sending the post request is slightly different to the one for creating a user.

Since my backend isn't handling sessions, there is no need to have a sign out function. I am handling the signed in and signed out functionality in my frontend by using the token that this function returns. And thats it! You know have basic authentication using the firebase auth API.

29