使用Google Firebase托管和功能测试和部署应用程序的最佳设置/工作流

时间:2018-03-04 20:17:42

标签: firebase google-cloud-functions firebase-hosting firebase-cli

我使用vuejs构建了一个小型Web应用程序(www.suntax.de)并托管在Google Firebase上。我使用Firebase托管,数据库和功能。我使用函数在后端进行一些计算。

现在一切都在运行,但是我遇到了一些麻烦,有些事情我希望改进我的工作流程。 因此,我想向你解释一下我做了什么以及我现在在哪里努力。

首先,我将vuejs应用程序设置为部署到firebase。我添加了我的自定义域名,一切都很好。 后来我实现了云功能,想要从我的vuejs应用程序拨打电话。 在firebase deploy之后,我可以在浏览器中调用此函数,它可以正常工作: https://us-central1-suntax-6d0ea.cloudfunctions.net/calcEEGcompensation?year=2013&month=1&size=10

现在我想,我只是从我的vuejs app调用该函数的URL。但后来我收到以下错误消息: [Error] Origin * is not allowed by Access-Control-Allow-Origin.

我当时读到我必须在rewrite中添加firebase.json部分:

现在我的firebase.json看起来像这样:

{
  "database": {
    "rules": "database.rules.json"
  },
  "hosting": {
    "public": "public",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    // Add the following rewrites section *within* "hosting"
   "rewrites": [ {
      "source": "/calcEEGcompensation", "function": "calcEEGcompensation"
    } ]
  }
}

现在我可以使用以下URL调用我的firebase函数: https://www.suntax.de/calcEEGcompensation?year=2013&month=1&size=10

在我的vuejs应用程序中集成上述URL后,应用程序在部署到firebase服务器后运行正常。

由于我想继续改进应用程序,我想在部署之前在本地测试所有内容。

我知道我可以通过以下方式在本地运行firebase托管和功能: firebase serve --only functions,hosting

但是,现在我的应用程序对我的函数https://www.suntax.de/calcEEGcompensation?year=2013&month=1&size=10进行了硬编码调用,这再次导致错误[Error] Origin * is not allowed by Access-Control-Allow-Origin.

但也将URL更改为本地函数 http://localhost:5001/suntax-6d0ea/us-central1/calcEEGcompensation?year=2013&month=1&size=10 导致错误消息 [Error] Origin * is not allowed by Access-Control-Allow-Origin.

进一步的阅读使我找到了cors的解决方案。所以我把我的功能改为:

const functions = require('firebase-functions');
const cors = require('cors')({origin: true});

exports.calcEEGcompensation = functions.https.onRequest((req, res) => {
    cors(req, res, () => {
        const yearOfCommissioning = req.query.year;
        const monthOfCommissioning = req.query.month;
        const pvsystemsize = req.query.size;

        ...

        res.send("hello");
    });
});

这有帮助,现在一切正常: - 部署的应用程序仍然正常运行。 - 我可以在调用本地函数和已部署函数的同时在本地运行应用程序。我只需要更改函数的URL。

但现在这是我的问题: 我能以更好的方式解决这个问题吗?如果我在本地测试vuejs应用程序和函数,我必须在部署之前更改函数URL。然后我必须在本地测试时将其更改回来。 没有cors,我无法在本地测试我的应用程序和功能。

我理想的解决方案是设置一个设置,可以在本地进行全面测试,并且可以使用firebase deploy轻松部署,而无需更改网址。这可能吗?

谢谢和最诚挚的问候, 克里斯托弗

2 个答案:

答案 0 :(得分:2)

我发现这个解决方案非常简单,完全符合我的要求。我不知道为什么我之前没弄清楚。 这是我做的:

我只是从我的firebase托管中调用相对URL:

calcEEGcompensation?year=2013&month=1&size=10

如果在firebase.json

中正确设置了重写,一切正常
{
  "database": {
    "rules": "database.rules.json"
  },
  "hosting": {
    "public": "public",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    // Add the following rewrites section *within* "hosting"
   "rewrites": [ {
      "source": "/calcEEGcompensation", "function": "calcEEGcompensation"
    } ]
  }
}

在设置完所有内容后,我可以执行firebase serve --only functions,hosting,我可以在本地测试所有内容。 执行firebase deploy后,一切都在服务器上顺利运行。

我不需要cors

感谢@wonsuc的回答。

答案 1 :(得分:1)

更新(适用于Firebase托管):
目前,您无法使用Firebase Hosting SDK解决此问题 但是有另一种方法可以实现这一目标。

在托管来源中尝试以下代码。

if (location.hostname === 'localhost' || location.hostname === '127.0.0.1') {
    console.log('It's a local server!');
}

在我看来,这些是目前检查开发环境的最佳方式 因此,您应该在Firebase托管中使用location.hostname,在云功能中使用server.address()

用常量变量定义函数终点。

const DEBUG = location.hostname === 'localhost' || location.hostname === '127.0.0.1';
const FUNCTIONS_ENDPOINT_DEV = 'http://localhost:5001/';
const FUNCTIONS_ENDPOINT_PRD = 'https://us-central1-something.cloudfunctions.net/';
const FUNCTIONS_URL_CALC = 'calcEEGcompensation?year=2013&month=1&size=10';

var endpoint;
if (DEBUG) {
    endpoint = FUNCTIONS_ENDPOINT_DEV + FUNCTIONS_URL_CALC;
} else {
    endpoint = FUNCTIONS_ENDPOINT_PRD + FUNCTIONS_URL_CALC;
}

原始答案(适用于Firebase的Cloud Functions):
您是否尝试过node.js网络模块的server.address()功能?
此方法将告诉您功能代码是在localhost还是在实际部署的服务器上运行。

例如,您可以这样使用。

const server = app.listen(function() {
    let host = server.address().address;
    let port = server.address().port;

    if (!host || host === '::') {
        host = 'localhost:';
    }

    console.log('Server is running on %s%s', host, port);
});