Next.js部署Cloud Run后调用Firebase云函数的密钥与环境变量问题
已将Web应用构建并部署至Google Cloud Run,调用Firebase Cloud Function时需配置相关密钥,且密钥已存入GitHub仓库Secrets中。GitHub Actions可读取这些密钥,但环境变量在前端无法正常使用——浏览器中打印process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID返回undefined,导致Firebase云函数URL中的项目ID显示为undefined,触发CORS策略阻止请求的报错。
浏览器控制台日志:
Access to fetch at 'https://us-central1-undefined.cloudfunctions.net/addData' from origin 'my_url_redacted' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
POST https://us-central1-undefined.cloudfunctions.net/addData net::ERR_FAILED
1. 移除Next.js冗余的环境变量配置
NEXT_PUBLIC_前缀的环境变量会被Next.js自动暴露到前端,无需在next.config.js的env块中重复配置,重复配置可能导致变量读取失败。修改next.config.js如下:
/** @type {import('next').NextConfig} */ const nextConfig = { typescript: { ignoreBuildErrors: true, }, output: "standalone", reactStrictMode: true, } module.exports = nextConfig
2. 直接在Cloud Run部署时注入环境变量
避免依赖.env.local文件(该文件可能因.gitignore规则被构建忽略),在GitHub Actions的部署步骤中直接将Secrets中的变量注入到Cloud Run服务:
修改google-cloudrun.yml中的Deploy步骤:
- name: Deploy run: gcloud run deploy $SERVICE --image gcr.io/$PROJECT_ID/$SERVICE:$GITHUB_SHA --platform managed --region $RUN_REGION --allow-unauthenticated --set-env-vars NEXT_PUBLIC_FIREBASE_API_KEY=${{ secrets.NEXT_PUBLIC_FIREBASE_API_KEY }},NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=${{ secrets.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN }},NEXT_PUBLIC_FIREBASE_DATABASE_URL=${{ secrets.NEXT_PUBLIC_FIREBASE_DATABASE_URL }},NEXT_PUBLIC_FIREBASE_PROJECT_ID=${{ secrets.NEXT_PUBLIC_FIREBASE_PROJECT_ID }},NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=${{ secrets.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET }},NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=${{ secrets.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID }},NEXT_PUBLIC_FIREBASE_APP_ID=${{ secrets.NEXT_PUBLIC_FIREBASE_APP_ID }}
同时删除GitHub Actions中生成.env.local的步骤:
# 移除以下步骤 - name: Set Environment Variables run: | echo NEXT_PUBLIC_FIREBASE_API_KEY='${{ secrets.NEXT_PUBLIC_FIREBASE_API_KEY }}' > .env.local ...(其余echo命令)
3. 验证Cloud Function的CORS配置(可选)
解决环境变量问题后,若仍存在CORS报错,需确保Firebase Cloud Function中配置了允许Cloud Run域名的CORS头。示例代码如下:
exports.addData = functions.https.onRequest((req, res) => { // 设置CORS头 res.set('Access-Control-Allow-Origin', 'https://your-cloud-run-domain.com'); res.set('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); res.set('Access-Control-Allow-Headers', 'Content-Type'); // 处理OPTIONS预检请求 if (req.method === 'OPTIONS') { res.status(204).send(''); return; } // 函数业务逻辑... });
.env.local生成方式不可靠:若项目.gitignore中包含.env.local,gcloud builds submit会默认忽略该文件,导致构建时无法读取环境变量。next.config.js重复配置NEXT_PUBLIC_变量:干扰Next.js自动暴露变量的逻辑,导致前端无法正常读取。
内容的提问来源于stack exchange,提问作者zatum

