Is there a way to control uploads to a path in Firebase Storage by group? For instance have an admin group that can upload anywhere or a team that can only upload to a certain path.
-
Related discussions: [Securing User Data guide](https://firebase.google.com/docs/storage/security/user-security) (mentions groups approach), [User Groups, Auth Claims, and Custom Tokens](https://groups.google.com/forum/#!searchin/firebase-talk/groups$20auth$20claims%7Csort:relevance/firebase-talk/77i9CRlwg88/iQsE78CbGQAJ) groups discussion. – Kato Sep 12 '17 at 21:06
2 Answers
After searching around a bit, I didn't find a ready answer, so I'll post what I have so far. It would be nice to know if there are other (better) ways of doing this.
Since I'm trying NOT to use another server, custom authentication tokens are out. However, the request.auth.uid is available to the storage rules. The uid property matches one of the users defined in the Auth area. You'll need to create a function in the storage rules that checks if request.auth.uid is in a group you define.
Firebase storage rules have a unique syntax. It sorta looks like javascript, but it's not. You can define functions, but you can't declare a var within them. Furthermore there is a subset of javascript-like methods available.
For instance, I first unsuccessfully tried the following:
function isAdmin() {
return ["value","list"].indexOf(request.auth.uid) > -1;
}
service firebase.storage {...}
Either the rules editor threw errors when I tried to define a var OR it always returned "unauthorized" when I used .indexOf.
The following ended up working for me.
function isAdmin() {
return request.auth.uid in {
"yaddayadddayaddUserIDKey":"User Name1"
};
}
function isSomeOtherGroup() {
return request.auth.uid in {
"yaddayaddaSomeOtherUID":"User Name2",
"YaddBlahBlahUID":"User Name3"
};
}
service firebase.storage {
match /b/<your bucket here>/o {
match /{allPaths=**} {
allow read, write: if isAdmin();
}
match /path/{allPaths=**} {
allow read, write: if isSomeOtherGroup() || isAdmin();
}
}
}

- 323
- 2
- 11
-
I just tried this solution but for some reason it isn't working. Were there any other caveats you had found along the way? – Tom 'Blue' Piddock Jan 23 '17 at 11:06
-
I was using email address authentication only. I didn't try with google or facebook auth. – ecalvo Feb 06 '17 at 21:13
I don't have enough reputation to comment on @ecalvo's answer. So I am adding an answer. The function isAdmin()
can be provided a list as following:
function isAdmin() {
return request.auth !=null && request.auth.uid in [
"uidAdmin1",
"uidAdmin2",
"uidOfOtherAdminsAsCommaSeparatedStrings"
];
}
Rest of the implementation can be borrowed from the answer of @ecalvo. I feel now it is more clear. In the answer of @ecalvo, I was confused why should I give username when I have to compare only uid.

- 842
- 11
- 19