Firebase查询,妨碍集合组查询的规则

时间:2020-08-03 07:16:29

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

就在我以为自己掌握了窍门时,查询规则给我扔了一个曲线球:(

我有以下查询规则:

// Needed for collection group (Member) query
// https://firebase.googleblog.com/2019/06/understanding-collection-group-queries.html
match /{rootPath=**}/Members/{member} {
    allow read: if request.auth != null;
}

这很简单,只需要一个授权用户即可。集合组查询可以按预期完美运行。

现在,我想再进行一次查询以获取成员文档:

Firebase.firestore.collection("Companies\\$companyID\\Members").get().await()

查询返回错误(PERMISSION_DENIED)。

我也尝试为这样的成员添加规则:

match /Companies/{companyID} {
    allow read: if request.auth != null &&
                isMember(database, companyID, request.auth.uid)
      
    match /Members/{member} {
        allow read: if request.auth != null 
    }
}

仍然,同样的错误。

这是文档路径:

document path

我查看了一些资源,但没有发现任何建议的解决方案:

Understanding Collection Group Queries in Cloud Firestore

Recursive wildcards

3 个答案:

答案 0 :(得分:0)

我将其发布为答案,因为评论太长了。

您是否尝试过以下示例规则:

service cloud.firestore {
  match /databases/{database}/documents {
    match /Companies/{companyID}/Members/{member} {
      allow read, write: if <condition>;
    }
  }
}

如先前在documentation you shared中所述,它基于具有分层数据的结构化规则?

答案 1 :(得分:0)

我建议您看看以下documentation,在其中可以找到一些示例:

service cloud.firestore {
  match /databases/{database}/documents {
    match /Companies/{companyID}/Members/{memberID} {
      // Only authenticated users can read
      allow read: if request.auth != null;
    }
  }
}

使用上述安全规则,任何经过身份验证的用户都可以检索任何单个公司成员

db.collection("Companies/{companyID}/Members").get()

现在,如果您希望对集合组查询应用相同的安全规则,则必须使用版本2

rules_version = '2';
service cloud.firestore {

  match /databases/{database}/documents {
    // Authenticated users can query the posts collection group
    // Applies to collection queries, collection group queries, and
    // single document retrievals
    match /{path=**}/Members/{memberID} {
      allow read: if request.auth != null;
    }
  }
}

任何经过身份验证的用户都可以检索任何单个公司成员

但是,如果您想向某个用户显示其在所有公司中的成员,该怎么办?您可以使用集合组查询从所有成员集合中检索结果:

  var user = firebase.auth().currentUser;
    
  db.collectionGroup("members").where("author", "==", user.uid).get()

注意:此查询要求将需要composite index作为成员集合。如果您尚未启用此索引,查询将返回一个错误链接,您可以通过该链接创建所需的索引。

答案 2 :(得分:-1)

您可以尝试使用“ match / {path = **} / Members / {member}”代替rootPath。我没有使用后者,但是前者在其他项目中为我工作。