Skip to content

FirebaseServerApp missing Referer header for Identity Toolkit requests (Next.js Instrumentation workaround fails on HMR) #9423

@kayp514

Description

@kayp514

Operating System

windows 11

Environment (if applicable)

Node.js

Firebase SDK Version

12.0.0

Firebase SDK Product(s)

Auth

Project Tooling

Nextjs App

Detailed Problem Description

Hello, This is an additional to #9173

When using FirebaseServerApp in a Next.js environment, requests made to identitytoolkit.googleapis.com fail with a referer-blocked error: [FirebaseError]: Firebase: Error (auth/requests-from-referer--are-blocked.)

Current Workaround
I managed to bypass this by using Next.js Instrumentation to monkey-patch global.fetch. My register function intercepts requests to identitytoolkit.googleapis.com and manually injects the missing Referer header:

export function register() { const originalFetch = global.fetch; global.fetch = async (input, init) => { // ... logic to check hostname and add Referer header ... return originalFetch(input, modifiedInit); }; } 

The Limitation (HMR)
While this works on initial server startup, it is unstable during development. As per the Next.js documentation, the register function is only called once when the server instance initiates.

During Hot Module Replacement (HMR), the patched fetch context seems to be lost or reset, causing the Referer header to drop and the referer-blocked errors to reappear until the server is fully restarted.

I am opening this issue to ask for advice or a fix: Is there a supported way to configure FirebaseServerApp to explicitly include the Referer header so we don't have to rely on global monkey-patching? If not, is there a recommended pattern for maintaining this header injection that persists correctly through Next.js HMR cycles?

Note: I am looking for a server-side solution that does not involve using Service Workers.

Steps and code to reproduce issue

  1. create instrumentation.ts file in the root directory of your project. export register
export function register() { const originalFetch = global.fetch; global.fetch = async (input, init) => { // ... logic to check hostname and add Referer header ... return originalFetch(input, modifiedInit); }; } 
  1. Initialize the FirebaseServerApp instance in the server-side component
import { initializeServerApp } from 'firebase/app'; import { getAuth } from 'firebase/auth'; import { headers } from 'next/headers'; export default function ServeSideComponent() { const FIREBASE_CONFIG = { apiKey: "YOUR_FIREBASE_API_KEY", authDomain: "YOUR_PROJECT.firebaseapp.com", projectId: "YOUR_PROJECT_ID", // ... other configs (messagingSenderId, appId, etc.) }; const authIdToken = headers().get('Authorization')?.split('Bearer ')[1]; const serverApp = initializeServerApp(FIREBASE_CONFIG, { authIdToken }); const auth = getAuth(serverApp); } 

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-triagenewA new issue that hasn't be categoirzed as question, bug or feature requestquestion

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions