Proxy Firestore with Firebase Admin Credentials

See the full example project on Github

This sample demonstrates how to expose Firestore documents through a REST API using the Zuplo URL Rewrite Handler and the Firebase Admin Auth Policy.

1/ Create Route

Create a route that uses the URL Rewrite Handler. The rewrite points to the Firestore REST API.

In this example, a GET request will retrieve a single document by by mapping the id parameter of the incoming request to the Firestore REST API endpoint to GET a document

{
  "/doc/{id}": {
    "get": {
      "summary": "Proxy Firebase Document",
      "x-zuplo-route": {
        "corsPolicy": "none",
        "handler": {
          "export": "urlRewriteHandler",
          "module": "$import(@zuplo/runtime)",
          "options": {
            "rewritePattern": "https://firestore.googleapis.com/v1/projects/${env.FIREBASE_PROJECT}/databases/(default)/documents/products/${params.id}"
          }
        },
        "policies": {
          "inbound": [
            "upstream-firebase-admin"
          ]
        }
      }
    }
  }
}

2/ Add Policy

The Firebase Admin Auth Policy will create an admin token using a Firebase Service Account that will be added to the outgoing request's Authorization header. Because this token will allow full access to any document, generally another authorization policy would also be applied.

{
  "handler": {
    "export": "UpstreamFirebaseAdminAuthInboundPolicy",
    "module": "$import(@zuplo/runtime)",
    "options": {
      "serviceAccountJson": "$env(SERVICE_ACCOUNT_JSON)"
    }
  },
  "name": "upstream-firebase-admin",
  "policyType": "upstream-firebase-admin-auth-inbound"
}

3/ Set Environment Variables

There are two environment variables used in the sample:

  • SERVICE_ACCOUNT_JSON - The Firebase Service Account token
  • FIREBASE_PROJECT - The Firebase project ID

3/ Call the API

The API can now be called to retrieve a document from Firestore.

curl https://API_URL/doc/{id}

Response:

{
  "name": "projects/project-demo-8/databases/(default)/documents/products/24uBKfjOkDvNv1mjrEpL",
  "fields": {
    "name": {
      "stringValue": "hammer"
    },
    "description": {
      "stringValue": "A normal hammer"
    },
    "price": {
      "stringValue": "14.99"
    }
  },
  "createTime": "2023-05-23T11:38:29.109118Z",
  "updateTime": "2023-05-23T11:38:29.109118Z"
}