从 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)
这对我来说很神秘。我知道该函数被正确调用,因为
我可以在 Cloud Functions 日志中看到我的打印 "Received query loud and clear:"。
当我删除 await fetch
行和 return 一些虚拟数据时,该函数正确执行。
此外,我确定 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 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 书籍 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
行和 return 一些虚拟数据时,该函数正确执行。
此外,我确定 API 调用有效,因为当我直接从浏览器的开发人员控制台将那几行复制到 运行 时,我得到了预期的 API 回应。
我不确定导致此错误的 Cloud Functions 环境有何不同。 (我使用的是 Blaze 计划,应该允许我向外部网站发出请求)
希望有人能帮助阐明这一点!
(我看过
对 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 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';
在我的代码顶部。