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

如何确保Firestore安全规则仅接受Firestore Timestamp而非JavaScript Date

问题解决:Firestore规则未阻止JavaScript Date类型输入

核心问题分析

  1. 字段名称不匹配
    你的Firestore规则中校验的字段是creationDate,但测试代码里传入的字段是dateCreated——规则根本没有对目标字段执行校验逻辑,所以请求直接通过了。

  2. Firebase SDK自动转换机制
    即使修正了字段名,Firebase JS SDK在调用setDoc时,会自动把JavaScript的Date对象转换为Firestore的Timestamp类型。到达Firestore服务器的数据已经是合法的timestamp类型,规则中的creationDate is timestamp判断会认为输入合法,导致你的测试无法触发预期的失败。


具体解决方案

1. 统一字段名称

首先确保规则和测试代码中的字段名完全一致,以下是两种修正方式:
方式一:修正Firestore规则

match /users/{userId} {
    allow create: if (request.resource.data.dateCreated != null && request.resource.data.dateCreated is timestamp)
}

方式二:修正测试代码中的字段名
将测试里的dateCreated改为creationDate,和规则保持统一。

2. 构造正确的非法输入测试用例

如果你的目标是验证规则能阻止非Timestamp类型的日期输入(比如字符串日期、自定义对象),需要构造不会被SDK自动转换的非法输入:

it('Fails if dateCreated is not a Firestore timestamp', async () => {
    // Arrange
    const authedUser = testEnv.authenticatedContext(myId);
    const db = authedUser.firestore();
    const docRef = doc(db, 'users', myId);
    // 构造非法输入:字符串格式的日期(不会被SDK转换为Timestamp)
    const docData = { dateCreated: "2024-01-01" };

    // Act & Assert
    await assertFails(setDoc(docRef, docData));
});

3. 强制使用服务器生成时间戳(可选)

如果你的真实需求是防止客户端自行设置日期,必须由服务器生成,可以修改规则要求日期等于请求时间:

match /users/{userId} {
    allow create: if (request.resource.data.dateCreated == request.time)
}

此时客户端需要使用serverTimestamp()来设置字段:

const docData = { dateCreated: firebase.firestore.FieldValue.serverTimestamp() };

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 22:05:04