Firestore:查询和安全 (Swift)

Posted

技术标签:

【中文标题】Firestore:查询和安全 (Swift)【英文标题】:Firestore: Queries and Security (Swift) 【发布时间】:2018-05-26 03:37:58 【问题描述】:

TL;DR 如何对安全的 Firestore 集合执行查询?

在 Firestore 中具有以下安全规则:

service cloud.firestore 
    match /databases/database/documents 
        match /users/userId 
          allow read, update, delete: if request.auth.uid == userId;
          allow create: if request.auth.uid != null;
            
    

目前,文档ID是userId,每个文档中还有一个字段是userId。如果我使用文档 ID 直接转到特定文档,我可以找到该文档:

let docRef = db.collection("users").document(userId)
docRef.getDocument  (document, error) in
    if let document = document, document.exists 
        let dataDescription = document.data().map(String.init(describing:)) ?? "nil"
        print("Document data: \(dataDescription)")
     else 
        print("Document cannot be read or does not exist")
    

但是,如果我随后执行查询并告诉它只带回那些 userId 字段与当前登录用户相同的文档,则会失败并出现“缺少权限或权限不足”安全错误。

db.collection("users").whereField("userId", isEqualTo: userId).getDocuments()  (querySnapshot, err) in
    if let err = err 
        print("Error getting documents: \(err)")
     else 
        for document in querySnapshot!.documents 
            print("\(document.documentID) => \(document.data())")
        
    

那么,我如何要求 Firestore 仅安全地查找其 userId 字段与登录用户的 userId 匹配的那些文档?

谢谢。

【问题讨论】:

改用.whereField(FieldPath(["userId"]), isEqualTo: userId)怎么样? 另外,在规则中你也可以使用allow read, update, delete: if request.auth.uid == request.resource.data.userId; @Guy Kogus 使用 .whereField(FieldPath(["userId"]), isEqualTo: userId) 还会生成错误“获取文档时出错:Error Domain=FIRFirestoreErrorDomain Code=7 '缺少权限或权限不足。 '" 【参考方案1】:

这行得通:

allow read, update, delete: if resource.data.userId == request.auth.uid;

【讨论】:

以上是关于Firestore:查询和安全 (Swift)的主要内容,如果未能解决你的问题,请参考以下文章

如何从Swift中的Cloud FireStore Firebase访问特定字段

努力在 Firestore Swift 中使用 getDocuments() 进行查询

包含数组的查询的 Firestore 安全规则

如何使用 swift 有条件地向 Firebase Firestore 中的查询添加另一个过滤器?

Swift Firestore 来自查询的自定义对象,同时使用 snapshotListener 监听实时更新

如何在 Swift 中重构重复的 Firestore 文档 ID?