我正在尝试完成以下功能:
- 用户可以加入比赛
- 如果他们还没有比赛
- 如果他们还没有参加比赛,他们正在尝试加入
- 如果他们还没有在匹配集合中的任何其他匹配中
我正在为最后一个而苦苦挣扎。我试过这个:
!exists(/databases/$(database)/documents/matches/$(uid)/players/$(request.auth.uid)) // if the user is not already in another match
...但它似乎不起作用。
这是我的规则:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /userAuthData/{uid}/{documents=**} {
allow read: if false
allow write: if false
}
match /userData/{uid}/{documents=**} {
allow read: if request.auth != null && request.auth.uid == uid
allow write: if false
}
function allowCreateMatch(uid) {
return request.auth != null
&& exists(/databases/$(database)/documents/userData/$(request.auth.uid)) // if the user exists
&& !exists(/databases/$(database)/documents/matches/$(request.auth.uid)) // if the user does not have their own match already
&& !exists(/databases/$(database)/documents/matches/$(uid)/players/$(request.auth.uid)) // if the user is not already in another match
&& request.resource.data.maxPlayers == 2 // if the match is set to have 2 players (1v1 is the default for now)
&& request.resource.data.state == 1 // if the match is set to a state of WAITING_FOR_PLAYERS
}
function allowJoinMatch(uid) {
return request.auth != null
&& exists(/databases/$(database)/documents/userData/$(request.auth.uid)) // if the user exists
&& !exists(/databases/$(database)/documents/matches/$(request.auth.uid)) // if the user does not have their own match already
&& !exists(/databases/$(database)/documents/matches/$(uid)/players/$(request.auth.uid)) // if the user is not already in another match
&& !(request.auth.uid in resource.data.players) // if the user is not already in the match
&& resource.data.players.keys().toSet().size() < resource.data.maxPlayers // if there is room left based on the max number of players
&& resource.data.state == 1 // if the match is in a state of WAITING_FOR_PLAYERS
&& resource.data.maxPlayers == request.resource.data.maxPlayers // if there max players value is the same
&& request.resource.data.players.keys().toSet().size() + 1 == resource.data.maxPlayers
? request.resource.data.state == 2 // the match is should be set to a state of READY_TO_START
: request.resource.data.state == 1 // the match is should be set to a state of WAITING_FOR_PLAYERS
}
function allowDeletion() {
return request.auth.uid == resource.id
&& resource.data.state == 1
}
match /matches/{uid}/{documents=**} {
allow read: if true
allow create: if allowCreateMatch(uid)
allow update: if allowJoinMatch(uid)
allow delete: if allowDeletion()
}
}
}