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

Firebase规则开发:添加截止时间后禁止修改字段的校验

Firebase Firestore规则:添加截止时间字段修改限制

需求说明

需要为现有Firestore规则补充以下校验逻辑:

  • 普通用户仅能在截止时间前修改自己用户文档中的additionalGuests和invitation字段
  • 截止时间以秒级时间戳形式存储在/databases/$(database)/documents/app/config的deadline字段中
  • 管理员不受此时间限制

修改后的完整规则

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    // 检查请求中是否未包含role字段
    function isRoleNotPresent() {
      return !('role' in request.resource.data);
    }
    
    // 检查role字段值是否合法(普通用户仅能设置guest/invited/declined)
    function isRoleValueValid() {
      return request.resource.data.role == 'guest'
        || request.resource.data.role == 'invited'
        || request.resource.data.role == 'declined';
    }

    // 检查role字段是否未被修改
    function isRoleNotChanged() {
        let role = get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role;
      return request.resource.data.role == role;
    }

    // 检查role字段是否为guest
    function isRoleGuest() {
      return request.resource.data.role == 'guest';
    }

    // 检查当前用户是否为管理员
    function isAdmin() {
        let role = get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role;
      return role == 'admin';
    }

    // 检查当前操作是否在截止时间之前
    function isBeforeDeadline() {
        // 获取config文档中的deadline秒级时间戳
        let deadlineTimestamp = get(/databases/$(database)/documents/app/config).data.deadline;
        // 将Firestore内置当前时间转换为秒级,与存储的deadline统一单位比较
        return deadlineTimestamp > request.time.toSeconds();
    }

    // 检查是否修改了受限制的字段(additionalGuests或invitation)
    function isRestrictedFieldModified() {
        return 'additionalGuests' in request.resource.data 
            || 'invitation' in request.resource.data;
    }

    // 用户集合规则
    match /users/{userId} {
        // 允许用户读取自己的文档
      allow read: if request.auth.uid == userId;

      // 允许用户删除自己的文档
      allow delete: if request.auth != null && request.auth.uid == userId;

      // 允许用户创建自己的文档(管理员可创建任意文档)
      allow create: if (request.auth.uid == userId
          && (
            isRoleNotPresent()
            || isRoleNotChanged()
            || isRoleGuest()
          )
          && isRoleValueValid()
        )
        || isAdmin();

      // 允许用户更新自己的文档(管理员可更新任意文档)
      // 新增限制:若修改了受限制字段,必须在截止时间前操作
      allow update: if (request.auth.uid == userId
            && (isRoleNotPresent() || isRoleNotChanged())
            && isRoleValueValid()
            // 核心逻辑:要么没修改受限制字段,要么修改时在截止时间前
            && (!isRestrictedFieldModified() || isBeforeDeadline())
        )
        || isAdmin();
    }

    // 配置文档规则
    match /app/config {
      allow read: if true; // 所有人可读
      allow write: if isAdmin(); // 仅管理员可写
    }
  }
}

关键修改说明

  1. 完善isBeforeDeadline函数:

    • 修正字段访问路径,需通过.data.deadline获取文档中的截止时间值
    • 将request.time(Firestore内置纳秒级时间戳)转换为秒级,与存储的deadline单位统一后比较
  2. 新增isRestrictedFieldModified函数:

    • 用于判断请求中是否包含受限制的两个字段,确认用户是否试图修改受保护内容
  3. 更新update规则条件:

    • 在普通用户的更新校验中加入&& (!isRestrictedFieldModified() || isBeforeDeadline())
    • 逻辑:若未修改受限制字段则直接通过;若修改了,则必须满足截止时间前的要求
    • 管理员不受此时间限制,保持原有权限逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 11:15:11