Firestore proxy with Nginx (Use firestore.yourdomain.com instead of firestore.googleapis.com)

We use firestore cloud db to show data to the users on our virtual web platform and mobile applications. After many events we have a problem where some of the users are behind a corporate firewall or they are connected to their companies VPN and the API endpoint https://firestore.googleapis.com somehow is blocked so they cannot use our system at all. Why a company would block *.googleapis.com? I have no idea, except maybe for China.

To overcome this, I’ve set up an Nginx proxy on an Amazon EC2 instance so that the web and mobile clients can send the firestore requests through our domain (firestore.yourdomain.com) instead of firestore.googleapis.com. Here’s the Nginx setup:

server {
    listen 80;

     root /var/www/html;
     index index.html;

     location /index.html {
         try_files $uri $uri/ =404;
     }

     location / {
         resolver 172.0.0.53 ipv6=off;
         proxy_pass https://firestore.googleapis.com;
         proxy_http_version 1.1;
         proxy_connect_timeout 120s;
         proxy_read_timeout 300s;
         proxy_send_timeout 100s;
         proxy_set_header Cache-Control no-cache;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_cache_bypass $http_upgrade;
         proxy_buffering off;
    }
}

So this setup is behind an Amazon load balancer. That’s why it listens to port 80. The actual traffic from the client to the load balancer is secured and then mapped to port 80 of the EC2 instance. You cannot just proxy the TLS encypted traffic to https://firestore.googleapis.com from your domain, you will get an SSL error because the certificate is registered to *.googleapis.com.

Supposing your system is on Amazon:

  • You’ve set up a load balancer with your wildcard certificate (*.yourdomain.com).
  • You mapped firestore.yourdomain.com to your load balancer.
  • You’ve created an instance with the nginx config above.
  • Now you can initialize you js firestore library like this:
import * as app from "firebase/app";
import "firebase/firestore";
import "firebase/database";
import "firebase/storage";
import "firebase/analytics";

const config = {
  apiKey: "yourkey",
  authDomain: "yourdomain.firebaseapp.com",
  databaseURL: "https://yourdatabase.firebaseio.com",
  projectId: "yourprojectId",
  messagingSenderId: "messagingSenderId",
  appId: "yourAppId",
  measurementId: "youMeasurementId",
};

app.initializeApp(config);
app.analytics();

export const firebase = app;
export const db = app.firestore();
db.settings({
  "host": "firestore.yourdomain.com",
  "ssl": true
});

Now you just refresh you browser app and check your XHR requests. They will go through your server. Hope this will help someone as I’ve spent a lot of time finding the right setup.

Happy proxying.