解決部屬到Firebase Hosting SSR遭遇的Credential問題Error: invalid_grant: Invalid grant: account not found

這幾天將Next.js原本遷徙到secret manager來管理,只是一旦部屬Firebase Hosting SSR,遭遇了Credential錯誤問題

Error: invalid_grant: Invalid grant: account not found

究竟該如何解決呢?


這是我暴力舊的直接import serviceAccount.json,但是為了安全性還是遷徙到secret manager

import admin from 'firebase-admin';
import { getStorage, getDownloadURL } from 'firebase-admin/storage';
import type { File, GetFilesOptions } from '@google-cloud/storage';
import firebaseCredentials from '../../serviceAccountKey.json';

export const getBucket = () => {
if (admin.apps.length === 0) {
admin.initializeApp({
credential: admin.credential.cert(
firebaseCredentials as admin.ServiceAccount
),
storageBucket: '<your-firebase-project>.appspot.com',
});
}

return getStorage().bucket();
}


在你的模組中初始化firebase-admin,以FirebaseStorage.ts為例

import admin from 'firebase-admin';
import { getStorage, getDownloadURL } from 'firebase-admin/storage';
import type { File, GetFilesOptions } from '@google-cloud/storage';

export const getBucket = () => {
if (admin.apps.length === 0) {
const storageBucket = process.env.STORAGE_BUCKET_NAME?.trim();
const projectId = process.env.ADMIN_PROJECT_ID?.trim();
const clientEmail = process.env.ADMIN_CLIENT_EMAIL?.trim();
const privateKey = process.env.ADMIN_PRIVATE_KEY?.replace(/\\n/g, '\n');

console.log('🔍 檢查 Firebase Admin 初始化參數:', {
hasStorageBucket: !!storageBucket,
hasProjectId: !!projectId,
hasClientEmail: !!clientEmail,
hasPrivateKey: !!privateKey,
});

if (!projectId || !clientEmail || !privateKey) {
throw new Error('❌ Firebase Admin 初始化失敗:環境變數不完整');
}

admin.initializeApp({
credential: admin.credential.cert({
projectId,
clientEmail,
privateKey,
}),
storageBucket,
});
}

return getStorage().bucket();
}


使用secret manage儲存 serveiceAccout.json資訊

cat serviceAccountKey.json | jq -r '.project_id' | \
firebase functions:secrets:set ADMIN_PROJECT_ID

cat serviceAccountKey.json | jq -r '.client_email' | \
firebase functions:secrets:set ADMIN_CLIENT_EMAIL

cat serviceAccountKey.json | jq -r '.private_key' | \
firebase functions:secrets:set ADMIN_PRIVATE_KEY


使用上面的jq指令導入到firebase functions:secrets指令,字串後有多一個換行字元(\n),導致部屬到在cloud run上時一直發生錯誤 `Error: invalid_grant: Invalid grant: account not found`,可是線下我是自己設定.env檔案,所以一直覺得gcp實在很奇怪。

如果你的firebase專案沒有要跨專案存取或是存取其他的storage,建議部屬時就拿掉credential這個欄位,firebase-admin跑在gcp上會取得預設的credential來跑,也不會遇到這個狀況了


在firebase.json中要求存取secrets

"frameworksBackend": {
...
"secrets": [
"ADMIN_PROJECT_ID",
"ADMIN_CLIENT_EMAIL",
"ADMIN_PRIVATE_KEY"
]
}

留言