如何在Firebase托管的Web应用程序中获取Firebase函数的URL?

5
我正在处理一个项目,其中我们使用Firebase中的预先存在的云函数。我们正在添加一个小型的React SPA,使用Firebase云托管,并且这个SPA将与一些现有的公共云函数进行交互。
到目前为止,我们一直在使用Firebase中的开发和生产项目。对于云函数,这很好用,我们使用firebase functions:config:set设置环境特定配置来区分生产和开发服务器。
问题出现在托管的SPA联系云函数时。我看到了很多关于如何在托管代码中访问环境配置的问题,例如这个问题:如何从Firebase托管应用程序引用Firebase Functions配置变量? 其中答案似乎是要有Firebase函数返回环境变量的值,但对我来说,这只是将问题向后移动了一步。我完全理解,在浏览器中运行SPA会使环境变量对这段代码可访问是一个巨大的安全问题。
我真正需要的仅是托管的SPA的特定环境配置,即云函数的基本地址。
例如,如果我的云函数中有:
const functions = require('firebase-functions');
const express = require('express');
const test = express();
test.on('/hello/:target', (req, res) => {
  res.send(`Hello ${req.params.target}`);
})
exports.test = functions.https.onRequest(test);

部署完毕后,该云函数可在以下两个网址访问:https://us-central1-DEV-PROJECT-NAME.cloudfunctions.net/test/hello/worldhttps://us-central1-PROD-PROJECT-NAME.cloudfunctions.net/test/hello/world。我应该如何最好地获取相应的根网址(https://us-central1-DEV-PROJECT-NAME.cloudfunctions.net 或者 https://us-central1-PROD-PROJECT-NAME.cloudfunctions.net),以便在部署SPA的项目中使用?例如,在前端JS代码中是否可以访问某些全局变量,从而执行以下操作:
const url = `${__FIREBASE_GLOBALS__.cloudFunctions.baseUrl}/test/hello/${input}`;

并且,根据托管应用程序部署的项目来正确定义URL?
2个回答

2
我假设您的SPA除了调用云函数之外,没有其他使用Firebase的方式(因为您没有提到其他方式)。
请阅读Firebase网页设置文档以获取Firebase托管, 特别是SDK导入和隐式初始化部分。当您使用Firebase托管托管网站时,会有一些特殊的URL可以提供该项目的配置。有一些特殊的脚本包含可以让您访问Firebase产品。特别要注意的是,相对路径URI /__/firebase/init.js 将生成JavaScript,该JavaScript将使用您项目的默认设置初始化Firebase JavaScript SDK。请在指向您的Web应用程序的浏览器中访问它。您可能感兴趣的是config的projectId属性。
如果您想获取该值,可以使用Firebase SDK,该SDK将由上述第一个链接中的脚本包含初始化。最少,您可以添加:
<script src="/__/firebase/5.8.2/firebase-app.js"></script>
<script src="/__/firebase/init.js"></script>

稍后(请参阅API文档):
firebase.app().options.projectId

获取 Firebase Hosting 提供内容的项目 ID。您可以使用它来构建函数的 URL。
对于您来说,将 HTTP 函数移植到 可调用函数 并使用 Firebase SDK 从网站调用它们可能也很方便。或者不这样做。

1
谢谢Doug,你说得对,我们在SPA中没有使用任何其他Firebase功能。因此,当我添加这些脚本时,我确实可以从已配置的Firebase应用程序的选项属性中获取projectId,但据我所知,这只是问题URL的一部分,另一部分是某种服务器位置/区域标识符(在我的原始问题中为“us-central1”)。这似乎没有包含在选项对象中,你知道我可以在哪里找到它吗? - Chris O'Kelly
1
是的,即使您使用可调用函数,也必须知道那是什么。这是无法避免的。 - Doug Stevenson
1
哦,这似乎很奇怪,所以没有好的方法让托管的应用程序对其项目配置不可知?在同一项目中的托管应用程序中获取云函数URL肯定是一个常见需求,并且有一个简单的解决方案。 - Chris O'Kelly
Cloud Functions 与 Hosting 实际上没有太多关系,除了 URL 重写外,在这种情况下,函数必须绝对部署到 us-central1。 - Doug Stevenson
firebase.app().options 返回 nullundefined - Shaun Luttin

0
我能够从环境变量中获取区域和应用程序ID。
例如:
console.log(process.env);

请检查您的 Firebase 日志

{ ...
  ENTRY_POINT: 'server',
  X_GOOGLE_FUNCTION_TRIGGER_TYPE: 'HTTP_TRIGGER',
  FIREBASE_CONFIG: '{"projectId":"pid","databaseURL":"https://pid.firebaseio.com","storageBucket":"pid.appspot.com","locationId":"europe-west"}',
  X_GOOGLE_FUNCTION_NAME: 'server',
  FUNCTION_TRIGGER_TYPE: 'HTTP_TRIGGER',
  X_GOOGLE_GCLOUD_PROJECT: 'pid',
  FUNCTION_NAME: 'server',
  X_GOOGLE_GCP_PROJECT: 'pid',
  X_GOOGLE_FUNCTION_REGION: 'us-central1',
  FUNCTION_REGION: 'us-central1',
  X_GOOGLE_ENTRY_POINT: 'server',
  GCLOUD_PROJECT: 'pid',
  GCP_PROJECT: 'pid',
  ... ommited
}

其中GCP_PROJECTGCLOUD_PROJECTFUNCTION_REGIONFUNCTION_NAME应该可以使用。例如:process.env.FUNCTION_REGION

不确定这有多可靠。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接