Proxying Flowsery Analytics with Firebase Hosting

Route Flowsery Analytics through Firebase Hosting using Cloud Functions to prevent adblocker interference and capture more accurate visitor data.

Note: Firebase Hosting does not natively support reverse proxy rewrites to external destinations. This guide leverages Firebase Cloud Functions as an alternative.

1. Initialize Firebase Functions (if not already configured)

If your project does not yet include Firebase Functions, run:

firebase init functions

Follow the setup prompts for your environment. When finished, a /functions directory will be present in your project.

2. Install Dependencies

Navigate to the functions/ directory and install the required packages:

cd functions/
npm i -s express express-http-proxy

3. Build the Reverse Proxy Function

Create or update functions/index.js with the following:

const { onRequest } = require('firebase-functions/v2/https');
const express = require('express');
const proxy = require('express-http-proxy');

const app = express();

app.set('trust proxy', true);

// Proxy the Flowsery Analytics tracking script
app.use(
  '/js/script.js',
  proxy('https://analytics.flowsery.com', {
    proxyReqPathResolver: () => '/js/script.js',
  })
);

// Proxy the event collection endpoint
app.use(
  '/api/events',
  proxy('https://analytics.flowsery.com', {
    proxyReqPathResolver: () => '/events',
    proxyReqOptDecorator: (proxyReqOpts, srcReq) => {
      // Forward the real visitor IP for accurate geolocation
      const clientIp = srcReq.headers['x-real-ip'] || srcReq.headers['x-forwarded-for']?.split(',')[0]?.trim() || srcReq.ip;
      proxyReqOpts.headers['x-flowsery-ip'] = clientIp;
      return proxyReqOpts;
    },
  })
);

exports.reverseProxy = onRequest(app);

Note: If your project already uses an /api/events route, add data-api to the Flowsery Analytics script tag to redirect events elsewhere. For example, data-api="/flowsery-events" sends data to /flowsery-events instead.

Important: If every visitor appears to be in the same location in your dashboard, confirm that the x-flowsery-ip header is set to the real visitor IP (not the proxy server IP) when forwarding requests to the Flowsery Analytics /events endpoint.

4. Configure Firebase Hosting Rewrites

Update firebase.json to route matching paths to the reverseProxy function:

{
  "hosting": {
    "public": "public",
    "ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
    "rewrites": [
      {
        "source": "/js/script.js",
        "function": "reverseProxy"
      },
      {
        "source": "/api/events",
        "function": "reverseProxy"
      }
    ]
  },
  "functions": [
    {
      "source": "functions",
      "codebase": "default",
      "ignore": ["node_modules", ".git", "firebase-debug.log", "firebase-debug.*.log", "*.local"]
    }
  ]
}

5. Modify the Script Tag

Replace the original Flowsery Analytics snippet with the proxied version:

<script defer data-fl-website-id="flid_******" data-domain="your_domain.com" src="/js/script.js"></script>

6. Deploy Hosting and Functions

Push both hosting and functions in a single deploy:

firebase deploy --only hosting,functions

Confirming It Works

To validate that the proxy is functioning correctly:

  1. Navigate to your website
  2. Open your browser's developer tools and switch to the Network tab
  3. Verify that analytics requests are served from your domain rather than analytics.flowsery.com

Troubleshooting

Every visitor appears from the same location

When all visitors show a single geographic location (typically your server's region), the proxy is not forwarding real visitor IPs correctly.

Resolution:

  1. Ensure your proxy includes the x-flowsery-ip header containing the actual visitor IP address (not the server IP) when forwarding requests to the Flowsery Analytics /events endpoint