解決部屬到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"
]
}
留言