You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firebase Firestore规则配置:仅允许用户访问自身上传的照片

问题:Firestore规则配置实现用户仅访问自己上传的照片

问题背景

我正在开发一款可上传照片的简易APP,使用Firebase Firestore与Storage。每次上传新照片时,会创建如下Item对象:

struct Item: Codable, Identifiable {
 var id: UUID // photo name
 var uidOwner: String // uid user owner
 var emailOwner: String // email user owner
 var path: String // photo path
 var shared: [String] = []
}

需要配置Firestore规则,实现仅允许每个用户查看自己上传的照片,当前Firestore数据路径为photos集合下的单文档结构。

当前Firestore规则

当前使用的规则仅针对单文档做权限检查,在Firestore Playground中有效,但在Xcode中执行全集合查询时请求被拒绝(推测是规则无法验证全集合下的文档权限):

rules_version = '2';

service cloud.firestore {
match /databases/{database}/documents {
    match /photos/{photo} {
          allow read: if resource.data.uidOwner == request.auth.uid;
    }
}

iOS端请求代码(补充编辑)

当前iOS端获取照片列表的代码是直接读取整个photos集合:

func downloadImagesName(){
    self.isLoading = true
    self.itemsPhoto = []
    // Reference
    let imagesCollectionRef = db.collection("photos")

    imagesCollectionRef.getDocuments(completion: { snapshot, error in
        if let error = error {
            print("Errore durante il recupero dei documenti: \(error.localizedDescription)")
            self.isLoading = false
            return
        }
        
        snapshot?.documents.forEach { doc in
            do {
                let item = try doc.data(as: Item.self)
                self.itemsPhoto.append(item)
                
                if doc == snapshot?.documents.last {
                    self.isLoading = false
                }
                
            } catch {
                print("Errore durante la conversione dei dati: \(error.localizedDescription)")
                self.isLoading = false
            }
        }
        self.isLoading = false
    })
}

解决方案

问题核心在于:Firestore安全规则会拒绝无过滤条件的全集合查询,因为规则无法批量验证每个文档的uidOwner是否匹配。需要同时调整规则和请求代码:

1. 更新Firestore规则

修改规则,同时支持单文档读取和带过滤条件的集合查询,还可以补充写入权限的校验:

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    match /photos/{photo} {
      // 允许用户读取自己的文档:单文档读取或带uidOwner过滤的查询
      allow read: if request.auth != null 
                  && (resource.data.uidOwner == request.auth.uid 
                      || request.query.where('uidOwner', '==', request.auth.uid));
      // 确保只有用户自己能上传/修改属于自己的文档
      allow write: if request.auth != null 
                   && request.resource.data.uidOwner == request.auth.uid;
    }
  }
}

2. 修改iOS请求代码,添加查询过滤

在集合查询时必须带上uidOwner等于当前用户UID的过滤条件,这样规则才会允许查询执行:

func downloadImagesName(){
    self.isLoading = true
    self.itemsPhoto = []
    
    // 先确认用户已登录,获取当前用户UID
    guard let currentUserUID = Auth.auth().currentUser?.uid else {
        print("用户未登录,无法获取照片")
        self.isLoading = false
        return
    }
    
    // 添加过滤条件,只查询当前用户的照片
    let imagesCollectionRef = db.collection("photos")
                                .whereField("uidOwner", isEqualTo: currentUserUID)

    imagesCollectionRef.getDocuments(completion: { snapshot, error in
        if let error = error {
            print("Errore durante il recupero dei documenti: \(error.localizedDescription)")
            self.isLoading = false
            return
        }
        
        snapshot?.documents.forEach { doc in
            do {
                let item = try doc.data(as: Item.self)
                self.itemsPhoto.append(item)
            } catch {
                print("Errore durante la conversione dei dati: \(error.localizedDescription)")
            }
        }
        self.isLoading = false
    })
}

注意点

  • 必须确保上传Item到Firestore时,uidOwner字段确实被设置为当前登录用户的UID,否则即使规则和查询正确,也无法读取到文档。
  • Firestore安全规则不会自动过滤不符合条件的文档,而是直接拒绝整个不符合规则的查询,所以查询必须携带对应的过滤条件。

内容的提问来源于stack exchange,提问作者matteog

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 00:52:06