我有一个使用firebase服务帐户的节点应用程序。我想将应用程序部署到Heroku,但我不想公开我的秘密密钥。我直接从公共github仓库部署,所以我不想在部署中包含服务帐户文件。
我可以使用服务帐户json文件,使每个属性成为环境变量,将每个变量添加到Heroku并进行部署。一切都很好(在我的firebase应用程序上授权新的Heroku域之后),但是有更好的方法吗?这是有效的,但这样做很麻烦(复制和粘贴每个变量并移动它)。我错过了一种更简单的方法吗?
这是我正在做的改变。从这行从文件中提取凭据:
admin.initializeApp({
credential: admin.credential.cert('./path/firebase-service-account.json'),
databaseURL: "https://my-firebase-app.firebaseio.com"
});
对于从环境变量引入所有相同内容的对象:
admin.initializeApp({
credential: admin.credential.cert({
"type": process.env.FIREBASE_TYPE,
"project_id": process.env.FIREBASE_PROJECT_ID,
"private_key_id": process.env.FIREBASE_PRIVATE_KEY_ID,
"private_key": process.env.FIREBASE_PRIVATE_KEY,
"client_email": process.env.FIREBASE_CLIENT_EMAIL,
"client_id": process.env.FIREBASE_CLIENT_ID,
"auth_uri": process.env.FIREBASE_AUTH_URI,
"token_uri": process.env.FIREBASE_TOKEN_URI,
"auth_provider_x509_cert_url": process.env.FIREBASE_AUTH_PROVIDER_X509_CERT_URL,
"client_x509_cert_url": process.env.FIREBASE_CLIENT_X509_CERT_URL
}),
databaseURL: "https://my-firebase-app.firebaseio.com"
});
这是将带有服务帐户的firebase应用程序部署到Heroku的最佳做法吗?我正在使用dotenv节点模块来完成此任务。
答案 0 :(得分:28)
证书选项对象有两个必填字段:clientEmail
和privateKey
。您的示例可以缩减为:
admin.initializeApp({
credential: admin.credential.cert({
"private_key": process.env.FIREBASE_PRIVATE_KEY,
"client_email": process.env.FIREBASE_CLIENT_EMAIL,
}),
databaseURL: "https://my-firebase-app.firebaseio.com"
});
顺便说一下,某些环境可能会遇到private_key
env var中的换行问题;我发现key.replace(/\\n/g, '\n')
是一个简单的解决方案。
答案 1 :(得分:6)
openssl base64 -in <firebaseConfig.json> -out <firebaseConfigBase64.txt>
或使用如下所示的Node.js Buffer.from(JSON.stringify({
"type": "",
"project_id": "",
"private_key_id": "",
"private_key": "",
"client_email": "",
"client_id": "",
"auth_uri": "",
"token_uri": "",
"auth_provider_x509_cert_url": "",
"client_x509_cert_url": ""
})).toString('base64')
GOOGLE_CONFIG_BASE64
这样的env变量中。 (如果是Heroku,请将其保存到ConfigVars)const firebaseAdminSdk = require('firebase-admin'),
firebaseAdminApp = firebaseAdminSdk.initializeApp({credential: firebaseAdminSdk.credential.cert(
JSON.parse(Buffer.from(process.env.GOOGLE_CONFIG_BASE64, 'base64').toString('ascii')))
});
答案 2 :(得分:3)
这是一种与我个人在将应用部署到使用 firebase 服务帐户的 heroku 时更喜欢使用的最佳答案略有不同的方法。
const admin = require("firebase-admin");
require("dotenv").config();
const serviceAccount = JSON.parse(process.env.GOOGLE_CREDS);
admin.initializeApp({
credential: admin.credential.cert(serviceAccount)
});
将服务帐户密钥文件中的内容复制为 JSON,并将 GOOGLE_CREDS 设置为在您的 .env 中采用此值。确保默认删除 JSON 中的所有换行符,因为 .env 会将其作为字符串读取。 下面是它的外观示例: .env sample
以相同的格式复制相同的键值并将其粘贴到您的 heroku 配置变量中。
希望对您有所帮助,谢谢。
答案 3 :(得分:1)
我刚刚使用了 Diokas 解决方案,并进行了以下改进: .env 只是:
注意对于 admin sdk 需要完整的配置文件....
FIREBASE_CREDS={"type","projectId","private_key","client_email"}
FIREBASE_DATABASE_URL=...
然后
var admin = require('firebase-admin');
require('dotenv').config();
const serviceAccount = JSON.parse(process.env.FIREBASE_CREDS);
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: process.env.FIREBASE_DATABASE_URL,
});
var db = admin.database();
module.exports = db;
答案 4 :(得分:0)
FWIW 我和@Huzaifa 做了同样的事情,除了没有对 JSON 字符串进行 base64 编码,到目前为止它对我来说很好:
const firebaseAdminSdk = require('firebase-admin');
// login and return a ref to the root of the firebase
function loginToFirebase() {
// JSON stored in this env variable must come from Firebase Admin SDK service account's private key:
// https://console.firebase.google.com/u/0/project/<your firebase>/settings/serviceaccounts/adminsdk
const googleAuthJson = process.env.GOOGLE_AUTH_JSON;
if (!googleAuthJson) throw new Error('The $GOOGLE_AUTH_JSON environment variable was not found!');
return firebaseAdminSdk.initializeApp({
credential: firebaseAdminSdk.credential.cert(JSON.parse(googleAuthJson)),
databaseURL: "https://<your firebase>.firebaseio.com"
}).database();
}