Reputation: 45
Trying to enable security roles for Android firestore app
following this document: https://firebase.google.com/docs/firestore/solutions/role-based-access
service cloud.firestore {
match /databases/{database}/documents {
match /Dairy/{dairyId} {
function isSignedIn() {
return request.auth != null;
}
function getRole() {
//both of the below statements are not working
//return resource.data.roles[request.auth.uid];
return get(/databases/$(database)/documents/Dairy/$(dairyId)).data.roles[request.auth.uid];
}
function isOneOfRoles(array) {
return isSignedIn() && (getRole() in array);
}
function isValidNewDoc() {
return resource.data == null
&& request.resource.data.roles[request.auth.uid] == 'OWNER';
}
allow write: if isValidNewDoc() || isOneOfRoles(['OWNER']);
allow read: if isOneOfRoles(['OWNER', 'ADMIN']);
match /{document=**} {
allow read: if isOneOfRoles(['OWNER', 'ADMIN']);
}
}
match /DairyOwnerProfile/{user_profile} {
function isUserSignedIn() {
return request.auth != null;
}
function isValidNewProfile() {
// Valid if Dairy does not exist and the new Dairy has the correct owner.
return isUserSignedIn() && resource.data == null
&& request.resource.data.uid == request.auth.uid;
}
allow read, write: if isUserSignedIn() && (user_profile == request.auth.uid || isValidNewProfile());
}
}
}
Domain model is
Create document is working for below document model with path /databases/{database}/documents/DairyOwnerProfile/{USER_ID}
public class DairyOwnerProfile {
private String uid;
private String name;
private String phone;
private String dairyId;
}
But create and read not working for Dairy collection and all its sub collections Dairy model below store in path /databases/{database}/documents/Dairy/{dairyId}
public class Dairy {
private String id;
private String dairyName;
private boolean active;
private String address;
private Date updateTime;
private Map<String, Role> roles;
}
public enum Role {
OWNER, FARMER, ADMIN, MANAGER
}
trying since few days, but couldn't figure-out what's wrong with above firestore security rule
Tried isValidNewDoc() method with below variants
//Not working
function isValidNewDoc() {
return resource.data == null
&& request.resource.data.roles[request.auth.uid] == 'OWNER';
}
//Not working
function isValidNewDoc() {
return resource.data == null
&& request.resource.data == null;
}
//Not working
function isValidNewDoc() {
return resource.data == null
&& request.resource.data != null;
}
//Not working
function isValidNewDoc() {
return resource.data == null;
}
//working
function isValidNewDoc() {
return isSignedIn();
}
//Working, Create and update both worked (Sub collection read/write failed)
//but this allows overwriting existing document by another user, adding "resource.data == null" with && causing it to fail
function isValidNewDoc() {
return request.resource.data.roles[request.auth.uid] == 'OWNER';
}
This is the error got in Android studio console com.google.firebase.firestore.FirebaseFirestoreException: PERMISSION_DENIED: Missing or insufficient permissions.
I am doing something wrong with the rule or hierarchy of data is the issue
Have many sub collections under Dairy collection, read/write on those sub collections also failing
this issue blocking my first version of android App release, please point me in right direction to find and fix the issue
Note: this is my first experience with android and firestore
please let me know if more information is required.
Sample Data stored in Forestore without security rule
Upvotes: 1
Views: 914
Reputation: 6854
Use resource == null
instead of resource.data == null
:
function isValidNewDoc() {
return resource == null
&& request.resource.data.roles[request.auth.uid] == 'OWNER';
}
Upvotes: 3