I'll try to explain your .write
security rule, which is:
"root.child('Users').child(auth.uid).child('email').val() === 'testuser@test.com'"
This is indeed not the easiest rule to start with and the Firebase documentation admittedly dives into the deep rather quickly.
After I log on to my application with twitter, my code will get an authData
variable that tells it:
authData
uid: "twitter:4511241"
provider: "twitter"
id: "4511241"
There might be a few more properties, but this should be the gist of it. The authData will typically contain a child object with properties that are specific to the provider, so in this case twitter
and you can normally find some pretty interesting stuff there. Such as in the case of Twitter, the user's twitter name.
authData
uid: "twitter:4511241"
provider: "twitter"
id: "4511241"
twitter:
userName: "puf"
email: "puf@twitter.com" // note: this is just an example email address,
// it doesn't exist (as far as I know)
This object is made available to my code, it is not stored anywhere in Firebase by default.
In your security rules, you can check against the same structure. But only a minimal subset of the information is available here, just enough to identify the user. The Firebase documentation for the auth object names these properties:
provider | The authentication method used ("password", "anonymous", "facebook", "github", "google", or "twitter").
uid |A unique user id, guaranteed to be unique across all providers.
With these properties, we can already allow a specific user write access to our data. Like I said in my comment to your answer:
".write": "auth.uid = 'twitter:4511241'"
This will allow me to write data when I log on with my @puf twitter account. But unfortunately it doesn't allow me to check against more user-friendly properties, such as the email address.
A common practice is to create a top-level Users
node in your Firebase and add all the information for all the users under that node, identified by their uid. So in my case above:
Users
twitter:4511241
userName: "puf"
displayName: "Frank van Puffelen"
email: "puf@twitter.com"
github:913631
userName: "puf"
displayName: "Frank van Puffelen"
email: "puf@github.com"
I left the provider and id off here, since they don't provide much value for the example
When you know a user's uid
, you can look up his additional information in this node. And that is exactly what the security rules you had before does:
"root.child('Users').child(auth.uid).child('email').val() === 'testuser@test.com'"
So this will look from the root of your Firebase, for a node called Users, then for the uid
of the logged in user and under that his/her email address.
The cool thing about checking for a specific email address, is that it is not tied to the user's provider. So no matter whether the user is logged on with twitter, github, facebook or some other supported provider, as long as they used the same email address for each account, they will be able to write the data.