【问题标题】:how to write auth based Firestore Rules for specific collections如何为特定集合编写基于身份验证的 Firestore 规则
【发布时间】:2021-05-23 07:54:21
【问题描述】:

我有一个名为Orders 的集合,我还有两个其他集合UsersDrivers。我希望 Orders 集合只能由 Drivers 集合中的 UID 访问。

所有登录到应用程序的人都是用户,但Drivers 是唯一可以访问Orders 文档的用户。

逻辑是检查用户是否已签名并且Drivers 集合包含具有该用户的UID 的字段。如果集合字段包含该用户的 UID,则他可以访问该文档集合。

allow write, read: if isSignIn() & `Driver colletion contains that user UID`

我该怎么做?如果我需要一些帮助来编写该代码?

这是我的规则,我并没有改变太多。我所知道的是这段代码适用于我数据库中的每个文档,所以我需要写一些细节

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow write, read: if isSignIn();
    }
    
    function isSignIn(){
    return request.auth != null;
    }
    
  }
}

这是我从 Firestore 获取数据的方式

func newOrders(){
        
        let fireStore = Firestore.firestore()
        let doc = fireStore.collection("Orders")
        
        self.driverListener = doc.addSnapshotListener { (query, err) in
            if err != nil {
                print(err?.localizedDescription ?? "")
            }
            guard let querysnap = query else {return}
            
            querysnap.documentChanges.forEach({ change in
                
                if change.type == .added {
                    
                self.DriverOffers = []
                for document in querysnap.documents{
                        
                    let snap = document.data()

                guard let orderLoc = snap["orderLocation"] as? GeoPoint else {return}
                    
                guard let docId = snap["docId"] as? String else {return}
                guard let name = snap["name"] as? String else {return}
                guard let phone = snap["phone"] as? String else {return}
                guard let time = snap["time"] as? String else {return}
                guard let marketName = snap["marketName"] as? String else {return}
                guard let price = snap["amount"] as? String else {return}
                guard let userImg = snap["userImg"] as? String else {return}
                guard let storeImg = snap["storeImg"] as? String else {return}
                guard let order = snap["order"] as? String else {return}
                guard let userid = snap["userUid"] as? String else {return}
                guard let timestamp = snap["date"] as? Timestamp else {return}
                let date = Date(timeIntervalSince1970: TimeInterval(timestamp.seconds))

                guard let userlocation = snap["userLocation"] as? GeoPoint else {return}

                    let offer = driverOrdersData(docId: docId, userUid: userid, name: name, phone: phone, amount: price, time: time, marketName: marketName, storeimgUrl: storeImg, userImgUrl: userImg, date: date, orderDetails: order, orderLocation: orderLoc, userLocation: userlocation, distance1: distance1, distance2: distance2 )
                    
                    self.DriverOffers.append(offer)
                    DispatchQueue.main.async {
                    self.DriverOrdersTV.reloadData()

                    }
                    }
                
            }
            }
        })
        
        }

}

【问题讨论】:

  • 你能分享一下其他收藏的截图吗?
  • @Dharmaraj 我已经更新了问题
  • @Swift:我看到你不接受我的回答。你能澄清一下它还缺少什么吗?
  • 在尝试了几天后,这个答案实际上没有用,我只是在 XCode 调试器中获得了文档的权限失败,但我仍然从该集合中获取文档@FrankvanPuffelen跨度>
  • 如果文档已经在本地缓存中(例如:如果您在缓存后更改规则,或者如果它是为具有访问权限的其他用户读取的)缓存返回文档 - 即使服务器没有。细节取决于你如何实现读取操作,你没有分享,但由于这不应该是一个正常的用例,如果在开发过程中发生这种情况,我建议卸载并重新安装应用程序以清除缓存的数据。

标签: firebase google-cloud-firestore firebase-authentication firebase-security


【解决方案1】:

您无法在安全规则中检查是否存在具有特定值的文档,因为这将需要您的规则来查询集合,并且成本高昂且无法扩展。

实现这个用例(以及许多其他用例)的技巧是使用用户的 UID 作为 Drivers(可能还有 Users)集合中的文档 ID。你可以通过添加类似的文件来做到这一点

let uid = ....; // wherever you get the UID from
firebase.firestore().collection("Drivers").doc(uid).set({ uid: uid });

现在有了该结构,您可以检查具有特定 UID 的文档是否存在在您的安全规则中,这是可能的:

function isDriver() {
  return exists(/databases/$(database)/documents/Drivers/$(request.auth.uid))
}

另请参阅 accessing other documents in security rules 上的 Firebase 文档。

【讨论】:

    猜你喜欢
    • 2019-02-13
    • 2018-04-04
    • 1970-01-01
    • 2019-03-25
    • 1970-01-01
    • 2019-04-04
    • 2019-07-15
    • 2019-01-23
    • 1970-01-01
    相关资源
    最近更新 更多