Firebase 如何为特定集合编写基于身份验证的Firestore规则
我有一个名为Firebase 如何为特定集合编写基于身份验证的Firestore规则,firebase,google-cloud-firestore,firebase-authentication,firebase-security,Firebase,Google Cloud Firestore,Firebase Authentication,Firebase Security,我有一个名为Orders的集合,还有另外两个为用户和驱动程序的集合。我希望Orders集合只能由Drivers集合中的UID访问 所有登录到应用程序的人都是用户,但是驱动程序是唯一可以访问订单文档的用户 逻辑是检查用户是否已签名,以及Drivers集合是否包含包含该用户UID的字段。如果集合字段包含该用户的UID,则他可以访问该文档集合 allow write, read: if isSignIn() & `Driver colletion contains that user UID`
Orders
的集合,还有另外两个为用户
和驱动程序
的集合。我希望Orders
集合只能由Drivers
集合中的UID访问
所有登录到应用程序的人都是用户,但是驱动程序
是唯一可以访问订单
文档的用户
逻辑是检查用户是否已签名,以及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()
}
}
}
}
})
}
}
您无法在安全规则中签入文档中是否存在具有特定值的文档,因为这将需要您的规则查询集合,而且成本高昂且无法扩展 实现此用例(以及许多其他用例)的诀窍是在
驱动程序
(可能还有用户
)集合中使用用户的UID作为文档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))
}
另请参阅上的Firebase文档。您可以分享屏幕截图中其他收藏的外观吗?@Dharmaraj我已经更新了quistion@Swift我看你没有接受我的回答。你能澄清一下它还缺少什么吗?在尝试了几天之后,这个答案实际上不起作用,我只是在XCode调试器中获得了文档的权限失败,但如果文档已经在本地缓存中,我仍然从集合@FrankVanpuffelle获取文档(例如:如果在缓存规则后更改了规则,或者为具有访问权限的其他用户读取了规则)缓存可能会返回文档,即使服务器没有返回。具体情况取决于您如何实现读取操作,您没有共享该操作,但由于这不应该是一个正常的用例,因此我建议卸载并重新安装应用程序,以清除在开发过程中发生的缓存数据。