Hi,
I've been struggling with this problem for many days now. I've done my research and if I cannot make this work I don't know what to do.
From my Swift application I want to retrieve all documents from a collection based on the criterias below (I'm using Firestore).
Preferred approach
The preferred approach is to store the parents as a map.
Database
/familyMembers/{familyMemberId}
{
parents
{
userId1
userId: "userId1"
userId2
userId: "userId2"
}
}
Security rules
match /anotherCollection/{familyMemberId}
{
allow read, write: ?
}
Query from Swift code
db.collection("familyMembers").whereField("parents.\(userId).userId", isEqualTo: userId).getDocuments()
Second approach
Since the first approach might not be feasible due to difficulties finding a proper security rule, I was hoping that this approach could work.
Database
/familyMembers/{familyMemberId}
{
parents: ["userId1", "userId2"]
}
Security rules
match /anotherCollection/{familyMemberId}
{
allow read, write: if request.auth.uid in get(/databases/$(database)/documents/familyMembers/$(familyMemberId)).data.parents;
// note, I'm not intereseted in solutions relative to the resource such as "if request.auth.uid in resource.data.parents"
}
Queries tried out from Swift code
db.collection("familyMembers").whereField("parents", in: [userId]).getDocuments()
db.collection("familyMembers").whereField("parents", arrayContains: userId).getDocuments()
Research
According to my research, what I'm trying above SHOULD work, but it's not working.
Some findings
I've read all firestore security rules related documentation (such as "rules are not filters", the query has to match the rule).
Final
None of the above approaches works. I've tried it out multiple times from the actual project and not only the online emulator. Apart from above I've also tried numerous other ways and still get Permission Denied.
This seems to me like a common case, and it's crucial for it to work for the project I'm working on. I really hope someone could help me on this.
--
You received this message because you are subscribed to the Google Groups "Firebase Google Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to firebase-tal...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/firebase-talk/8b3487b2-99f0-4c0e-92ed-37f33ca5ce26%40googlegroups.com.
Hi Jannica,In your second case I still think the issue comes down to "rules are not filters". Remember that for a query (a "list" operation) to work the rules engine has to be able to prove, without touching the database, that all possible results will be allowed by the rule. Because your rule has a get() request in it this is automatically impossible. I would expect that rule to work for a single document get operation, but it won't work for a query that can return multiple documents.- Sam
To unsubscribe from this group and stop receiving emails from it, send an email to fireba...@googlegroups.com.
To unsubscribe from this group and stop receiving emails from it, send an email to firebase-tal...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/firebase-talk/4ba58ff2-9b52-4176-aa0f-7ba10192bca4%40googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/firebase-talk/CAHafJBrNvAM7_DnBQioTN-CvRYJivttc_B2JHD-18FK3hDyqOA%40mail.gmail.com.
If docs are accessed by family, then you can probably avoid a lot of complexity by just flattening your family map and structuring your docs by family. So something like the following. The rules would become fairly trivial at this point:
/family/{familyId}/members/{userId} => { isParent: boolean, name: ... }/family/{familyId}/docs/{docId} => { ... }A simple way to use the current setup would be to create functions that trigger whenever you add/remove a member in /familyMembers/{familyMemberId} and create a map of permissions for use in rules. Although it's very unclear how you link a parent to their docs right now, so I left that part up to you. Here's an example with rules and functions code to support. Here's an unrelated example I wrote some time back, that is likely interesting for ideas.All of these are valid and as a general rule, structuring your data appropriately for how it will be accessed and used is the key. You may want to check out Todd's series on Firestore, which includes some great videos on data structures and rules.☼, Kato
On Wed, May 27, 2020 at 6:56 AM 'Sam Stern' via Firebase Google Group <fireba...@googlegroups.com> wrote:
Hey Jannica,My previous response was a bit too broad. You can use get() in a query rule but the reason it's a problem for you is because your get() path is being built from the match { } path. So each result needs to make a different get() to know if it can be read, and that is not something we can allow in the engine.Could you keep a list of accessible documents per user? Then your rule would look more like this:match /anotherCollection/{familyMemberId} {
allow read, write: if request.auth.uid in get(/databases/$(database)/documents/userAccess/$(request.auth.uid)).data.parents;
}- Sam
To view this discussion on the web visit https://groups.google.com/d/msgid/firebase-talk/4ba58ff2-9b52-4176-aa0f-7ba10192bca4%40googlegroups.com.
--
You received this message because you are subscribed to the Google Groups "Firebase Google Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fireba...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/firebase-talk/CAHafJBrNvAM7_DnBQioTN-CvRYJivttc_B2JHD-18FK3hDyqOA%40mail.gmail.com.
To unsubscribe from this group and stop receiving emails from it, send an email to firebase-tal...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/firebase-talk/91a41865-4f67-4466-a528-02a305461758%40googlegroups.com.