我正在尝试创建一个Firebase云函数,用于在Google Books API上执行搜索。
export const searchBooksOnline = functions.https.onCall(
async function(data: any, context: functions.https.CallableContext) {
const query: string = data.query;
console.log(`Received query loud and clear: ${query}`);
try {
const res = await fetch(`https://www.googleapis.com/books/v1/volumes?q=${query}&key=MY-API-KEY`);
const json = await res.json();
return json;
} catch(err) {
throw new functions.https.HttpsError(err.status, 'Failed to search books online');
}
}
);
但是每当我从Javascript API调用这个函数时,我都会得到一个错误:
Unhandled error Error: Unknown error code: undefined.
at new HttpsError (/srv/node_modules/firebase-functions/lib/providers/https.js:95:19)
at exports.searchBooksOnline (/srv/lib/books.js:42:15)
at func (/srv/node_modules/firebase-functions/lib/providers/https.js:267:32)
at <anonymous>
at process._tickDomainCallback (internal/process/next_tick.js:229:7)
这对我来说很神秘。我知道函数被正确调用是因为
我可以在Cloud Functions日志"Received query loud and clear:"中看到我的打印。
当我删除
await fetch
行并返回一些伪数据时,该函数将正确执行。
此外,我确信API调用正在工作,因为当我从浏览器的开发人员控制台复制出这几行直接运行时,我会得到预期的API响应。
我不确定导致此错误的Cloud Functions环境有什么不同。(我正在Blaze计划中,这应该允许我向外部网站提出请求(
希望有人能对此有所帮助!
(我也看到过类似的问题,但OP应用的解决方案对我来说没有什么不同,我仍然有同样的错误。(
对API的调用失败,并且您没有正确使用functions.https.HttpsError。根据链接的API文档,构造函数的第一个参数必须是FunctionsErrorCode类型对象,该对象必须是以下字符串之一:
"ok"|"cancelled"|"unknown"|"invalid argument"|超过截止日期"|"未找到"|"已存在|"权限被拒绝"|"资源已用尽"|"失败的前置条件"|"中止"|"超出范围"|"未实现"|"内部"|"不可用"|"数据丢失"|"未经身份验证">
这些字符串每个都映射回一个HTTP状态代码,因此您必须决定实际告诉客户端的内容。如果你只是想指出一个无法解决的故障,那么你可能想要"内部"。
Doug Stevenson的回答并没有直接解决问题,但帮助我诊断了它:
当我按照他的建议修复了HttpsError报告后,我再次尝试调用该函数,这次它给了我一条错误消息,说'fetch' not defined
。事实证明,我从客户端JavaScript成功测试的fetch
并不是在NodeJS(云函数使用的(中本地实现的。
因此,修复方法只是对我的API请求使用不同的方法。在我的例子中,我选择使用nodefetch,它实现了与JavaScriptfetch
函数相同的接口。
所以我唯一需要做的改变就是做
npm install node-fetch @types/node-fetch # the @types package needed for TypeScript
然后
import fetch from 'node-fetch';
在我代码的顶部。