Firebase Storage结合Firestore规则失效,上传权限疑问
Firebase Storage规则问题排查与解答
问题描述
我正尝试使用Firebase Storage JS SDK上传图片,并配置了基于Firestore数据的存储规则。
上传代码
imageList.forEach(element => { tasks.push(firebaseStorage.child("Devices").child(dateTime).child(element.name).put(element, { contentType: element.type })) });
存储规则
rules_version = '2'; service firebase.storage { match /b/{bucket}/o { match /Devices/{deviceId} { // Authentication is required. allow create: if request.auth.uid != null && // Only Admins are capable of uploading images. firestore.exists(/databases/(default)/documents/Admins/$(request.auth.uid)); // Authentication is required. allow read: if request.auth.uid != null && // Only Cashiers are capable of reading images. firestore.exists(/databases/(default)/documents/Cashiers/$(request.auth.uid)); // No update or deletion of files in client (web) for now. allow update, delete: if false } } }
目前规则未生效并出现错误(见附图),请问问题出在哪里?另外,上传操作是否同时需要读和写权限?
问题排查与解答
1. 规则路径匹配错误
你的上传路径是Devices/{dateTime}/{element.name},但现有规则仅匹配Devices/{deviceId}——这里的{deviceId}只会匹配一级子路径(即dateTime这一层),不会递归覆盖其下的文件。Firebase Storage规则默认不递归匹配子目录,因此当前规则无法作用到你实际上传的文件上。
修复方案:修改规则,添加递归匹配符号{allPaths=**},让规则覆盖Devices目录下所有层级的文件:
rules_version = '2'; service firebase.storage { match /b/{bucket}/o { match /Devices/{deviceId}/{allPaths=**} { allow create: if request.auth.uid != null && firestore.exists(/databases/(default)/documents/Admins/$(request.auth.uid)); allow read: if request.auth.uid != null && firestore.exists(/databases/(default)/documents/Cashiers/$(request.auth.uid)); allow update, delete: if false } } }
2. 上传操作的权限需求
单纯的文件上传(调用put方法)只需要create权限,不需要read权限。但如果上传后需要获取文件的下载URL,此时会触发读取操作,就需要配置read权限。如果仅需完成上传动作,无需后续读取,仅保留create权限即可。
额外排查点
- 确认当前用户已完成Firebase认证,
request.auth.uid不为空 - 检查Firestore的
Admins集合中,是否存在以当前用户UID命名的文档(规则依赖该文档存在) - 使用Firebase控制台的规则模拟器,模拟上传场景输入对应路径和用户UID,验证规则逻辑是否生效
内容的提问来源于stack exchange,提问作者Bitwise DEVS
相关产品推荐
相关产品推荐

