如何在 PC 上本地测试 Cloud Functions for Firebase
Posted
技术标签:
【中文标题】如何在 PC 上本地测试 Cloud Functions for Firebase【英文标题】:how to test Cloud Functions for Firebase locally on pc 【发布时间】:2017-08-01 06:23:09 【问题描述】:今天 Firebase 发布了它的全新产品 Cloud Functions for Firebase,我刚刚创建了一个 hello world 函数并将其部署到我现有的 firebase 项目中。
它看起来就像 aws lambda function 一样捆绑了所有依赖项并将其上传到 firebase。但是即使代码的微小变化也需要花费太多时间,并且还需要良好的互联网连接。如果您由于某种原因处于离线状态,那么在您有办法在本地计算机上离线执行和测试该功能之前,您只是不知道您正在编写什么代码。
有什么方法可以在本地测试 Cloud Functions for Firebase?
【问题讨论】:
【参考方案1】:firebaser 在这里
部署您的函数确实比我通常愿意等待的时间要长。我们正在努力改进这一点,并且(正如 Brendan 所说)正在开发本地模拟器。
但目前,我主要是先将我的实际业务逻辑写入一个单独的 Node 脚本。这样我就可以在本地命令提示符下使用node speech.js
对其进行测试。一旦我对函数的工作感到满意,我要么将其复制/粘贴到我的实际函数文件中,要么(更好)将speech
模块导入我的函数文件并从那里调用它。
我很快找到的一个简短示例是我使用 Cloud Vision API 连接文本提取时。我有一个名为 ocr.js
的文件,其中包含:
var fetch = require('node-fetch');
function extract_text(url, gcloud_authorization)
console.log('extract_text from image '+url+' with authorization '+gcloud_authorization);
return fetch(url).then(function(res)
return res.buffer();
).then(function(buffer)
return fetch('https://vision.googleapis.com/v1/images:annotate?key='+gcloud_authorization,
method: "POST",
headers:
"Content-Type": "application/json"
,
body: JSON.stringify(
"requests":[
"image":
"content": buffer.toString('base64')
,
"features":[
"type":"TEXT_DETECTION",
"maxResults":1
]
]
)
);
).then(function(res)
var json = res.json();
if (res.status >= 200 && res.status < 300)
return json;
else
return json.then(Promise.reject.bind(Promise));
).then(function(json)
if (json.responses && json.responses.length && json.responses[0].error)
return Promise.reject(json.responses[0].error);
return json.responses[0].textAnnotations[0].description;
);
if (process.argv.length > 2)
// by passing the image URL and gcloud access token, you can test this module
process.argv.forEach(a => console.log(a));
extract_text(
process.argv[2], // image URL
process.argv[3] // gcloud access token or API key
).then(function(description)
console.log(description);
).catch(function(error)
console.error(error);
);
exports.extract_text = extract_text;
然后在我的 Functions index.js 中,我有:
var functions = require('firebase-functions');
var fetch = require('node-fetch');
var ocr = require('./ocr.js');
exports.ocr = functions.database().path('/messages/room/id').onWrite(function(event)
console.log('OCR triggered for /messages/'+event.params.room+'/'+event.params.id);
if (!event.data || !event.data.exists()) return;
if (event.data.ocr) return;
if (event.data.val().text.indexOf("https://firebasestorage.googleapis.com/") !== 0) return; // only OCR images
console.log(JSON.stringify(functions.env));
return ocr.extract_text(event.data.val().text, functions.env.googlecloud.apikey).then(function(text)
return event.data.adminRef.update( ocr: text );
);
);
如您所见,最后一个文件实际上只是将“工作方法”ocr.extract_text
连接到数据库位置。
请注意,这是不久前的一个项目,因此某些语法(主要是 functions.env
部分)可能有所改变。
【讨论】:
您能否分享任何实际示例,或至少参考包含您在回答中描述的 hello world program 的任何存储库 测试在实践中是如何工作的?你提到你在命令行运行node speech.js
。但这不测试你程序的操作逻辑是否正确?它只测试我猜的“设置”(即语法、依赖项等)?如果正确,有没有办法在本地测试操作逻辑?
我从命令行传入 GCP 需要的值。所以它测试我的脚本及其与外部 API 的交互。如果数据进入 Cloud Functions,它不会测试实际流量。【参考方案2】:
firebaser 在这里
要在本地调试 Cloud Functions for Firebase,有一个模拟器。请参阅documentation for more info。
【讨论】:
Alpha 版 Firebase 模拟器可用于 https 功能:firebase.google.com/docs/functions/local-emulator @BrianLenoski 似乎调试选项不见了?您提供的链接显示了如何在本地运行,而不是如何调试。【参考方案3】:在本地运行和调试/检查函数
先决条件(google-cloud 功能和特定于 firebase):
npm install -g @google-cloud/functions-emulator
npm install --save firebase-functions
npm install -g firebase-tools
运行和检查/调试:首先在本地运行函数,然后检查每个函数,最后运行每个特定函数以调试+检查它。使用functions start
替代firebase serve
,并注意每个工具的文档都可用(且有用)。
按预期运行和调试特定功能myFn
(例如in Nodejs 通过chrome://inspect
并注意这可以使用Nodejs v10,但不受官方支持):
firebase serve --only functions
functions inspect myFn
functions call myFn # or call from browser
其他文档:
https://firebase.google.com/docs/functions/local-emulator https://cloud.google.com/functions/docs/emulator#debug-emulator https://github.com/GoogleCloudPlatform/cloud-functions-emulator/wiki
【讨论】:
可以做单步吗?允许检查变量的值吗? 我收到Error: FIREBASE FATAL ERROR: Cannot parse Firebase url. Please use https://<YOUR FIREBASE>.firebaseio.com
【参考方案4】:
>> 有什么方法可以在本地测试 Cloud Functions for Firebase?
您可以使用以下命令启动 firebase shell(在您的函数目录中执行):
npm run build && firebase functions:shell
你可以像这样在 shell 中调用你的函数:
helloWorld()
请参阅this 链接了解更多信息。
【讨论】:
【参考方案5】:在这里回答:https://github.com/firebase/firebase-functions/issues/4#issuecomment-286515989
Google Cloud Functions 还开源了一个本地模拟器,我们正在 致力于与 Cloud Functions 建立更紧密的集成 火力基地。同时,您可以在这里查看: https://github.com/GoogleCloudPlatform/cloud-functions-emulator/
模拟器允许您在本地运行函数。这是 解释如何使用它的文档: https://cloud.google.com/functions/docs/emulator
【讨论】:
【参考方案6】:一开始我无法让单步执行。我的过程与此处许多答案中记录的过程相同。
此外,这些页面几乎包含我需要的所有文档:
https://firebase.google.com/docs/functions/local-emulator https://cloud.google.com/functions/docs/emulator#debugging_with_the_emulator我已经使用firebase serve --only functions
运行了函数,但还没有启动并运行调试器。然后我遇到了直接使用模拟器的另一种方式,并设法达到了这样的断点:
# start the emulator
functions start
# allow inspection
functions inspect helloWorld
# call the function from the cli
functions call helloWorld
这行得通,我可以打断点。
但是,当在邮递员或浏览器中点击函数的端点时,我根本没有得到任何响应。
我缺少的步骤是:
# deploy the function to the emulator
functions deploy helloWorld --trigger-http
# you need to toggle inspection after the deploy
functions inspect helloWorld
现在我可以从邮递员或浏览器中命中函数的端点,并命中断点。
我推荐出色的 NiM chrome extension 进行调试,并希望这个答案对某人有所帮助,即使这是一个老问题。
【讨论】:
【参考方案7】:首先,我建议你安装以下依赖项,
npm install --save firebase-functions
npm install -g firebase-tools
如果已经安装,那么您可以将其更新到最新版本。一般来说,functions-emulator 都有上述依赖,但我还是建议你更新它,
npm install -g @google-cloud/functions-emulator
更新后,进入应用程序的functions文件夹并运行以下命令,
firebase serve --only functions
希望对你有帮助!
【讨论】:
【参考方案8】:适用于调试 HTTP 函数(webhooks 等)的 vscode 用户...
谷歌云模拟器 (firebase serve --only functions
) 会启动一个单独的进程来运行您的函数。您可以使用 vscode 附加到此进程,但由于模拟器仅在调用第一个函数之后创建此进程,因此并不简单。
app.get("/processid", function(request, response)
response.send(`$process.pid`);
);
用firebase serve --only functions
启动模拟器
调用http://<localhost_url>/processid
端点。这将创建进程并返回 processID
使用 vscode 附加到指定进程。您现在可以在任何其他函数上设置断点、步骤等(它们都使用相同的过程)。
可能有更好的方法将所有这些粘合在一起。
【讨论】:
我发现在 index.js 的顶部记录 process.pid 更容易。它会针对每个新进程进行评估,并且会在您运行“firebase serve”后立即发生 - 无需发出请求即可获得它。 @Tom 除了这似乎不起作用。正如我所提到的,当调用第一个函数时会启动一个新进程。您可以通过查看 index.js 顶部记录的进程 ID 与 /processid 函数调用返回的进程 ID 不同来验证这一点。 哦,这很奇怪。我很确定它对我有用。我会在下次处理该问题时重新检查 - 也许它的行为在这方面不一致。 感谢@adelphus,这正是我一直在寻找的东西,很好。 如何附加到进程?【参考方案9】:现在有一个云functions emulator that 可以让你在本地调用函数
完成 PoC 后,我将更新此答案以包含我使用的代码和步骤。
【讨论】:
以上是关于如何在 PC 上本地测试 Cloud Functions for Firebase的主要内容,如果未能解决你的问题,请参考以下文章
在本地测试 Python Google Cloud Functions
如何将 Google Cloud Firestore 本地模拟器用于 python 和测试目的
在本地测试 Cloud Functions 时,Cloud Firestore 模拟器未运行