Turn Firebase Firestore Data into a simple REST API

Recently, we shipped two new policies that make it easy to use Zuplo to utilize Firebase services. The first policy Upstream Firebase Admin Auth authorizes requests using a Firebase Admin Token that can be used to call any Firebase API. The second policy, Upstream Firebase User Auth authorizes requests as a specific user which allows securing Firebase resources using security rules.

It's common for multi-tenant systems to share the same database with many users. With Firestore, there are several ways to do this - one is create security rules that grant users access to certain collections, documents, etc., the other is to put another system in front of Firestore to gate access to data. In this walkthrough you will learn how to use Zuplo to expose data stored in Firebase securely without utilizing Firebase's security rules. This can be useful if you don't want to tie your system to Firebase rules or maybe you just need additional flexibility.

This post walks through the steps, but if you'd prefer you can also watch the demo video.

1/ Firestore Collection#

For this walkthrough, we'll assume your Firebase database has a collection called products with at least one document.

Firestore Collection

2/ Create a Zuplo Route#

In the Zuplo Portal, create a route in Zuplo that uses a URL Rewrite handler to map the incoming request to Firestore's REST API. In this case set the Route's url to /products/{id} and the rewrite value to the value below. Replace YOUR_PROJECT_ID with your Firebase project ID.

https://firestore.googleapis.com/v1/projects/YOUR_PROJECT_ID/databases/(default)/documents/products/${params.id}

Products Route

3/ Firebase Authentication Policy#

Next, to give the request access to call the Firestore REST API, add the Upstream Firebase Admin Auth policy. Notice the environment variable named SERVICE_ACCOUNT_JSON. We'll set this variable in the next step.

Add Policy

4/ Environment Variable#

Next, set the SERVICE_ACCOUNT_JSON environment variable as a secret. To get the value of the private key, navigate to Firebase Project Settings, select the Service Accounts tab and then generate and download a private key.

CAUTION: The value of the private key is a JSON file. Before you save the file to Zuplo's environment variables, you must remove all line breaks and all instances of the \n escape character. The JSON file should be a single line.

Environment Variable

5/ Test the Route#

Next, return the file explorer in Zuplo and select the route you created earlier. Click the Test button. Set the ID pramaeter in the path /products/{id} to an ID in your Firebase collection. Click Test and you should see the data from the product returned.

Test Result

6/ Modify the Body#

The response returned from Firestore isn't in the nicest format. Add a new custom policy to the route by selecting Add Policy and searching for custom code outbound. Set the configuration of the policy to the code below and click Save.

{
  "export": "default",
  "module": "$import(./modules/rewrite-body)"
}

Next create a new outbound module called rewrite-body.ts and set it to the following code. This will take the JSON sent by Firestore and convert it into a more readable format.

export default async function (response: Response) {
  // Read the outgoing body
  const body = await response.json();
 
  // Create a new body with additional properties
  const outbound = {
    name: body.fields.name.stringValue,
    description: body.fields.description.stringValue,
    price: body.fields.price.stringValue,
  };
 
  // Return a new request with the modified body
  return new Response(JSON.stringify(outbound), response);
}

7/ Test the Body Rewrite#

Go back to the route tester and fetch the document again. This time you will get a response with a nicely formatted JSON document like the below example.

{
  "name": "Widget",
  "description": "The best widget you have ever used.",
  "price": "99.99"
}

Now you have a document that is stored in Firebase Firestore that can be served to users through a nice REST API. I addition to what was shown in this walkthrough, its easy to add even more functionality like authentication with API Keys, rate limiting, and more using Zuplo.

Designed for Developers, Made for the Edge