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

如何基于Firestore用户文档versionCode字段配置安全访问规则

Firestore按用户版本号控制访问权限的安全规则配置

我在users集合中新增了appVersion相关字段,users集合文档路径示例:documents/users/5kwgNgGi3sY6oCbUAg9v,集合结构参考下图:
用户集合结构示意图

集合中新增了versionCode字段,用户下载新版本应用后该字段会自动更新。原有配置的Firestore安全规则如下:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
          allow read, write: if request.auth !=null
    }
  }
}

需要实现的访问控制逻辑:

  • 未登录用户直接拒绝访问
  • 已登录用户仅能查询自身UID对应的用户文档
  • 仅当目标用户文档中versionCode字段值为4时允许访问,其余情况拒绝
    对应逻辑伪代码如下:
if(request.auth!=null){
firebase().collection('users').where('UID','==',request.auth.uid).get().then(x=>{
    if(x.docs[0].versionCode==4){
      allow
    }
    else{
      deny
    }})
else{
  deny
}

正确实现方案

Firestore安全规则是在请求到达数据库时,由规则引擎直接基于请求上下文、目标文档数据做校验,不支持在规则内写客户端式的异步查询逻辑,直接按路径匹配规则做判断即可,不需要手动查询文档。

方案1:标准结构(推荐,性能最优)

建议将users集合下的文档ID直接设置为对应用户的Firebase Auth UID,这是Firebase的官方推荐结构,规则写法最简单,查询性能最高:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // 默认拒绝所有路径的访问,遵循最小权限原则
    match /{document=**} {
      allow read, write: if false;
    }
    // 单独配置users集合的访问规则
    match /users/{userId} {
      allow read, write: if 
        // 校验用户已登录
        request.auth != null &&
        // 仅允许访问自己对应的用户文档
        request.auth.uid == userId &&
        // 校验版本号符合要求
        resource.data.versionCode == 4;
    }
  }
}

方案2:适配现有结构(保留UID字段存储)

如果暂时不调整现有文档ID结构,继续用文档内的UID字段存储用户ID,可使用如下规则,注意该规则要求所有查询users集合的请求必须携带UID == 当前登录用户uid的过滤条件,否则规则会直接拦截请求:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if false;
    }
    match /users/{docId} {
      allow read, write: if
        request.auth != null &&
        // 校验当前访问的文档属于登录用户本人
        request.auth.uid == resource.data.UID &&
        resource.data.versionCode == 4;
    }
  }
}

版本更新场景补充规则

如果低版本用户需要通过更新自身文档的versionCode字段完成升级校验,需要单独给字段更新加放行逻辑,否则低版本用户会因为versionCode不为4被拦截,永远无法更新版本号:

// 追加到users集合的匹配块内
allow update: if 
  request.auth != null &&
  request.auth.uid == resource.data.UID &&
  // 仅允许修改versionCode字段,防止越权修改其他数据
  request.resource.data.keys().hasOnly(['versionCode']) &&
  // 仅允许将versionCode更新为4
  request.resource.data.versionCode == 4;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 04:24:17