I want to secure my Firestore database with the integrated code editor in the firebase website. My aim is to check before reading document called "moyenne", if:
numr == request.auth.token.phone_number || numr in get(/databases/$(database)/documents/Profil/$(request.auth.token.phone_number).resource.data.numbers
I tried this:
//first try
match /Note/{numr}/moyenne/moyenne {
allow read:
if (numr == request.auth.token.phone_number || numr in get(/databases/$(database)/documents/Profil/$(request.auth.token.phone_number)).resource.data.numbers);
}
//second try
match /Note/{numr}/moyenne/moyenne {
allow read:
if (numr == request.auth.token.phone_number ||
numr in get(/databases/$(database)/documents/Profil/$(path(request.auth.token.phone_number))).resource.data.numbers);
}
But unfortunately, it doesn't work.
Error for the first try (the test number is +91909090909):
Call the [get] function with a path to a non-existing resource: / databases /% 28default% 29 / documents / Profile /% 2B33651177261
Error for the second try:
Error: simulator.rules line [14], column [17]. Property resource is undefined on object.
PS: structure of the profil document:
Related
I'm making the security rules for Firebase Firestore, but I can't reference the map inside another map, as shown in the image below. I need to reference the type and whether it is active.
Document with Map inside another Map:
I tried to use the following command:
get (/databases/$(database)/documents/after_sales/{after_salesUID}/users_type).data.type in ['admin', 'approver'] &&
get (/databases/$(database)/documents/after_sales/{after_salesUID} /users_type.data.active == true;
When trying to test access to the document, I receive the following error message "Error while running the simulation: An unknown error has occurred".
I am unsure of your complete database structure but I created a collection named 'companies' and a document in it.
These rules worked for me:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /companies/{companyID} {
allow read: if get(/databases/$(database)/documents/companies/$(companyID)).data.user_types[request.auth.uid].admin == true;
}
}
}
I am not sure which location you are trying to access in your db but that's how you can read values in nested maps. Apparently it's after_sales ID in your case that I made user UID in my test.
match /UserProfile {
match /{uId}{
allow get: if isUserLoggedIn() && !isUserBlocked(uId);
}
when i try to get data from UserProfile/{uId} using the above security rules it throws the following error in the firestore and in code it says insufficient permissions:
Error running simulation — Error: simulator.rules line [199], column [28]. Function not found error: Name: [get].
now the definition of above two function are here
function isUserLoggedIn(){
return request.auth != null;
}
function isUserBlocked(uId){
return (('blocked' in get(/databases/$(database)/documents/UserSettings/$(uId)).data) && (request.auth.uid in get(/databases/$(database)/documents/UserSettings/$(uId)).data.blocked));
}
the first function runs very well
but the second one doesn't
it throws that error
and as of my knowledge the function is alright
please help i have wasted a whole lot of time on this piddly problem
what i have tried
i read in one of the threads that it is a temporary problem
but it is not like that. its been more than 48 hours now
somewhere it was also mentioned that this is a bug only in simulator but the code will run smoothly and even this is not the case. in code the error is insufficient permissions as expected by me
i have read the docs properly so my code is alright have tested the get method in other rules and there it is working fine
thats it please help
Update: The errors are a bug in the rules simulator, see Doug's comment below.
I tried out your rules and they worked as expected in the simulator.
Rules:
match /UserProfile {
function isUserLoggedIn(){
return request.auth != null;
}
function isUserBlocked(uId){
return (('blocked' in get(/databases/$(database)/documents/UserSettings/$(uId)).data) && (request.auth.uid in get(/databases/$(database)/documents/UserSettings/$(uId)).data.blocked));
}
match /{uId}{
allow get: if isUserLoggedIn() && !isUserBlocked(uId);
}
}
Test query in simulator:
get /UserProfile/foo
Authenticated: Yes
Firebase UID: bar
The request succeeds or fails based on the UserSettings/foo document in the database:
Denies request:
/UserSettings/foo
{
content: "my content"
blocked: { bar: true }
}
Allows request:
/UserSettings/foo
{
content: "my content"
blocked: { otheruser: true }
}
I think that errors can pop up when the data doesn't exist or isn't in the expected format.
For example, if I delete the /UserSettings/foo document I also receive:
Error: simulator.rules line [58], column [28]. Function not found error: Name: [get].
I also get this error if the blocked field is anything other than a map (because in is a function for maps):
Error: simulator.rules line [58], column [95]. Function not found error: Name: [in].
You can probably clean up these errors by using exists and checking the type of blocked but either way, your rules should still deny the request as expected.
I'm trying to secure my Firebase (google cloud storage) files based on user data. In firestore, I use a rule based on getting database content (look up the uid in users table and match a field) and that's working fine. I'm trying to use the same kind of rules in firebase storage but in the simulator I get Error: simulator.rules line [12], column [17]. Function not found error: Name: [get].; Error: Invalid argument provided to call. Function: [get], Argument: ["||invalid_argument||"]. My rules look like this:
match /b/{bucket}/o {
function isAuth() {
return request.auth != null && request.auth.uid != null
}
function isAdmin() {
return isAuth() &&
"admin" in get(/databases/$(database)/documents/users/$(request.auth.uid)).data.roles;
}
function clientMatch(client) { // expects user's "client" field to be ID of client
return isAuth() &&
client == get(/databases/$(database)/documents/users/$(request.auth.uid)).data.client;
}
match /P/Clients/{client}/{allPaths=**} {
allow read, write: if isAdmin() || clientMatch(client);
}
}
}
Line 12 is the one beginning client == get, in clientMatch().
I haven't been able to tell whether these functions are only supported for Firestore (db) rules, or whether they should work for storage as well.
If this doesn't work, what are my options? How do people look up user data for Firebase storage security?
You currently can't reference Firestore documents in Storage rules. If you would like to see that as a feature of Storage rules, please file a feature request.
Consider instead using a Cloud Functions storage trigger to perform some additional checks after the file is uploaded, and remove the file if you find that it's not valid.
This is now possible with cross-service security rules. You have to use firestore. namespace before the get() and exists() functions as shown below:
function isAdmin() {
return isAuth() && "admin" in firestore.get(/databases/$(database)/documents/users/$(request.auth.uid)).data.roles;
}
Do note that you'll be charged for read operations just like in Firestore security rules.
Trying to add security rules to storage. When I add a security rule to make sure only authenticated users should be allowed with read/write, simulator is working. But when I try to add another constraint on the size of a file, I'm encountering an error.
The following is the Security Rule:
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null && request.resource.size < 5 * 1024 * 1024;
}
}
}
I have files under files\
I get the following error in simulator:
Simulated read denied
Error details:
Error: simulator.rules line [4], column [29]. Property resource is undefined on object.
Issue happens if I try to simulate write as well.
EDIT1: IMPORTANT
OK! I found this question and tried experimenting a bit on that line and got the simulator allowing read/write! I made the following change:
allow read, write: if request.auth != null && (request != null
|| request.resource.size < 5 * 1024 * 1024);
That's basically I added a null check. So, at the moment, I'm not clear what's going on here!
I was able to work around this with a rule like
match /users/{uid}/{document=**} {
allow read, create, update: if
request.auth != null &&
request.auth.uid == uid &&
(!("resource" in request) || request.resource.data.uid == request.auth.uid);
}
In this case I wanted to ensure that the "uid" property in the update matches the user's uid. However, if in the simulator you don't do "Build Document" first then request.resource is undefined (I think this is a bug; it should be defined but null IMO).
I believe this really only applies in the simulator, and is not a realistic scenario since create/update requests will always contain a document, even an empty one. But I think I'll keep it in my rule just in case.
I just installed FriendlyPix iOS and followed all the steps listed on the readme including deploying the cloud functions and rules. I am getting an error and I think it has to do with the storage rules. The error I get is:
User does not have permission to access gs://friendlypixsk.appspot.com/HS4uNP1BYNNnW2Qf59azZH8i3gp2/full/-LAoHLCCMnlD8RoFhUNd/jpeg.
This happens in the uploadPressed function in FPUploadViewController. It happens in the fullref.downloadURL function call. The closure passed to that function is getting an error.
The Firebase Storage rules I have are as follows:
// Returns true if the given UID matches the signed in UID,
// the uploaded file is an image and its size is below the given number of MB.
// Also allow deletes.
function isImageAndBelowMaxSize(uid, maxSizeMB) {
return request.auth.token.admin == true || (request.auth.uid == uid
&& (request.resource == null // Allow deletes
|| request.resource.size < maxSizeMB * 1024 * 1024 // Max size for the uploaded file
&& request.resource.contentType.matches('image/.*'))) // The file is an image
}
service firebase.storage {
match /b/{bucket}/o {
match /{userId}/thumb/{postId}/{fileName} {
allow read, write: if isImageAndBelowMaxSize(userId, 1);
}
match /{userId}/full/{postId}/{fileName} {
allow read, write: if isImageAndBelowMaxSize(userId, 5);
}
}
}
I have not modified them at all. The image does get uploaded and I can see it in the firebase console. I'm a little new to firebase and not sure exactly how these rules work. I have signed in using google sign in.
Any help would be greatly appreciated!!
Thanks