Reputation: 33
I'm writing an app where it should be possible to invite users to a family. Once the user accepts they become members.
The data looks like this:
families: {
familyKey1: {
name: "First Family Name"
},
familyKey2: {
name: "Second Family Name"
},
},
invites: {
inviteKey1: {
familyKey: "familyKey1",
email: "[email protected]"
}
},
users: {
uid1: {
familyKey: "familyKey2"
}
}
I want a logged in user to be able to access the /families/familyKeyX/
path if:
/users/uidX/
for the currently logged in user./invites/inviteKeyX/
where the email matches the currently logged in user and the invite contains familyKeyXThe first part works fine by creating a rule as follows:
"families": {
"$familyKey": {
".read": "root.child('users').child(auth.uid).child('familyKey').val() == $familyKey"
}
}
The second part however I cannot get to work. It could have been set up the same way if I could post the email as part of the path to the object but firebase does not allow the @
sign so I had to generate the inviteKey
. But that key is unknown when I write the rule and firebase doesn't allow searches or wildcards on the rule path.
I was thinking of making the path {"invites": { "familyKeyX": { "email": "[email protected]"} } }
. But that is a no-go since it only allows for one invite per family. There could be multiple users with different emails with pending invites. As soon I introduce a unique key to form a list of invites I don't know the path to write the rule...
How do I solve this?
Upvotes: 0
Views: 266
Reputation: 598728
In Firebase security rules you can read/check data at a known path in the database. You cannot however search for data under a specific path in the database.
So while in code you could do:
root.child("invites").orderBy("email").equalTo("[email protected]")
The equivalent to this query is not possible in security rules.
In order to be able to look up whether a given email has access to the family, you will need to store the email address of the user as a key in a separate map. Since .
is not allowed inside a key, you'll have to encode that - typically by replacing it with a ,
which is allowed in a key and conveniently cannot appear in an email address.
So:
emailToInvites: {
"user@domain,tld": {
"familyKey1": "inviteKey1"
}
},
Now with this in place, you can replace .
with ,
in the email address and then use that to look up if an invite exists under emailToInvites
.
Upvotes: 1