📜 Firestore 安全規則(開發者用)
rules_version = '2';
service cloud.firestore {
match /databases/{db}/documents {
function isAdmin() {
return request.auth != null && request.auth.token.email in ['you@host.com'];
}
function isJudge(eventId, judgeId) {
return request.auth != null
&& exists(/databases/$(db)/documents/events/$(eventId)/judges/$(judgeId))
&& get(/databases/$(db)/documents/events/$(eventId)/judges/$(judgeId)).data.uid == request.auth.uid;
}
function playerExists(eventId, playerId) {
return exists(/databases/$(db)/documents/events/$(eventId)/players/$(playerId));
}
function maxRank(eventId) {
return get(/databases/$(db)/documents/events/$(eventId)).data.playersCount;
}
match /events/{eventId} {
allow read: if true;
allow write: if isAdmin();
match /players/{playerId} {
allow read: if true;
allow write: if isAdmin();
}
match /judges/{judgeId} {
allow read: if isAdmin() || isJudge(eventId, judgeId);
allow write: if isAdmin()
|| (isJudge(eventId, judgeId)
&& request.resource.data.keys().hasOnly(['uid','submitted'])
&& request.resource.data.uid == request.auth.uid);
}
match /scores/{judgeId} {
match /r/{rank} {
allow read: if true;
allow create, update, delete: if isJudge(eventId, judgeId)
&& (int(rank) >= 1 && int(rank) <= maxRank(eventId))
&& request.resource.data.keys().hasOnly(['playerId','ts'])
&& playerExists(eventId, request.resource.data.playerId);
}
}
}
}
}
正式使用請改為:評審只能寫入自己 judgeId 的 scores、主辦端才能改名單。