为什么将环境变量加载到 Firebase 函数时出现未定义?
我正在尝试使用 Google Secrets Manager API 和 Firebase 函数之间的集成将环境变量加载到我的 Firebase 函数中,但是它们全部显示为未定义。我之前使用的是 .env。文件来加载这些变量,在我尝试这个之前它工作得很好,但现在也不起作用!我正在使用 Node.js。
为了在 Secrets API 上设置秘密,我运行:
firebase functions:secrets:set MY_SECRET
我通过在每个秘密上运行以下命令来验证秘密是否已成功设置:
firebase functions:secrets:access MY_SECRET
我在 index.ts
中定义我的函数,如下所示:
import * as functions from 'firebase-functions'
import apiApp from "./api/api"
const REGION = "my region as a string"
const secrets = ["SERVICE_ACCOUNT"]
export const api = functions
.region(REGION)
.runWith({ secrets })
.https.onRequest(apiApp)
在代码中,我使用 process.env.MY_SECRET
访问它们。但是,当我运行 firebaseserve
(在 Firebase 模拟器中运行)或 firebasedeploy
时,我总是会收到此错误,后跟由 env 变量导致的堆栈跟踪 <代码>未定义:
Error: Error occurred while parsing your function triggers.
InvalidCharacterError
at /.../functions/node_modules/base-64/base64.js:23:36
at Object.<anonymous> (/.../functions/node_modules/base-64/base64.js:164:2)
at Module._compile (node:internal/modules/cjs/loader:1097:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1151:10)
at Module.load (node:internal/modules/cjs/loader:975:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Module.require (node:internal/modules/cjs/loader:999:19)
at require (node:internal/modules/cjs/helpers:102:18)
at Object.<anonymous> (/.../functions/lib/admin.js:5:16)
at Module._compile (node:internal/modules/cjs/loader:1097:14)
admin.ts:(
import * as admin from 'firebase-admin'
import * as base64 from 'base-64'
const serviceAccount = JSON.parse(base64.decode(process.env.SERVICE_ACCOUNT))
const credential = admin.credential.cert(serviceAccount)
admin.initializeApp({ credential })
...
我对其中一个秘密进行base64解码并收到错误,因为它未定义)
package.json:
{
"name": "functions",
"description": "Cloud Functions for Firebase",
"scripts": {
"build": "tsc",
"serve": "npm run build && firebase emulators:start --only functions",
"shell": "npm run build && firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log",
"postbuild": "copyfiles -u 1 src/**/*.handlebars src/**/*.json lib/"
},
"engines": {
"node": "16"
},
"main": "lib/index.js",
"dependencies": {
...
"base-64": "^1.0.0",
"firebase-admin": "^10.0.2",
"firebase-functions": "^3.18.0",
...
},
"devDependencies": {
"@babel/runtime": "^7.17.2",
"@types/base-64": "^1.0.0",
...
},
"private": true
}
我尝试修改代码,这样我就不会遇到错误离开,但这仅仅意味着我的端点稍后出错,因为环境变量是未定义
。
出了什么问题?
I am trying to use the integration between Google Secrets Manager API and Firebase Functions to load environment variables into my Firebase functions, however they are all coming up as undefined. I was previously using .env. files to load these variables, which worked fine before I tried this, but now also isn't working! I'm using Node.js.
To set secrets on the Secrets API, I ran:
firebase functions:secrets:set MY_SECRET
I verified the secrets had been set successfully by running the following on each one:
firebase functions:secrets:access MY_SECRET
I'm defining my functions in index.ts
as follows:
import * as functions from 'firebase-functions'
import apiApp from "./api/api"
const REGION = "my region as a string"
const secrets = ["SERVICE_ACCOUNT"]
export const api = functions
.region(REGION)
.runWith({ secrets })
.https.onRequest(apiApp)
And in code, I'm accessing them with process.env.MY_SECRET
. However, when I run firebase serve
(to run in the Firebase emulator) or firebase deploy
, I always get this error followed by a stack trace resulting from the env variable being undefined
:
Error: Error occurred while parsing your function triggers.
InvalidCharacterError
at /.../functions/node_modules/base-64/base64.js:23:36
at Object.<anonymous> (/.../functions/node_modules/base-64/base64.js:164:2)
at Module._compile (node:internal/modules/cjs/loader:1097:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1151:10)
at Module.load (node:internal/modules/cjs/loader:975:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Module.require (node:internal/modules/cjs/loader:999:19)
at require (node:internal/modules/cjs/helpers:102:18)
at Object.<anonymous> (/.../functions/lib/admin.js:5:16)
at Module._compile (node:internal/modules/cjs/loader:1097:14)
admin.ts:
import * as admin from 'firebase-admin'
import * as base64 from 'base-64'
const serviceAccount = JSON.parse(base64.decode(process.env.SERVICE_ACCOUNT))
const credential = admin.credential.cert(serviceAccount)
admin.initializeApp({ credential })
...
(I'm base64 decoding one of the secrets and get an error because it's undefined)
package.json:
{
"name": "functions",
"description": "Cloud Functions for Firebase",
"scripts": {
"build": "tsc",
"serve": "npm run build && firebase emulators:start --only functions",
"shell": "npm run build && firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log",
"postbuild": "copyfiles -u 1 src/**/*.handlebars src/**/*.json lib/"
},
"engines": {
"node": "16"
},
"main": "lib/index.js",
"dependencies": {
...
"base-64": "^1.0.0",
"firebase-admin": "^10.0.2",
"firebase-functions": "^3.18.0",
...
},
"devDependencies": {
"@babel/runtime": "^7.17.2",
"@types/base-64": "^1.0.0",
...
},
"private": true
}
I've tried modifying the code so I don't run into errors right away, but this just means my endpoints error later on because the env variable is undefined
.
What is going wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
由于访问
秘密
的方式不正确,您正在做的事情将导致未定义
。在此代码段中:您将
secret
添加到env
变量中,然后该变量只能在.https.onRequest(apiApp)
。例如,上面的代码将在您传递给的函数上记录
SERVICE_ACCOUNT
秘密。此文档中也有说明:为了能够在不使用 https 函数的
.runWith
参数的情况下访问您的密钥,您必须首先安装 @google-cloud/secret-manager:然后启动它:
访问您的秘密版本:
作为参考,这里是根据您的情况编译的代码
admin.ts
:然后您可以导入
admin.ts
并使用这些方法调用db
。有关更多信息,请查看这些文档:
您可能还想查看Secret Manager 最佳实践。
What you're doing will result in
undefined
due to incorrect ways of accessingsecrets
. In this code snippet:You're adding the
secret
to theenv
variables which then can only be used on the.https.onRequest(apiApp)
. E.g.The above code will log the
SERVICE_ACCOUNT
secret on the function which you passed to. It's also stated in this documentation:For you to be able to access your secret without using the
.runWith
parameter of the https functions, you must first install the @google-cloud/secret-manager:then initiate it:
Accessing your secret versions:
For reference, here's the compiled code based on your
admin.ts
:You can then import
admin.ts
and calldb
with these method.For more information, check out these documentations:
You may also want to checkout Secret Manager Best Practices.
我遇到了这个问题,因为我的导入导致在 index.ts 中调用 admin.initialiseApp。
index.ts:
api.ts 通过许多其他文件导入 admin.ts,而 admin.ts 需要填充 process.env.SERVICE_ACCOUNT。正如 Marc Anthony B 所说,如果从 index.ts 调用,SERVICE_ACCOUNT 还不会被填充,因此会出现错误。
我通过将 admin.ts 重构为以下内容来解决:
因此我所有的导出都是函数,而不是 db 和 auth 的实例。
I ran into this issue because my imports were leading to admin.initialiseApp being called in index.ts.
index.ts:
api.ts was importing admin.ts through a number of other files, and admin.ts required process.env.SERVICE_ACCOUNT to be populated. As Marc Anthony B said, SERVICE_ACCOUNT wouldn't yet be populated if calling from index.ts, hence the error.
I solved by refactoring admin.ts to the following:
So all my exports were functions, instead of instances of
db
andauth
.我遇到了类似的问题,当尝试使用
initializeApp()
时,环境变量未定义@mef27 的解决方案也对我有用。但我正在使用较新版本的 Firebase Admin sdk。
所以对于 2023 年读到这篇文章的人来说,这对我有用:
I had a similar issue where the environment variables where undefined when trying to use
initializeApp()
The solution of @mef27 also worked for me. But i'm using a newer version of the Firebase Admin sdk.
So for anyone reading this in 2023, this worked for me: