声明单独的Firebase Cloud Functions并仍使用Express.js

Bri*_*den 5 node.js express firebase firebase-authentication google-cloud-functions

许多使用Express for Firebase Cloud Functions的示例

在我发现的每个示例中,代码都将Express应用程序公开为单个Cloud Function:

exports.app = functions.https.onRequest(app);
Run Code Online (Sandbox Code Playgroud)

对于一个人的Firebase项目功能,这意味着他们将看到一个名为“ app”的条目,并且所有Express.js HTTP侦听器的所有日志都将转到Firebase中的一个位置。这也意味着,无论Express.js应用程序有多大,Firebase都会在该应用程序的生产环境中部署单个功能。

另外,在使用firebase-functions.https.onRequest每种导出时,例如在Typescript中,您可以获得单独的功能:

export const hello = functions.https.onRequest(async (req, res) => {
  res.status(200).send('hello world');
});
Run Code Online (Sandbox Code Playgroud)

在Firebase控制台中,我有hello函数,在index.js中还有另一个函数:

在此处输入图片说明

这也意味着Firebase将为每个函数创建不同的节点/实例:helloemphemeralKey

我将在Firebase控制台中为每个功能获得单独的日志记录。

我想使用中间件来确保将有效的身份验证令牌传递给我的端点Cloud Functions(例如Firebase示例),但是我不希望不使用单个“ app”单个Cloud Function,而希望在函数导出中使用专用函数我的index.js。

Bri*_*den 5

感谢 Doug Stevenson 的回答和帮助。我想提供我自己的答案。

所以我的问题的答案是,一般来说:不,你不能。

正如 Doug 指出的那样,这对于许多人的扩展需求来说不是问题。Firebase 将创建最多 1,000 个函数实例以进行扩展。

我想提供一个与 Doug 略有不同的答案,说明我将如何编写 Express 应用程序并为项目提供不同的 Firebase 云函数:

const payment = express()
const order = express()
payment.get('/route', ...)
order.get('/route', ...)
export const payment = functions.https.onRequest(payment)
export const order = functions.https.onRequest(order)
Run Code Online (Sandbox Code Playgroud)

这里的优点是我可以开始表达 REST 或 RPC 路由,例如:

  • /付款/某些操作(RPC)
  • /order(获取、放置、发布等)

另一个好处是,我可以为信用卡支付/处理之类的事情提供“测试”API 和“实时”API:

// [START Express LIVE App]


// [START get user]
app.get('/user', async (req, res) => {
  await handleGetUser(req, res, paymentServiceLive);
});
// [END get user]

// [START claim]
app.post('/claim', async (req, res) => {
  await handleClaim(req, res, claimEmailTo);
});
// [END claim]

// [START user]
app.post('/user', async (req, res) => {
  await handleUserPost(req, res, paymentServiceLive);
});
// [END user]

// [START ephemeralKey]
app.post('/ephemeralKey', async (req, res) => {
  await handleEphemeralKey(req, res, paymentServiceLive);
});
// [END ephemeralKey]


// [START charge]
app.post('/charge', async (req, res) => {
  await handleCharge(req, res, paymentServiceLive);
});
// [END charge]

// [START purchase]
app.post('/purchase', async (req, res) => {
  await handlePurchase(req, res, paymentServiceLive);
});
// [END purchase]

//Expose Express API as a single Cloud Function:
exports.app = functions.https.onRequest(app);

// [END Express LIVE App]



// [START Express TEST App]

// [START get user]
appTest.get('/user', async (req, res) => {
  console.log('appTest /user get', req);
  await handleGetUser(req, res, paymentServiceTest);
});
// [END get user]

// [START claim]
appTest.post('/claim', async (req, res) => {
  await handleClaim(req, res, claimEmailToTest, true);
});
// [END claim]


// [START user]
appTest.post('/user', async (req, res) => {
  console.log('appTest /user post', req);
  await handleUserPost(req, res, paymentServiceTest);
});
// [END user]

// [START ephemeralKey]
appTest.post('/ephemeralKey', async (req, res) => {
  await handleEphemeralKey(req, res, paymentServiceTest)
});
// [END ephemeralKey]


// [START charge]
appTest.post('/charge', async (req, res) => {
  await handleCharge(req, res, stripeTest);
});
// [END charge]

// [START purchase]
appTest.post('/purchase', async (req, res) => {
  await handlePurchase(req, res, paymentServiceTest);
});
// [END purchase]

//Expose Express API as a single Cloud Function:np
exports.apptest = functions.https.onRequest(appTest);

// [END Express TEST App]
Run Code Online (Sandbox Code Playgroud)

这让我有一个开发环境和一个现场环境。在我的应用程序配置文件中,我只有一个不同的 API url:

/us-central1/apptest
Run Code Online (Sandbox Code Playgroud)

或者

/us-central1/app
Run Code Online (Sandbox Code Playgroud)

  • 我来这里是为了回答这个问题,并得出了与您对这个答案所做的相同的结论。我还看到了拆分它们的另一个正当理由,即您可以更轻松地从控制台和 API 级别查看错误、性能、延迟和内存等。当所有 API 都捆绑在同一个函数下时,很难确定 1 是否为异常值。@DougStevenson 对吗?或者还有其他解决方法 (3认同)