从 Firebase Cloud Function 调用 Google Books API 时出现 HttpsError

Posted

技术标签:

【中文标题】从 Firebase Cloud Function 调用 Google Books API 时出现 HttpsError【英文标题】:HttpsError when calling Google Books API from Firebase Cloud Function 【发布时间】:2020-06-19 13:19:09 【问题描述】:

我正在尝试创建一个在 Google Books API 上执行搜索的 Firebase Cloud Function。

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 日志中看到我的打印“接收到的查询响亮而清晰:”。

当我删除await fetch 行并返回一些虚拟数据时,函数正确执行。

此外,我确信 API 调用正在工作,因为当我复制这几行代码以直接从浏览器的开发者控制台运行时,我得到了预期的 API 响应。

我不确定导致此错误的 Cloud Functions 环境有何不同。 (我正在使用 Blaze 计划,这应该允许我向外部站点发出请求)

希望有人可以帮助阐明这一点!

(我见过this similar issue,但是OP应用的解决方案对我没有任何影响,我仍然有同样的错误。)

【问题讨论】:

【参考方案1】:

对 API 的调用失败,并且您没有正确使用 functions.https.HttpsError。根据链接的 API 文档,构造函数的第一个参数必须是 FunctionsErrorCode 类型的对象,它必须是以下字符串之一:

“好的” | “取消” | “未知” | “无效参数” | “超过最后期限” | “未找到” | “已经存在” | “权限被拒绝” | “资源枯竭” | “失败的前提条件” | “中止” | “超出范围” | “未实现” | “内部” | “不可用” | “数据丢失” | “未经身份验证”

这些字符串每个都映射回 HTTP 状态代码,因此您必须确定您实际告诉客户端的内容。如果您只想指示无法解决的故障,您可能需要“内部”。

【讨论】:

不是我期望的解决方案,而是我需要的解决方案。非常感谢!这帮助我弄清楚出了什么问题 - 请参阅下面的答案:)【参考方案2】:

Doug Stevenson 的answer 并没有直接解决问题,而是帮我诊断:

当我按照他的建议修复了我的 HttpsError 报告后,我尝试再次调用该函数,这一次它给了我一条错误消息,说 'fetch' not defined。 Turns out 我从客户端 JavaScript 成功测试的 fetch 并未在 NodeJS(Cloud Functions 使用)中原生实现。

所以解决方法只是对我的 API 请求使用不同的方法。就我而言,我选择使用node-fetch,它实现了与JavaScript fetch 函数相同的接口。

所以我需要做的唯一改变就是做

npm install node-fetch @types/node-fetch # the @types package needed for TypeScript

然后

import fetch from 'node-fetch';

在我的代码顶部。

【讨论】:

以上是关于从 Firebase Cloud Function 调用 Google Books API 时出现 HttpsError的主要内容,如果未能解决你的问题,请参考以下文章

从请求中获取用户信息到 Firebase 中的 Cloud Function

如何从 Cloud Function 获取 Firebase 项目名称或 ID

从 Firebase Cloud Function 连接到 Stripe 时出错

从 Firebase Cloud Function 调用 Google Books API 时出现 HttpsError

如何使用 Cloud Function 将数据从 Firebase Firestore 索引到 Elastic App Search?

如何从 Firebase Cloud Function 在 Google Pub/Sub 中发布消息?