Firebase Realtime Database父节点.validate规则阻止子节点写入如何解决
问题根因
你对.validate规则的认知存在偏差,Firebase Realtime Database的规则评估逻辑为:写入任意路径时,该路径所有父层级的.validate、.write规则都会被同步评估,只要任意一条父规则不满足,请求会直接被拒绝。
你将$gameID.length === 6 && !data.exists()写在games/$gameID层级的.validate规则中,意味着不管是直接写入games/$gameID节点本身,还是写入它的任意子节点(比如games/$gameID/players),都会触发这条校验。当游戏已经创建完成后,!data.exists()的判断结果为false,自然会拦截所有子节点的写入请求。
修复方案
你只需要调整.validate规则,将!data.exists()的校验逻辑限制为仅在直接创建$gameID节点本身时生效即可,推荐使用path变量判断当前写入的路径层级:
{ "rules": { "games": { "$gameID": { ".read": "auth !== null", ".write": "auth !== null", // path.length为2时代表直接写入$gameID节点(创建游戏操作),需校验节点不存在;写入子节点时跳过该校验 ".validate": "$gameID.length === 6 && (path.length > 2 || !data.exists())", "players": { ".read": "auth !== null", ".write": "auth !== null" } } } } }
如果你的创建游戏逻辑要求必须携带指定根字段(比如房主IDowner、游戏配置config等),也可以用字段存在性判断替代路径判断,写法如下:
// 仅在$gameID节点不存在时,要求必须携带owner字段,避免重复创建 ".validate": "$gameID.length === 6 && (!data.exists() ? newData.hasChild('owner') : true)"
内容的提问来源于stack exchange,提问作者Ben Clarke
相关产品推荐
相关产品推荐

