Reputation: 111
so I am trying to match the user email with the collection name like below in my Firestore rules:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userEmail} {
allow read: if request.auth.token.email.matches(userEmail);
}
}
}
I am aware its not good practice to set collection ID's as emails, but please assume it to be any string here. The above does not work. however, if I replace request.auth.token.email.matches(userEmail)
with request.auth.token.email.matches("[email protected]")
it works fine.
Above I have a single document in my users collection with id = [email protected]
, so why is it not matching when I use the userEmail
variable but will match if I use "[email protected]" string?
Additional Info:
Request to /getAccountInfo
you can see [email protected]
as email
App code
I used Vuexfire for firestore binding.
store/index.js
bindUsers: firestoreAction(({bindFirestoreRef}) => {
return bindFirestoreRef("users", db.collection("users")
.where('email', '==', '[email protected]');
}),
App.vue
async mounted() {
if (firebase.auth.currentUser) {
// Bind Vuexfire after if/when user exists to capture Firestore changes
await this.$store.dispatch("bindUsers");
}
}
Upvotes: 1
Views: 575
Reputation: 317292
Your query is filtering on a document property called email (not its ID):
return bindFirestoreRef("users", db.collection("users")
.where('email', '==', '[email protected]');
This has nothing to do with the email token in the user's Firebase Auth account. You haven't shown that you have an email property in the document at all - all you have is a document with an ID that contains an email address.
Your query ultimately needs to match the rule that limits the query. This means that you need some way of explicitly filtering on the client in a way that matches the constraints of the rule. This means you're going to have to use a get()
type query for the specific document with an ID, not a collection query that requires filtering with a where clause.
Upvotes: 1
Reputation: 2798
I could be wrong, but it looks like you are writing your rule more like a filter than as a security rule.
@DougStevenson will know much better than me, but if you hard-code a string value then Firestore can determine explicitly if that rule will succeed or fail. But if you use a variable, then I believe that Firestore determines whether the rule will return true or false in general - not specific runtime cases. In this case, the rule should return false
since there will be rows that fail the test.
It almost looks like you are trying to use your rule to filter out rows. Firestore Rules don't work that way.
As Doug suggests, you should show us some client-side code you are using for accessing that collection so we can determine if the code is falling into the "rule trying to be a filter" trap.
Upvotes: 0