代码之家  ›  专栏  ›  技术社区  ›  Brian Ogden

声明单独的Firebase云函数并继续使用快递.js

  •  0
  • Brian Ogden  · 技术社区  · 5 年前

    many examples 对Firebase云函数使用Express。

    exports.app = functions.https.onRequest(app);
    

    对于一个人的Firebase项目功能,这意味着他们将看到一个名为“app”的条目和所有用户的所有日志快递.jsHTTP侦听器将转到Firebase中的一个位置。这也意味着,无论一个人的身体有多大快递.js应用程序是,Firebase将在应用程序的生产中部署单个功能。

    或者,当使用 firebase-functions.https.onRequest 每个导出都有单独的函数,例如,在Typescript中:

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

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

    enter image description here

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

    我希望使用中间件来确保有效的身份验证令牌被传递给我的端点云函数,如下所示 Firebase example 但我不希望使用单一的“应用程序”单一的云功能,我更希望在我的应用程序中使用专用的功能导出索引.js.

    2 回复  |  直到 5 年前
        1
  •  5
  •   Brian Ogden    5 年前

    感谢道格史蒂文森的回答和帮助。不过,我想提供我自己的答案。

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

    正如Doug所指出的,对于许多人的扩展需求来说,这不是一个问题。Firebase将创建多达1000个可扩展的函数实例。

    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)
    

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

    • /付款/行动(RPC)
    • /命令(获取、放置、张贴等)

    另一个好处是,我可以为诸如信用卡支付/处理之类的事情提供“测试”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]
    

    这允许我拥有一个开发环境和一个实时环境。在我的应用程序配置文件中,我只是有一个不同的API url:

    /us-central1/apptest
    

    /us-central1/app
    
        2
  •  4
  •   rphlmr    5 年前

    有趣的讨论。

    我选择了相同的方法:一个“端点”(也就是根路径,比如“/posts”,“/users”)==一个专用的云函数(因为这个原因,它更像“服务”,对我来说就是“lambda函数”)。

    要“干”我的所有功能导入一个“快速”发电机。我在一个地方配置我的express实例。

    const express = () => {
      const express = require("express");
      const cors = require("cors")({ origin: true });
      const morgan = require("morgan");
      const helmet = require("helmet");
    
      const app = express();
    
      app.use(helmet());
      app.use(helmet.noCache());
      app.use(cors);
      app.use(morgan("combined"));
    
      return app;
    };
    
    module.exports = express;
    

    我的“你好”端点:

    const app = require("./../../express")();
    
    /**
     * /hello
     */
    
    app.get("/", (req, res) => {
      return res.send("Hello World");
    });
    
    module.exports = app;
    

    const helloApi = require("./api/hello");
    
    const https = functions.region("europe-west1").https;
    
    module.exports.hello = https.onRequest(helloApi);
    

    似乎很适合我们:)

        3
  •  3
  •   Doug Stevenson    5 年前

    const app = express()
    app.get('/route1', ...)
    app.get('/route2', ...)
    export const f1 = functions.https.onRequest(app)
    export const f2 = functions.https.onRequest(app)
    // etc
    

    现在您可以尝试处理不同函数之间的不同路由(以及它们的不同结果url)。但是您并没有固有地限制某些路由在不同的函数中被调用。由你来确定客户端是否使用了你想要的功能。

    如果出于性能原因而尝试执行此拆分,我会考虑这种过早的优化。云功能将无缝地扩展你的应用程序,而不仅仅是一个服务器实例。像这样分解你的职能 可以 如果您希望超过 documented limits contact support 以帮助解释部署过程中出现的问题。

    custom StackDriver logging ,这将帮助您更好地组织和监视函数生成的不同类型的日志。