You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用arrayUnion更新Firestore用户decks列表遇权限拒绝错误

问题原因与解决方案

核心问题

你遇到的权限拒绝错误,根源在于arrayUnion的特性和Firestore规则的冲突:

  • arrayUnion仅当元素不存在于目标数组时,才会添加元素并使数组长度+1;如果元素已存在,数组长度不会变化。
  • 你的规则强制要求request.resource.data.decks.size() == resource.data.decks.size() + 1,当元素已存在时,这个条件不满足,直接触发权限拒绝。

排查与解决步骤

1. 检查待添加元素是否已存在

先查询目标用户的decks数组,确认fake-deck-id是否已经存在:

const userDoc = await getDoc(doc(db, 'users', userId));
console.log(userDoc.data()?.decks);

如果该ID已在数组中,arrayUnion不会修改数组,规则校验自然失败。

2. 调整Firestore规则以兼容arrayUnion

修改规则,允许数组长度不变(元素已存在时的无操作)或增加(新元素添加),同时确保新数组包含原数组的所有元素(防止恶意删除):

// Allow updates only to the "decks" and "votes" lists
allow update: if request.auth != null &&
request.auth.uid == userId &&
(
  (
    // Allow updates to "decks" using array operations
    request.resource.data.keys().hasOnly(['decks']) &&
    request.resource.data.decks is list &&
    // 允许长度不变(元素已存在)或+1(新元素添加)
    request.resource.data.decks.size() >= resource.data.decks.size() &&
    // 确保新数组包含原数组所有元素,避免恶意删除
    request.resource.data.decks.hasAll(resource.data.decks)
  ) ||
  (
    // Allow updates to "votes" using array operations
    request.resource.data.keys().hasOnly(['votes']) &&
    request.resource.data.votes is list &&
    request.resource.data.votes.size() >= resource.data.votes.size() &&
    request.resource.data.votes.hasAll(resource.data.votes)
  )
);

3. 其他排查点

  • 确认userId正确性:检查代码中userId变量是否与当前认证用户的uid完全一致,规则中request.auth.uid == userId是核心校验条件,变量错误会直接导致权限拒绝。
  • 检查用户文档是否存在:如果目标用户文档尚未创建,resource.data会为null,此时resource.data.decks.size()会触发规则校验错误。这种情况需要先初始化用户文档,或在规则中额外处理文档不存在的场景(比如补充create规则)。

内容的提问来源于stack exchange,提问作者MarksCode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 23:53:14