javascript - Firebase Cloud Function with Google Secrets Manager 如何让 async/await 工作
问题描述
我有一个小问题,我的 firebase 云功能在我通过调用 Google Secret Manager API 获得 API 密钥之前完成。API 密钥很重要,因为它通过 API 调用从外部服务器获取数据,以将 API 调用的结果存储在 Google Cloud Storage 中。
这是我的代码,
'use strict';
// Request Data From A URL
var request = require('request');
var https = require('https');
// Var Firebase Functions
var functions = require('firebase-functions');
const admin = require('firebase-admin');
// Initalise App
admin.initializeApp();
// init firebase admin and get the default project id
const projectId = admin.instanceId().app.options.projectId
const util = require('util');
// Imports the Google Storage client library
const {Storage} = require('@google-cloud/storage');
// Import the Secret Manager client and instantiate it:
const {SecretManagerServiceClient} = require('@google-cloud/secret-manager');
const secretClient = new SecretManagerServiceClient();
// Setting Timeout in Seconds - default is 1 second
// The maximum value for timeoutSeconds is 540, or 9 minutes. Valid values for memory are:
// 128MB, 256MB, 512MB, 1GB, 2GB
const runtimeOpts = {
timeoutSeconds: 300,
memory: '512MB'
}
let apikey = '';
// From were the data comes
// 1 = Shoreserver
var shipid = '1';
// Get the current date
var today = new Date();
var dd = String(today.getDate()).padStart(2, '0');
var mm = String(today.getMonth() + 1).padStart(2, '0'); //January is 0!
var yyyy = today.getFullYear();
today = '0000' + '-' + '00' + '-' + '00';
// Creates a storage client
const storage = new Storage({
projectId: projectId,
});
// Set Bucket Name
const bucket = storage.bucket('masterlog');
/**
* Delete a file from a storage bucket and download a new file from remote location to store in the bucket
*/
exports.getEmilyAPItoStorage = functions
.runWith(runtimeOpts)
.region('europe-west1')
.https.onRequest((req, res) => {
// Get Secret
***(async () => { apikey = await getSecret() })***
console.info(`ApiKey Secret: ${apikey}`);
// First we want to delete the current file, the filename is always the same.
// Delete files in the Bucket people
bucket.deleteFiles({
prefix: `people.json`
})
.catch( (err) => {
console.log(`Failed to delete people.json`);
});
// Start of the requesting different tables
// Table to get data from
var apitable = 'people';
// Set destination filename
const people = bucket.file('people.json');
var url = 'https://<URL>/api/' + shipid + '/' + apitable + '?apikey=' + apikey + '&syncdate=' + today;
// Set the options to make the request
var options = {
url: url,
strictSSL: false,
secureProtocol: 'TLSv1_method'
}
// Make a request for the API and store the file in Storage
request(options)
.pipe(people
.createWriteStream({sourceFormat: 'NEWLINE_DELIMITED_JSON'}))
.on('finish', function(error) {
if (error) {
console.log(error);
res.status(500).send(error);
} else {
console.log( "- done!")
res.status(200).send("OK");
}
});
// End Function with status code 200
// Set destination filename
const agents = bucket.file('agents.json');
// Table to get data from
var apitable = 'ports';
var url = 'https://emily.greenpeace.net/api/' + shipid + '/' + apitable + '?apikey=' + apikey + '&syncdate=' + today;
// Set the options to make the request
var options = {
url: url,
strictSSL: false,
secureProtocol: 'TLSv1_method'
}
// Make a request for the API and store the file in Storage
request(options)
.pipe(agents
.createWriteStream({sourceFormat: 'NEWLINE_DELIMITED_JSON'}))
.on('finish', function(error) {
if (error) {
console.log(error);
res.status(500).send(error);
} else {
console.log( "- done!")
res.status(200).send("OK");
}
});
// End Function with status code 200
async function getSecret() {
// Access the secret.
const resource_name = 'projects/' + projectId + '/secrets/emilyapikey/versions/latest';
let [version] = await secretClient.accessSecretVersion({name: resource_name})
console.info(`Found secret ${version.payload.data} with state ${version.state}`);
apikey = version.payload.data;
return apikey;
}
});
我可以在函数 getSecret() 中从 Google Secrets Manager 获取 API 密钥,当我将 API 密钥设置到我的服务器时,API 密钥不可用。我的期望是 getSecret 将在执行其余代码之前完成。
如果有人能洞察她我所缺少的东西,我真的很想听听你的意见。
解决方案
如果您想在任何函数中使用 async/await,则必须将该函数声明为 async:
exports.getEmilyAPItoStorage = functions
.runWith(runtimeOpts)
.region('europe-west1')
.https.onRequest(async (req, res) => { ... })
然后您可以在其正文中的代码中等待:
const apikey = await getSecret()
推荐阅读
- python - 如何将 numpy ndarray 转置到位?
- ios - QtCreator 缺少 iOS 模拟器和工具包
- javascript - javascript Instagram登录访问控制允许来源错误
- javascript - 如何使用字体真棒作为传单中的图标而不是标记
- php - PHP Reforce 搜索引擎
- java - Java 到 C++ 异或加密失败
- python - Python:Google Maps API,CSV 文件上的 TypeError
- android - 压缩android studio文件
- apache-spark - 为什么在 YARN 上执行两次 spark-shell 会导致第二次挂起?
- swift - 导航控制器没有可疑地工作