firebase - How do I check the equality of a Firestore Reference in Firestore Security Rules? - Stack Overflow

For background, our database has a letterbox collection with a field called members, an array storing F

For background, our database has a letterbox collection with a field called members, an array storing Firestore references to our users collection. In security rules, we need to check whether a user is a member of a letterbox by verifying if their reference exists in the members array.

In the rules playground, I have attempted to use .hasAny() and hardcoded a user reference, comparing it against the references stored in members. However, all attempts have failed. Debugging suggests that in security rules, Firestore references are converted into path data types, e.g., "/databases/%28default%29/documents/users/$(userId)". (For this message, I replaced the actual userId with a placeholder.)

I have also tried hardcoding paths for direct equality checks, but nothing has worked, and I haven’t found relevant documentation addressing this issue. Could anyone clarify whether checking Firestore references for equality in security rules is possible? If so, what is the recommended approach?

I have tried checking if "/databases/(default)/documents/users/$(userId)" == resource.data.members[0] as well as "/databases/%28default%29/documents/users/$(userId)" == resource.data.members[0] (Resource.data.members[0] is equal to "/databases/%28default%29/documents/users/$(userId)") but it still returns false in both instances.

For background, our database has a letterbox collection with a field called members, an array storing Firestore references to our users collection. In security rules, we need to check whether a user is a member of a letterbox by verifying if their reference exists in the members array.

In the rules playground, I have attempted to use .hasAny() and hardcoded a user reference, comparing it against the references stored in members. However, all attempts have failed. Debugging suggests that in security rules, Firestore references are converted into path data types, e.g., "/databases/%28default%29/documents/users/$(userId)". (For this message, I replaced the actual userId with a placeholder.)

I have also tried hardcoding paths for direct equality checks, but nothing has worked, and I haven’t found relevant documentation addressing this issue. Could anyone clarify whether checking Firestore references for equality in security rules is possible? If so, what is the recommended approach?

I have tried checking if "/databases/(default)/documents/users/$(userId)" == resource.data.members[0] as well as "/databases/%28default%29/documents/users/$(userId)" == resource.data.members[0] (Resource.data.members[0] is equal to "/databases/%28default%29/documents/users/$(userId)") but it still returns false in both instances.

Share Improve this question asked Feb 23 at 12:51 Connor WhiteConnor White 111 silver badge1 bronze badge
Add a comment  | 

1 Answer 1

Reset to default 1

Based on your question, you have data that looks like this:

{
  "letterboxes/letterbox1": { 
    "members": [
      doc(db, "/users/user1"),
      doc(db, "/users/user2"),
      doc(db, "/users/user3"),
    ],
    // ... other fields ...
  }
}

In your security rules, you've defined:

if ("/databases/(default)/documents/users/$(userId)" == resource.data.members[0])

The problem with the above rule is that resource.data.members is a rules.List with elements that are rules.Path objects - not strings.

As strings are not coerced to paths or paths to strings during an equality check, your condition above will always return false.

To work around this, you must convert both sides to a string or both to a path.

if (path("/databases/(default)/documents/users/$(userId)") == resource.data.members[0])

or

if ("/databases/(default)/documents/users/$(userId)" == string(resource.data.members[0]))

In your specific scenario, because you want to check against elements of a rules.List, you will want to use path() to make the value the same type as the entire list and then use the in operator to check if it is contained in the list (which is simpler than hasAny for checking a single element).

if (path("/databases/(default)/documents/users/$(userId)") in resource.data.members)

or

if (path("/databases/(default)/documents/users/" + request.auth.uid) in resource.data.members)

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745154598a4614041.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信