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

HttpsError when calling Google Books API from Firebase Cloud Function

我正在尝试创建一个 Firebase Cloud Function,用于对 Google 书籍 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)

这对我来说很神秘。我知道该函数被正确调用,因为

此外,我确定 API 调用有效,因为当我直接从浏览器的开发人员控制台将那几行复制到 运行 时,我得到了预期的 API 回应。

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

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

(我看过,但是OP应用的解决方案对我没有影响,我仍然有同样的错误。)

对 API 的调用失败,您没有使用 functions.https.HttpsError correctly. According to the linked API documentation, the first argument to the constructor must be a FunctionsErrorCode 类型对象,它必须是以下字符串之一:

"ok" | "cancelled" | "unknown" | "invalid-argument" | "deadline-exceeded" | "not-found" | "already-exists" | "permission-denied" | "resource-exhausted" | "failed-precondition" | "aborted" | "out-of-range" | "unimplemented" | "internal" | "unavailable" | "data-loss" | "unauthenticated"

这些字符串各自映射回一个 HTTP 状态代码,因此您必须决定您实际上要告诉客户端什么。如果您只想指示无法解决的故障,您可能需要 "internal"。

Doug Stevenson 的 没有直接解决问题,但帮我诊断了:

按照他的建议修复了我的 HttpsError 报告后,我尝试再次调用该函数,这次它给我一条错误消息 'fetch' not definedTurns 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';

在我的代码顶部。