我可能错过了一些简单的事情。我已经坚持这个问题有一段时间了,这很关键。任何帮助将不胜感激。
我有一个 firestore 存储数据库,其规则允许每个人读取(查看)图像。
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /images/{userId} {
allow read: if true;
allow write: if request.auth != null && request.auth.uid == userId;
}
match /videos/{userId} {
allow read: if true
allow write: if request.auth != null && request.auth.uid == userId;
}
}
}
然而,当我刷新特定页面时,我得到:
Uncaught (in promise) FirebaseError: Firebase Storage: User does not have permission to access 'images/BJBAPfJMTCOq9OypfdkZ9z1NtQ93'. (storage/unauthorized)
列出属于特定用户的所有图像的代码:
export default function MultiMedia({ handleUser }) {
const imageListRef = useRef(ref(storage, `images/${handleUser}`));
const [imageList, setImageList] = useState([]);
useEffect(() => {
listAll(imageListRef.current).then((response) => {
response.items.forEach((item) => {
getDownloadURL(item).then((url) => {
setImageList((prev) => [...prev, url]);
});
});
});
}, []);
return...
令人困惑的是,图像确实在不同的页面上呈现,该主页从 Firestore 数据库中提取,该数据库将图像 url 和 uid 作为字段以及其他字段。
export default function ImageGallery() {
const [imageData, setImageData] = useState([]);
useEffect(() => {
async function reloadHome() {
try {
const querySnapshot = await getDocs(collection(db, "images"));
querySnapshot.forEach((doc) => {
setImageData((prevValue) => {
return [
...prevValue,
{ imageURL: doc.data().imageURL, user: doc.data().user },
];
});
});
} catch (error) {
console.log(error);
}
}
reloadHome();
}, []);
图像文件夹的 Firestore 安全性:
rules_version = '2';
service cloud.firestore {
match /images/{image} {
allow read: if true;
allow create: if isLoggedIn();
allow update, delete: if isLoggedIn() && request.auth.uid == resource.data.user;
}
}
我希望阻止用户在从 Firebase 存储中提取的用户个人资料上看到图像的存储安全规则与阻止同一用户看到下载网址存储在Firestore 数据库。
最佳答案
由于您在 users/{userId}
上使用 listAll()
,我假设该前缀下有多个文件,并且它不是单个对象。在这种情况下,您必须为该前缀内的对象以及您现在正在执行的路径指定规则。例如,您当前的规则将允许读取对象images/user1.png
。尝试使用 recursive wildcard如下图:
match /images/{userId}/{file=**} {
allow read: if true;
allow write: if request.auth != null && request.auth.uid == userId;
}
此外,您可以只更新一次状态,而不是在循环的每次迭代中更新状态:
useEffect(() => {
listAll(imageListRef.current).then(async (response) => {
const promises = response.items.map((item) => getDownloadURL(item));
const urls = await Promise.all(promises);
setImageList(urls);
})
}, []);
关于javascript - Firebase 存储安全规则拒绝读取权限,即使 "allow read: if true",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75887617/