Take control of your backend with Firebase Cloud Functions

Luis G. Valle
6 min readAug 8, 2017

As a software engineer building Android apps, I inevitably run into problems with server API’s not designed with mobile clients in mind. In this post I’ll explain how we can use Firebase Cloud Functions to clean up and transform those API’s responses before they reach our app.

Backend API responses that are hard to work on mobile apps usually happen in two types of companies:

  • Startups: not enough people to deal with everything, so they need to compromise. If the same person is doing backend, frontend, devops, sysadmin and this month’s hipster beer order, then they are probably too busy to care about your concerns on the server API responses.
  • Large corporations: in this case there’s enough people. In fact, there’s too many people. Nobody knows who’s responsible for making the changes you need, and by the time details are ironed out, budgets are approved, tickets are created, hands shaken, permissions granted and goats sacrificed you are already shipping version 3.0 of the app.

This is why I love Firebase: it’s the bicycle of mobile apps developers. It gives you freedom and autonomy with almost no investment. And you can get it up and running even if you know nothing about servers, lambdas, node.js or hosting.

Take control of your backend API

What is the worst thing you’ve ever found on a server API? I can think of a bunch:

  • Same field type could contain numbers, strings, or arrays
  • API will ignore basic HTTP response codes and return 200 OK for errors, putting the error code in the body of the response
    …which of course has a totally different schema from the content of normal responses
  • Multiple fields with the same name instead of arrays
  • Responses with no fixed schema, which require manual parsing
  • Different response schemas for the same endpoint, depending on parameters
  • Mixed return formats from different endpoints (some XML, some JSON, etc)

Wouldn’t be great if you could fix all those problems before they even reach your app? It’s not only convenient but more efficient; mainly for two reasons:

  • Not wasting time and power on massaging awkward responses into something you can work with
  • No need to duplicate the response manipulation logic on several platforms

The example: a news app

Let’s define a practical case for this example. We want to build a news app that reads an edition feed from a company’s backend. Now imagine there are a series of problems with that feed:

  1. The structure is heavily nested, with lots of unnecessary data
  2. The feed is messy and contains different elements identified with the same key, instead of using arrays
  3. The response is not JSON
fuck

Parsing this is not a pleasant job on Android. If you use Retrofit you’ll need a separate converter, lot of Java classes to act as Server API models for the unnecessary received data and helper classes to transform that Server models into your tidied up Domain models.

HTTP Triggers to the rescue

Firebase HTTP triggers let you trigger a function through an HTTP request. We’ll use them to proxy our backend. Instead of calling the problematic API directly, we’ll call our HTTP trigger endpoint, that will execute a function to fetch today’s news edition from the backend, clean it up and return it as beautiful small JSON.
Have in mind Cloud Functions have a limited time of 540 seconds to run before they are forcibly terminated, so we need to keep them small.

1. Define a function to be triggered through HTTP

That’s it. When deployed to your Firebase project this will generate a URL you can call using an HTTP request.

Cloud Function ‘fetch’ deployed on Firebase

Our mobile app network requests will go through this URL, the code in the function’s body will get executed, fetching, cleaning and returning the data in the format we need.

2. Fetch raw backend data

We need a little bit more code for this. We also need to make sure your Firebase project has billing enabled.

We just wanna make the world dance

It is necessary to do external HTTP requests and since our backend lives outside Google’s servers we need to switch to the Blaze plan, which is surprisingly cheap. The first 2,000.000 function executions a month are free and, to put it on perspective, I only did 68 while developing this project. After that you pay $0.40/million requests. At that price point, it’s a cost I am happy to underwrite to save us the pain of dealing with problematic and inconsistent APIs..

The other thing we need is a REST client to call our backend. I like node rest client because it’s super simple to use and comes with beautiful features out of the box, like converting XML to JSON automatically.

2.1 Adding a REST client

This snippet is already doing a lot: we haven’t written much, but this code fetches our backend XML edition feed and returns it as JSON with minimum effort from us.

You could leave this example as it is and you would already be saving yourself from converting XML to JSON in the app.

2.2 Cleaning up raw data

At this point all the heavy work of cleaning up is extracted into a `cleanUp` function, that takes the raw data we get from the backend and extracts only the bits we are interested in.
This is the function you’ll need to change for your particular case. In this sample we are going to use the format returned by The Guardian public RSS feed as an example of a convoluted raw backend response.

So let’s imagine your backend returns something like this:

Raw backend response in XML format

Let’s say we are only interested in building a list of items with a few of those properties, like title, description, pubDate, creator and what seems to be a list of media.
Our target will be to produce a JSON response like this:

This is something really easy to achieve in JS:

Putting it all together: all the code you need for the clean up Firebase Cloud Function

This is all you need to use a Firebase HTTP trigger as clean up proxy for a mobile unfriendly API.

Full cloud function code for this example

Stay tuned!

This is the first post in a new series. In the next article we’ll learn about using Firebase Database as an intermediate cache for all this data, so you can save the result and only request fresh data from the backend after a set period of time.

I’d love to hear your thoughts on this, please do reach me at @lgvalle

Special thanks and ❤️ to Rui Teixeira for making my JS make sense, to Sebastiano Poggi for making my English make sense and to nnnneeeiil, @blundell, @niamh__power and Andrei Catinean for their reviews & suggestions.

--

--