从Firebase云函数调用Google Books API时出现HttpsError



我正在尝试创建一个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';

在我代码的顶部。

相关内容

  • 没有找到相关文章

最新更新