Firebase firestore security rules allow if document ID contains string - firebase

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+".*");

Related

Firebase Storage Security Rules - Does the match statement match for strings placed anywhere in a filename?

Accordingly to this section in the official docs, these security rules:
service firebase.storage {
match b/{bucket}/o {
// Matches any filename containing string '/images/'.
match /images/{imageId} {
allow read, write: if false;
}
// Matches all filenames containing string `/images/`
match /images/{imageId=**} {
allow read, write: if true;
}
}
}
All reads and writes to files with the string /images/ anywhere in their filename will be allowed because the second rule is always true, even though the first rule is always false.
I understand the naming conventions to emulate a file system and the overlapping stuff... but, does that "anywhere" mean these permissions apply to filenames like /foo/bar/images/profilePicture.png? (Just asking because it is strange to me, I supposed rules won't apply to files with another prefix, just supposed they must start with images)
That actually looks like a mistake in that sample. As far as I know the first match /images/{imageId} matches file that are immediately under the images filter, while the second match /images/{imageId=**} also matches files that are in deeper nested folders under /images.

Unable to access field that has hyphen in it

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

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 Security Rules Regex in Path

I have security rule write like this :
/databases/{database}/documents {
match /collection_COUNTRY_EN/{docId} {
allow....
}
match /collection_COUNTRY_ES/{docId} {
allow...
}
}
Where the rule are identical to all the country. Is there a way to implement regex in the match /path to have the same rule for all the collection that start with something and end with a country code ?
Or does i have to structure my data in a different way ?
Thanks for your time.
Security rules do not support regex in the path match. You can only wildcard on the full name of a path segment.
What you might want to do instead is organize all your common top-level collection into subcollections organized under a known document, and apply the same rules to each of them that way:
match /countries/data/{countryCollection}/{docId} {
allow...
}
This would apply the same permissions to all country subcollections organized under /countries/data, which can be an empty document, or even a non-existent document.

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

Resources