如何编写Firestore安全规则实现玩家ID的not in校验逻辑?
用Firestore安全规则校验玩家ID未存在于数组中的实现方案
你需要通过Firestore安全规则拦截重复添加玩家ID的请求,结合你提供的IGameData接口和arrayUnion更新代码,以下是具体实现:
安全规则写法
场景1:添加当前请求用户的ID
如果要添加的是发起请求用户的UID,规则可以这么写:
match /games/{gameId} { allow update: if // 校验当前用户ID不在现有玩家数组中 !(resource.data.players.hasAny([request.auth.uid])) && // 同时校验玩家数量不超过限制 request.resource.data.players.size() <= resource.data.playersLimit; }
场景2:添加指定的玩家ID(非当前用户)
如果要添加的是任意指定的玩家ID,可通过对比更新前后的数组差集来校验:
match /games/{gameId} { allow update: if // 获取更新时新增的玩家ID集合 let newPlayers = request.resource.data.players.diff(resource.data.players); // 确保仅添加了一个新ID,且该ID未在原数组中存在 newPlayers.size() == 1 && !(resource.data.players.hasAny(newPlayers)) && // 校验玩家数量不超过限制 request.resource.data.players.size() <= resource.data.playersLimit; }
配合你的更新代码说明
你当前使用arrayUnion(playerId)的更新逻辑是合理的——这个方法本身会自动忽略已存在的元素,但通过上述安全规则,可以在Firestore服务端提前拦截重复添加的请求,避免无效的文档写入操作,同时保证玩家数量不超过设定的playersLimit。
内容的提问来源于stack exchange,提问作者Антон Стецюра
相关产品推荐
相关产品推荐

