Unable to access field that has hyphen in it - firebase

I am struggling to write a firebase rule that is checking the user id that is stored in a document. Hardcoding a given value as a string works
allow write: if request.auth.uid == 'user-id-hardcoded';
,however I am unable to find a way to dynamically address it. I am left with the impression it's due to the hyphen in the document field after checking this question - Firebase security rules : How can I use dashes or hyphen in paths?. I also tried to substitute user-id with userId to no avail.
allow write: if request.auth.uid == resource.data.user-id;
Any help will be appreciated.

If your field name in document contains a hyphen then use the brackets notation instead:
allow write: if request.auth.uid == resource.data["user-id"];

I checked this link, it looks like the hyphen will be detected start or end of a structural component.
FirebaseVisionDocumentText.RecognizedBreak

Related

How to allow all users to read only certain documents with a field " friend : true "

In Firestore i have the collection as "users" and document id are random numbers.
Now i need to allow the users to read the documents which contains field friend : true
I have tried following rules :
match /users/{document=**}
{
allow read : if request.resource.data.friend = true;
}
match /users/{document=**}
{
allow read : if resource.data.friend = true;
}
But yet i can't read the documents which contains friend = true.
Please help me
My first guess is that you're not passing the same condition in with the read operation. Keep in mind that Firebase security rules do not filter data. Instead they "merely" ensure that the read operation is allowed. So the second rules in your snippet allow this query:
firebase.firestore().collection("users").where("friend", "=", true)
If you don't pass the where condition, the read will be rejected as you're trying to read all documents, which the security rules don't allow. Only when the query and the rules match up, will the read be allowed.
Your first rules fragment cannot work in any case, as request.resource only has meaning in the context of write operations. From the docs:
request.resource
The new resource value, present on write requests only.

Firebase firestore security rules allow if document ID contains string

I have got the following:
match /direct/{postId} {
allow read, write: if postId.includes(request.auth.uid);
}
However, I would like to only allow read, write if the document ID (postId) contains the string. .includes is not working for me in security rules.
Edit: it should match a substring instead of the entire document id
Edit2
collection called direct where each document ID is a string which contains 2 uids in it’s name.
Any help would be appreciated. Thanks.
The document ID is a string, and as far as I can see the String class in security rules doesn't have an include method.
It does have a matches method though, so you can use that to test whether the document ID contains a substring with a regular expression.
Something like:
match /direct/{postId} {
allow read, write: if postId.matches(request.auth.uid);
}
A working read where the postId matches the UID of the user:
Trying to read another document:
Update: to test for a substring:
allow read: if postId.matches(".*"+request.auth.uid+".*");

how to check if a filename contains uid in firebase storage security rules?

I want to make a rules in my firebase storage, and I want the filename of image stored in firebase storage contains uid of its uploader. usually in programming language I use .contains to check
service firebase.storage {
match /b/{bucket}/o {
match /eventThumbnail/{imageID} {
allow create: if request.resource.name.contains(request.auth.uid)
}
}
}
is this rules valid ? I can't find documentation about using contains in firebase storage security rules documentation. actually the rules is more complex, I still search what makes I fail to create an image, and I suspect that rules is not valid
You can use something like this:
match /{fileName} {
allow read: if fileName[0:6] == 'abcdef';
}
Documentation on string rules:
https://firebase.google.com/docs/reference/security/storage#string
The API documentation for security rules for Cloud Storage is here. The specific documentation for string type objects is here. You can see that in the documentation, there is no "contains" method for string. But there is a method for using a regular expression to verify the contents of a string using matches().
However, I think Frank is correct in his comment suggesting that it would be better to use a dedicated prefix for each user using their UID in the path of the file. For example "/eventThumbnail/{uid}/{file}" could be used to determine the permissions for any file organized under uid, where uid could simply be verified as equal to request.auth.uid (no substrings or regular expression required). This is also far more secure and reliable than checking file substrings.
Filename can now be used as UID and matched using Firebase storage split syntax found here.
I do also recommend rather using the path to prefix each UID instead, but if the files are already in a production environment the split syntax could prove useful.
Update:
Syntax on Firebase Documentation appears to be incorrect as indicated by this post

How to properly write Regex validation in Firestore Security Rules

I'm trying to validate submitted data against Regex expressions in Firestore Security Rules. I've read through the documentation, but I'm still unsure how to write them.
I read through the Regex documentation here https://firebase.google.com/docs/reference/security/database/regex , but it doesn't really show how to use it in Firestore. I tried using an 'allow validate' rule and copy/pasted a regex expression from the docs, but I'm getting all kinds of errors.
Here's what I tried:
Do I need to put it in a format like this? (From the docs) allow create: if !("ranking" in request.resource.data)? If so, how do I use a regex expression with it?
It looks like you're trying to start a regex with /. That's not going to work - it's not like perl. Slash starts a path object. Might want to check the API documentation on this. You should just be passing a plain string to matches() that contains the regex to match.
https://firebase.google.com/docs/reference/rules/rules.String#matches

Firebase Security Rules: Guard against reserved chars

Firebase has certain reserved characters:
., $, #, [, ], /
How do I block these characters from being added into my database in security rules?
Use .validate along with matches(). matches() accepts regular expressions. contains() checks if the string contains the specified value.
This would be if you were writing an object like this: {"post": "he.lo"}
".validate": "!(newData.child('post').val().matches(/[.$\/#]/) || newData.child('post').val().contains(']') || newData.child('post').val().contains('['))"
And if you were just writing a string: "he.lo"
".validate": "!(newData.val().matches(/[.$\/#]/) || newData.val().contains(']') || newData.val().contains('['))"
I tried for quite some time to include "[" and "]", but Firebase didn't like them which is why I added the contains() methods.
These rules would be used for checking against values and, as #Frank said, not keys.
Reference: Firebase 3.0 Security Rules
These characters cannot be used in database keys, but can be used in database values.
The Firebase Database will automatically rejects write operations where such characters appear in a key, you don't have to write any rules for that.

Resources