admin管理员组

文章数量:1415460

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)

本文标签: firebaseHow do I check the equality of a Firestore Reference in Firestore Security RulesStack Overflow