How To: Simple Firebase REST API server authentication using Ruby

Published 02 December 2016 under software, firebase, real-time database, rubyonrails

Firebase is a set of tools and infrastructure which includes a real-time database. We recently needed to get a Ruby on Rails application talking to a Firebase real-time database over their REST API. Unfortunately, the documentation is somewhat scarce on how to do get authentication to work without using the deprecated auth parameter. The new way seems to be to send an access_token parameter or Authorization header as part of the request to the API. We are generating the access token using the following:

require 'jwt'  

credentials = JSON.parse("credentials.json"))
private_key = credentials["private_key"]

def generate_jwt_assertion
  now_seconds =
  payload = {:iss => credentials["client_email"],
             :aud => credentials["token_uri"],
             :iat => now_seconds,
             :exp => now_seconds+(60*60), # Maximum expiration time is one hour
             :scope => ''
  JWT.encode payload, private_key, "RS256"

def generate_access_token
  uri = URI.parse(credentials["token_uri"])
  https =, uri.port)
  https.use_ssl = true
  req =
  req['Cache-Control'] = "no-store"
    grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
    assertion: generate_jwt_assertion

  resp = JSON.parse(https.request(req).body)

credentials.json is the file we got from Project settings -> Service Accounts, GENERATE NEW PRIVATE KEY. It's also worth noting we're using the ruby jwt gem to generate the JSON web token for the assertion. This can be installed using gem install jwt.

The result from generate_access_token can then be passed either as a header or a GET parameter in our request to the API. For example, using the Authorization header in a POST request:

  def post(path, data)
    uri = URI.parse("https://#{credentials["project_id"]}{path}.json")
    https =, uri.port)
    https.use_ssl = true
    req =
    req["Authorization"] = "Bearer #{Firebase.get_access_token}"
    req.body = data.to_json
    return https.request(req)




blog comments powered by Disqus