firebase - Firebase:云功能更改 Firestore 中的数据 - 资源项目的权限被拒绝 [X:YYYYYYYYYY:web:KKKKKKKKKKKK]
问题描述
我正在尝试通过 firebase 云功能将数据添加到我的 firestore 集合中。但是,执行该功能时会出现以下错误。
我的云功能代码是:
import * as functions from "firebase-functions";
import * as admin from "firebase-admin";
admin.initializeApp();
const Firestore = require("@google-cloud/firestore");
const PROJECTID = "[...]";
const firestore = new Firestore({
projectId: PROJECTID,
timestampsInSnapshots: true,
});
exports.createNewChat = functions.region("europe-west1")
.https.onRequest((request, response) => {
console.log("!!!!!!");
console.log("THe BodY: " + request);
console.log("THe BodY: " + request.rawBody);
console.log("THe BodY: " + request.body);
try {
const groupName = request.body.groupName;
const members: string[] = request.body.members;
firestore.collection("chats").add({
groupName: groupName,
members: members,
lastMessage: new Date(),
messages: [],
}).then((doc: any) => {
const chatId = doc.id;
members.forEach((member) => {
firestore.collection("myChats/" + member).add({
chatKey: chatId,
});
});
return response.status(200).send(doc);
});
} catch (e) {
functions.logger.log("catch clause " + e);
response.status(500).send(e);
}
});
我的邮递员请求如下所示:
标头:内容类型 -> 应用程序/json
正文(原始,json):
{ "groupName": "someGroupName", "members": ["123321aklslasl" ] }
抛出的异常是:
!已请求 Google API!
- 网址:“https://oauth2.googleapis.com/token”
- 请注意,这可能是生产服务。(节点:23224)UnhandledPromiseRejectionWarning:错误:7 PERMISSION_DENIED:资源项目的权限被拒绝[...]。在 Object.callErrorFromStatus (E:\Workspaces\cloudFunctions\functions\node_modules@grpc\grpc-js\build\src\call.js:31:26) 在 Object.onReceiveStatus (E:\Workspaces\cloudFunctions\functions\node_modules@ grpc\grpc-js\build\src\client.js:179:52) 在 Object.onReceiveStatus (E:\Workspaces\cloudFunctions\functions\node_modules@grpc\grpc-js\build\src\client-interceptors.js: 336:141) 在 Object.onReceiveStatus (E:\Workspaces\cloudFunctions\functions\node_modules@grpc\grpc-js\build\src\client-interceptors.js:299:181) 在 E:\Workspaces\cloudFunctions\functions\ node_modules@grpc\grpc-js\build\src\call-stream.js:145:78 at processTicksAndRejections (internal/process/task_queues.js:79:11) 原因:\Users\XXXXX\AppData\Roaming\npm\node_modules\firebase-tools\lib\emulator\functionsEmulatorRuntime.js:479:23) 在 Layer.handle [as handle_request] (C:\Users\XXXXX\AppData\Roaming\npm \node_modules\firebase-tools\node_modules\express\lib\router\layer.js:95:5) 在下一个 (C:\Users\XXXXX\AppData\Roaming\npm\node_modules\firebase-tools\node_modules\express\lib \router\route.js:137:13) (node:23224) UnhandledPromiseRejectionWarning: 未处理的承诺拒绝。此错误源于在没有 catch 块的情况下抛出异步函数内部,或拒绝未使用 .catch() 处理的承诺。要在未处理的 Promise 拒绝时终止节点进程,请使用 CLI 标志 \Users\XXXXX\AppData\Roaming\npm\node_modules\firebase-tools\node_modules\express\lib\router\layer.js:95:5) 在下一个 (C:\Users\XXXXX\AppData\Roaming\npm\node_modules \firebase-tools\node_modules\express\lib\router\route.js:137:13) (node:23224) UnhandledPromiseRejectionWarning:未处理的承诺拒绝。此错误源于在没有 catch 块的情况下抛出异步函数内部,或拒绝未使用 .catch() 处理的承诺。要在未处理的 Promise 拒绝时终止节点进程,请使用 CLI 标志 \Users\XXXXX\AppData\Roaming\npm\node_modules\firebase-tools\node_modules\express\lib\router\layer.js:95:5) 在下一个 (C:\Users\XXXXX\AppData\Roaming\npm\node_modules \firebase-tools\node_modules\express\lib\router\route.js:137:13) (node:23224) UnhandledPromiseRejectionWarning:未处理的承诺拒绝。此错误源于在没有 catch 块的情况下抛出异步函数内部,或拒绝未使用 .catch() 处理的承诺。要在未处理的 Promise 拒绝时终止节点进程,请使用 CLI 标志 此错误源于在没有 catch 块的情况下抛出异步函数内部,或拒绝未使用 .catch() 处理的承诺。要在未处理的 Promise 拒绝时终止节点进程,请使用 CLI 标志 此错误源于在没有 catch 块的情况下抛出异步函数内部,或拒绝未使用 .catch() 处理的承诺。要在未处理的 Promise 拒绝时终止节点进程,请使用 CLI 标志
--unhandled-rejections=strict
(见https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode)。(拒绝 ID:3)(节点:23224)[DEP0018] DeprecationWarning:不推荐使用未处理的承诺拒绝。将来,未处理的 Promise 拒绝将使用非零退出代码终止 Node.js 进程。
解决方案
在 Cloud Function for Firebase 中,您应该使用Node.js 的 Admin SDK,而不是标准的 JS SDK。
此外,您需要使用在循环中并行执行对异步方法Promise.all()
的调用。add()
forEach()
因此,以下一组改编应该可以解决您的问题:
import * as functions from "firebase-functions";
import * as admin from "firebase-admin";
admin.initializeApp();
exports.createNewChat = functions.region("europe-west1")
.https.onRequest((request, response) => {
const groupName = request.body.groupName;
const members: string[] = request.body.members;
const db = admin.firestore();
db.collection("chats").add({
groupName: groupName,
members: members,
lastMessage: new Date(),
messages: [],
}).then((doc: any) => {
const chatId = doc.id;
const promises = [];
members.forEach((member) => {
promises.push(db.collection("myChats/" + member).add({
chatKey: chatId,
}));
});
return Promise.all(promises);
})
.then(() => {
response.status(200).send(JSON.stringify(doc));
})
.catch(e => {
functions.logger.log("catch clause " + e);
response.status(500).send(JSON.stringify(e));
});
});
推荐阅读
- ruby-on-rails - Rails Heroku 部署错误:预编译资产失败 – Sprockets::FileNotFound: 找不到类型为 'application/javascript' 的文件 'angular'
- django - Django 服务人员的问题:未捕获的 SyntaxError:意外的令牌 '<'
- node.js - if else MongoDB中基于条件的更新状态
- recursion - 比较 DFS(recursive) + DP(memoization) 与 General Recursion + DP (memoization)
- azerothcore - 世界服务器崩溃
- node.js - 如何在 Typescript 中模拟 Express Req 和 Res
- windows - awk 命令不会在 Windows 上停止以合并大型 csv 文件
- matlab - 如何嵌套循环以使整个事物重复 100 倍
- firebase - 未收到 Flutter iOS 中的通知
- asp.net-web-api - Azure Devops CI/CD CodeCoverage with yml