如何解决为什么我的 Firebase 安全规则没有按预期工作?
我希望允许用户在我的应用上编辑他们的帖子。如果他们的 uid 与存储中文件夹的名称匹配,他们就可以编辑他们的帖子。
这是我的 Firebase 存储安全规则:
它说我可以删除图像(users/gafspL9sdVSOXVkxYNlqzxyDbvG2/listingPhotos/lXOxKS1N8dFefzai5H2B/R158bed9819e4fccf7e18a5eeeaf79c6b.png)
然后,当我尝试编辑所述列表时:
我收到 403 错误。未经授权的用户,实际上它在 GET 函数中抛出了这个错误,甚至在删除部分都没有。
正如您在上面看到的,我目前已登录并且我的 uid 是正确的。
错误:(xhrio_network.ts:70 GET mydomainname?prefix=users%2FgafspL9sdVSOXVkxYNlqzxyDbvG2%2FlistingPhotos%2FlXOxKS1N8dFefzai5H2B%2F&delimiter=%2F>p>
这是我要访问的文件夹:
我的文件夹设置:mybucket/users/{userUID}/listingPhotos/{listingID}/picture.jpg
任何想法这里可能出了什么问题?可能是我的代码行不正确,但模拟显示没有问题,所以我有点困惑。
谢谢!
编辑
当用户想要编辑他们的列表时,我会更新存储在 firestore 中的列表详细信息,然后删除存储在 firebase 存储文件夹中的所有照片,然后上传新的一批照片。
这里是我更新列表详细信息并删除现有照片的地方:
function editListingData() {
setLoading("loading");
db.collection("listings")
.doc(listingID)
.set(
{
title: title,category: category,condition: condition,description: description,price: price,sellingFormat: sellingDetails,shippingPrice: shippingPrice,listingPhotos: [],},{ merge: true }
)
.then(() => {
const storageRef = firebase
.storage()
.ref()
.child(
`users/` +
auth.currentUser.uid +
`/listingPhotos/` +
listingID +
`/`
);
storageRef.listAll().then((listResults) => {
const promises = listResults.items.map((item) => {
console.log("deleting item: ",item.name)
return item.delete();
})
Promise.all(promises).then(
onUploadSubmission()
).catch((error => console.log("error deleteing files",error)));
});
})
.then(() => {
setLoading("complete");
setTimeout(() => {
history.push("/l/" + listingID)
},2000);
})
.catch((error) => {
console.log("firebase error: " + error);
setLoading("error");
});
}
这里是我上传新照片的地方,然后将它们的 downloadURL 放入 firestore 文档,以便我以后可以轻松获取它们:
function onUploadSubmission() {
if (photos != []) {
const promises = [];
var listingREF = db.collection("listings").doc(listingID);
photos.forEach((photo,index) => {
if (photo.fileType.includes('image')) {
console.log("current photo to upload: ",photo,"index: ",index)
const uploadTask = firebase
.storage()
.ref()
.child(
`users/` +
auth.currentUser.uid +
`/listingPhotos/` +
listingID +
`/${"photo" + index}`
)
.put(photo.file);
promises.push(uploadTask);
uploadTask.on(
firebase.storage.TaskEvent.STATE_CHANGED,(snapshot) => {
const progress =
(snapshot.bytesTransferred / snapshot.totalBytes) * 100;
if (snapshot.state === firebase.storage.TaskState.RUNNING) {
console.log(`Progress: ${progress}%`);
}
},(error) => console.log(error.code),async () => {
const downloadURL = await uploadTask.snapshot.ref.getDownloadURL();
listingREF.update({
listingPhotos: firebase.firestore.FieldValue.arrayUnion(
{
url: downloadURL,index: index
}
),});
}
);
}
});
Promise.all(promises)
.then(() => setCreatedListing(false))
.catch((err) => console.log(err.code));
} else {
}
}
编辑 2
所以我想要实现的是:
为此,他们将:
- 选择他们的新照片。
- 当他们点击提交时,firebase 将删除当前存储在 firebase 存储中的照片。
- 然后它会上传用户之前选择的新照片。
- 然后将下载 URL 复制到 firestore 中的列表文档,以便我们以后可以轻松查看它们
存储的安全规则是:
- 任何人都可以阅读用户照片(类似于 eBay,您可以看到 列出照片,无论您是否登录)
- 用户只能写入(删除、更新、创建)自己的文件夹。每个文件夹都以用户 UID 命名。只有当当前登录的用户 UID 与存储中的文件夹名称匹配时,他们才能访问这些文件夹。
解决方法
您在 get() 方法上收到的错误是由于该位置的规则缺乏读取该目录的任何权限。
规则从上到下级联,虽然你已经阅读了上面的内容,但这仅适用于指定的路径 users/{userUID}
一旦解决了,我们就可以继续调试了。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。