Proxy Firestore with Firebase User Credentials

This sample demonstrates how to expose Firestore documents through a REST API using the Zuplo URL Rewrite Handler and the Firebase User 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 POST
request will accept an {name}
parameter in the URL and a body for a new document. This document will be scoped to the authenticated user. The request will be mapped to the Firestore REST API endpoint to create a document.
{
"/todos/{name}": {
"post": {
"x-zuplo-route": {
"corsPolicy": "none",
"policies": {
"inbound": [
"set-user",
"firebase-user-auth"
]
},
"handler": {
"module": "$import(@zuplo/runtime)",
"export": "urlRewriteHandler",
"options": {
"rewritePattern": "https://firestore.googleapis.com/v1/projects/${env.FIREBASE_PROJECT}/databases/(default)/documents/todos/${request.user.sub}/${params.name}"
}
}
},
"operationId": "51985ae4-9cf9-4fbd-a617-ecb4e648b8f1"
}
}
}
2/ Add Authentication Policy
This demo uses a mock authentication policy that is a custom policy. This policy just takes the value of the user-id
header and sets the authenticated user to that value. A real API would use the API Key or one of the JWT policies to authenticate the user.
{
"name": "set-user",
"policyType": "custom-code-inbound",
"handler": {
"export": "default",
"module": "$import(./modules/set-user)"
}
}
3/ Add Policy
The Firebase User Auth Policy will create an token for the current user that will be added to the outgoing request's Authorization
header. This token is scoped to a specific user so any Firebase rules that are in place will be enforced.
{
"name": "firebase-user-auth",
"policyType": "upstream-firebase-user-auth-inbound",
"handler": {
"module": "$import(@zuplo/runtime)",
"export": "UpstreamFirebaseUserAuthInboundPolicy",
"options": {
"serviceAccountJson": "$env(SERVICE_ACCOUNT_JSON)",
"userIdPropertyPath": ".sub",
"webApiKey": "$env(WEB_API_KEY)"
}
}
}
4/ Set Environment Variables
There are two environment variables used in the sample:
SERVICE_ACCOUNT_JSON
- The Firebase Service Account tokenFIREBASE_PROJECT
- The Firebase project IDWEB_API_KEY
- The Firebase web api key
5/ Call the API
The API can now be called to retrieve a document from Firestore.
curl -X POST https://API_URL/todos/my-doc-name
-H "Content-Type: application/json"
-H "Authorization: user123"
-d '{"fields": { "name": { "stringValue": "my-list" } } }'
Response:
{
"name": "projects/project-demo-8/databases/(default)/documents/todos/user123/list1/U7HlIJnAJdKDJeaF8Bmn",
"fields": {
"name": {
"stringValue": "my-list"
}
},
"createTime": "2023-06-02T18:17:39.041624Z",
"updateTime": "2023-06-02T18:17:39.041624Z"
}