Firebase Google sign-in for apps on Cloud Run
Add the exact hostname your Cloud Run app runs on (its *.run.app URL or your custom domain) to Firebase's authorized domains. Without it, sign-in fails with auth/unauthorized-domain.
To show your own domain at Google sign-in, put Firebase Hosting in front of the service (Hosting serves /__/auth/ for you). With a load balancer or Cloud Run domain mapping, forward /__/auth/ from your app to firebaseapp.com instead.
Why sign-in fails or shows firebaseapp.com on Cloud Run
- A new hostname Firebase doesn't know. Cloud Run gives each service a generated URL such as
https://helloworld-RANDOM_HASH-us-central1.a.run.app. Firebase only runs OAuth sign-in on domains in its authorized list. - The sign-in helper lives on another domain. By default
authDomainis<project-id>.firebaseapp.com. Firebase's docs say Google may then showContinue to: https://<project-id>.firebaseapp.com. They also saysignInWithRedirect()needs a fix on browsers that block third-party storage access (Chrome M115+, Firefox 109+, Safari 16.1+) when you host anywhere other than Firebase Hosting. - Your
/__/auth/setup depends on how you add a custom domain. Google's Cloud Run docs list three ways: a global external Application Load Balancer (recommended), Cloud Run domain mapping (limited availability, Preview), or Firebase Hosting.
Choose your domain setup (as of Oct 2026)
| Setup | Who answers /__/auth/ |
Points from the docs |
|---|---|---|
| A. Firebase Hosting rewrite to Cloud Run | Firebase Hosting, automatically | 60-second request timeout. Only the __session cookie reaches your app. Supported regions only. |
| B. Global external Application Load Balancer | Your app (you forward it) | Recommended by Cloud Run. Supports your own TLS certificate and path routing. |
| C. Cloud Run domain mapping | Your app (you forward it) | Preview. Google says it's "not production-ready" and "not recommended for production services". Limited regions. Maps / only. |
No custom domain (*.run.app only) |
Nobody by default | Use popups, or forward /__/auth/ in your app as in B. |
Step 1: Add your hostnames to Firebase authorized domains
As of Oct 2026, Firebase's docs give Security > Authentication > Settings > Authorized domains > Add domain. Older guides use Build > Authentication > Settings. Add the hostname exactly as users load it, for example:
helloworld-RANDOM_HASH-us-central1.a.run.app
app.example.com
The first line uses the placeholder format from Firebase's Cloud Run guide. Copy your real run.app hostname from the Cloud Run console or from the output of gcloud run deploy. For more on the list itself, see Firebase authorized domains.
Option A: Firebase Hosting in front of Cloud Run
This is the shortest route to your own domain at sign-in. Firebase Hosting reserves /__/* paths, and those come first in Hosting's response order, ahead of rewrites. So /__/auth/handler keeps working even when every other path goes to Cloud Run.
- In a folder separate from your service's source, create
firebase.json.publicis the one required Hosting field, so create an emptypublicfolder next to it.
json
{
"hosting": {
"public": "public",
"rewrites": [
{
"source": "**",
"run": {
"serviceId": "my-service",
"region": "us-central1",
"pinTag": true
}
}
]
}
}
region defaults to us-central1 if you leave it out. pinTag is optional: it pins each Hosting release to the Cloud Run revision that was live when you deployed.
- Deploy:
firebase deploy --only hosting --project YOUR_PROJECT_ID. - Connect your custom domain to Hosting. The full DNS, verification and SSL steps are in Firebase Hosting custom domain for auth.
- Continue with Steps 2 and 3 below.
Know the limits before you switch:
- Firebase Hosting has a 60-second request timeout. Longer requests get a 504.
- Hosting strips cookies on requests to Cloud Run, except one named
__session. If your server reads a session cookie, it has to be called__session. - Your service must be in a region that supports Hosting rewrites (for example
us-central1,europe-west1orasia-east1; the full list is in Firebase's Cloud Run guide).
Option B or C: forward /__/auth/ from your Cloud Run app
With a load balancer or domain mapping, requests for /__/auth/ reach your container, so your app has to forward them to Firebase. Firebase's docs say the forwarding must be invisible to the browser and "cannot be done via a 302 Redirect".
Node.js (Express) with http-proxy-middleware:
import express from "express";
import { createProxyMiddleware } from "http-proxy-middleware";
const app = express();
// Register this BEFORE any body-parsing middleware (express.json(), etc.).
app.use(
"/__/auth",
createProxyMiddleware({
target: "https://your-project-id.firebaseapp.com/__/auth",
changeOrigin: true, // send Host: your-project-id.firebaseapp.com
})
);
// ...your routes
app.listen(process.env.PORT || 8080);
This follows the library's "keep the same base path" pattern, so /__/auth/handler on your domain goes to /__/auth/handler on firebaseapp.com. If a body parser has to run first, the library's fixRequestBody helper fixes POST bodies that were already read.
Test this on a preview deployment before relying on it.
nginx in your container: Firebase's own example is:
location /__/auth {
proxy_pass https://<project>.firebaseapp.com;
}
Cloud Run domain mapping commands (Preview):
gcloud beta run domain-mappings create --service SERVICE --domain app.example.com
gcloud beta run domain-mappings describe --domain app.example.com
Add every record listed under resourceRecords at your DNS provider. Google says the certificate usually takes about 15 minutes but can take up to 24 hours. If your DNS is behind Cloudflare's CDN, Google's docs say to turn off Always Use HTTPS under SSL/TLS > Edge Certificates, or the mapping can fail to validate.
Step 2: Add the redirect URI
As of Oct 2026, open Google Auth Platform > Clients in the Google Cloud console (older guides say Credentials), choose the web client created for your Firebase project, and add:
https://app.example.com/__/auth/handler
Changes can take 5 minutes to a few hours to apply.
Step 3: Set authDomain and rebuild
const firebaseConfig = {
apiKey: "...",
authDomain: "app.example.com", // was "your-project-id.firebaseapp.com"
projectId: "your-project-id",
appId: "...",
};
Next.js on Cloud Run: NEXT_PUBLIC_ variables are written into the browser bundle when next build runs. Changing them later as Cloud Run environment variables won't update client code. Set NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN (or whatever you call it) at build time, then rebuild the image. For the full Next.js sign-in setup, see Next.js Firebase Google sign-in.
Check Firebase ID tokens on your Cloud Run server
Sign-in happens in the browser. Your server should identify the user by checking their Firebase ID token, which the client sends over HTTPS.
Client (send the token):
import { getAuth } from "firebase/auth";
// currentUser is null until sign-in has finished.
const token = await getAuth().currentUser.getIdToken();
const res = await fetch("/api/me", {
headers: { Authorization: `Bearer ${token}` },
});
Server (Node.js Admin SDK):
import { initializeApp } from "firebase-admin/app";
import { getAuth } from "firebase-admin/auth";
initializeApp(); // on Cloud Run, picks up Application Default Credentials
app.get("/api/me", async (req, res) => {
const match = /^Bearer (.+)$/.exec(req.headers.authorization || "");
if (!match) return res.status(401).json({ error: "missing token" });
try {
const decoded = await getAuth().verifyIdToken(match[1]);
res.json({ uid: decoded.uid });
} catch {
res.status(401).json({ error: "invalid token" });
}
});
Firebase recommends Application Default Credentials for apps on Cloud Run, so you don't ship a key file. verifyIdToken() checks the token's format, expiry and signature, but by itself it doesn't check whether the token was revoked (see Firebase's "Detect ID token revocation").
How to confirm it worked
- Open
https://app.example.com/__/auth/handler. The address bar should stay on your domain (no 302 tofirebaseapp.com), and the response shouldn't be your app's own 404. - Sign in. Google's account chooser should show your domain instead of
<project-id>.firebaseapp.com(why Google says "continue to firebaseapp.com"). - Call
/api/meafter signing in. It should return youruid. Without the header it should return 401.
Related problems
- Redirect returns to your app with no user: signInWithRedirect not working.
auth/unauthorized-domainon one hostname but not another (for example on therun.appURL when you only added your custom domain): each hostname is its own entry in the list, so add it as in Step 1.Error 400: redirect_uri_mismatchafter switchingauthDomain: the Step 2 URI is missing or hasn't taken effect yet.
FAQ
Can I use my `run.app` URL as `authDomain`?
Only if your app forwards /__/auth/ on that hostname (Option B code), and you add https://<service>.run.app/__/auth/handler as a redirect URI. Without that, keep the default firebaseapp.com authDomain and consider signInWithPopup(), which Firebase lists as an alternative for hosts other than Firebase Hosting.
Is Cloud Run domain mapping OK for production?
Google's Cloud Run docs say domain mappings are in Preview, "not production-ready", and "not recommended for production services". For production, use a global external Application Load Balancer or Firebase Hosting.
Why doesn't my server see its session cookie behind Firebase Hosting?
Firebase Hosting strips cookies from requests it forwards to Cloud Run, except the one named __session. Rename your session cookie to __session.
Do I need a service account key file to check ID tokens on Cloud Run?
Usually no. Firebase recommends initializing the Admin SDK with Application Default Credentials on Cloud Run, and calling initializeApp() with no arguments does that.
Sources
- Map custom domains (Cloud Run, Google Cloud Documentation)
- Serve dynamic content and host microservices with Cloud Run (Firebase Hosting)
- Configure Hosting behavior (Firebase Hosting)
- Manage cache behavior (Firebase Hosting)
- Load Firebase SDKs from reserved URLs (Firebase Hosting)
- Best practices for using signInWithRedirect on browsers that block third-party storage access (Firebase)
- Authenticate Using Google with JavaScript (Firebase)
- Authenticate with Firebase Using Email Link in JavaScript (Firebase), authorized domains steps
- Manage OAuth Clients (Google Cloud Platform Console Help)
- Verify ID Tokens (Firebase Authentication)
- Add the Firebase Admin SDK to your server (Firebase)
- http-proxy-middleware README (GitHub)
- How to use environment variables in Next.js
How this page was made: drafted with AI from the sources listed, reviewed by Pewterkit. Docs checked 26 Oct 2026. Spotted something out of date? Tell us.