typescript - 部署后本地运行HTTP功能时无法访问存储文件
问题描述
所以我的firestore集合用户中有一些错误的记录:图像字段(错误的路径:users/uid/name.jpg,预期输出:
https://firebasestorage.googleapis.com/v0/b/project-id.appspot.com/o/users%2F4yWeML3ktpVt6oWowtEhg8oJx1I3%2Fcropped828392415291985722.jpg?alt=media&token=6daeeab9-6b34-4a27-a4d5-0789a7d773c3
) - 存储中的图像保存为:
users > user_id > cropped{fileName}.jpg
所以我写了一个云函数来从桶'用户'中获取所有文件
import * as functions from "firebase-functions";
import * as admin from "firebase-admin";
import { Storage } from "@google-cloud/storage";
admin.initializeApp({
credential: admin.credential.cert({
projectId: "myProjectId",
clientEmail:
"firebase-adminsdk-myAdmin@project-id.iam.gserviceaccount.com",
privateKey:
"-----BEGIN PRIVATE KEY-----\nmyprivatekey=\n-----END PRIVATE KEY-----\n"
}),
storageBucket: "myProject.appspot.com"
});
const db = admin.firestore();
const storage = new Storage({
projectId: "myProjectId",
credentials: {
client_email: "firebase-adminsdk-myAdmin@project-id.iam.gserviceaccount.com",
private_key: "-----BEGIN PRIVATE KEY-----\nMyPrivateKey=\n-----END PRIVATE KEY-----\n"
}
});
export const updateUserImage = functions.https.onRequest((request, response) => {
const wrongData: any = [];
db.collection("users")
.where("image", ">=", "/users")
.orderBy("image", "asc")
.get()
.then(res => {
res.forEach(ele => {
if (ele.data().hasOwnProperty("image")) {
console.log(ele.data().image.includes("/firebasestorage"));
if (!ele.data().image.includes("/firebasestorage")) {
wrongData.push(ele);
}
}
});
console.log('Wrong docs: ' + wrongData.length);
for (const doc of wrongData) {
const getFileName = doc.data().image.split("/")[3];
const subFolder = doc.data().image.split("/")[2];
console.log(getFileName);
storage.bucket('users').file(`${subFolder}/${getFileName}`).get()
.then((fileData: any) => {
console.log(fileData);
}).catch(err => console.log(err))
}
})
.catch(err => console.log(err));
}
);
我部署了此功能,然后使用 firebase 模拟器在本地进行测试,所有包都在 package.json 中更新为最新:
"dependencies": {
"@google-cloud/firestore": "^2.2.6",
"@google-cloud/storage": "^3.1.0",
"@google/maps": "^0.5.5",
"@types/google__maps": "^0.5.5",
"express": "^4.17.1",
"firebase": "^6.3.5",
"firebase-admin": "^8.3.0",
"firebase-functions": "^3.2.0"
},
但是,当我通过命令进行调试时:firebase serve --only functions
即使管理 SDK 可以获取数据,但是当从存储中获取文件时,它会抛出错误:
{ Error: firebase-adminsdk-xtk2b@project-id.iam.gserviceaccount.com does not have storage.objects.get access to users/4yWeML3ktpVt6oWowtEhg8oJx1I3/cropped828392415291985722.jpg. }
我上网并设置了谷歌云存储的权限 - 此帐户的谷歌云平台控制台,包括角色:
Firebase admin SDK 管理代理(生成 json 时由 Google 默认)
存储管理员
所有者
存储对象管理员
然后等待 5 分钟,但当我尝试在本地调用该函数时仍然出现同样的错误。配置中缺少什么吗?我对云功能和云存储有点陌生
解决方案
您的代码正在尝试访问名为“users”的存储桶中的文件:
storage.bucket('users')
但我 100% 确定您的存储桶名称不是“用户”。存储桶名称与出现在存储桶中的“文件夹”的名称不同。您的存储桶的名称更有可能与您的项目 ID 匹配,或者它是您在创建它时编造的全球唯一名称(在所有 Google Cloud 中的所有项目中的所有存储桶中)。
推荐阅读
- tensorflow - 限制小数点后的数字(四舍五入)而不破坏TensorFlow中的梯度
- sql - 提高 oracle 中 Merge 语句的性能
- java - 实现 Externalizable 时是否需要显式默认构造函数?
- javascript - 每个循环中的赛普拉斯等待命令
- python - 我找不到从 Python 中的单引号 JSON 中提取数据的方法
- python - 使用熊猫比较excel中的两列
- javascript - 使用纯 javascript 是否可以将未显示在窗口上的元素复制到剪贴板?
- amazon-web-services - 为什么我的仪表板中的 https://www.awseducate.com/ 缺少“AWS 账户”选项卡?
- r - R中的Cox PH时间相关协变量格式
- python-3.x - Lambda 函数中的 Boto3 - RequestsDependencyWarning