如何在Firestore规则中限制用户访问时间段
Firestore按时间段限制用户访问的实现方案
一、时间存储方案
你选择用Int类型存储startAccess(如900代表9:00)和endAccess(如2100代表21:00)是完全合适的,这种方式比timestamp更轻量,刚好适配只按小时分钟限制访问的需求,无需处理日期部分。
二、Firestore规则实现
核心思路是把Firestore服务器的当前时间(request.time)转换成和存储格式一致的时分整数,再与配置的起止时间对比。以下分两种场景给出实现:
场景1:全局统一访问限制(所有用户共用同一时间段)
假设你把时间配置存在settings/access文档中,规则写法如下:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // 读取全局访问时间配置 function getGlobalAccessConfig() { return get(/databases/$(database)/documents/settings/access); } // 判断当前时间是否在允许范围内,兼容跨天场景 function isInAccessWindow() { let currentTime = request.time.hour() * 100 + request.time.minute(); let start = getGlobalAccessConfig().data.startAccess; let end = getGlobalAccessConfig().data.endAccess; return start <= end ? (currentTime >= start && currentTime <= end) : (currentTime >= start || currentTime <= end); } // 对所有文档应用访问限制 match /{document=**} { allow read, write: if isInAccessWindow(); } } }
场景2:用户专属访问限制(不同用户有不同时间段)
假设每个用户的时间配置存在users/{userId}文档中,规则写法如下:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // 判断当前用户的访问时间是否合规 function isUserInAccessWindow() { let userDoc = get(/databases/$(database)/documents/users/$(request.auth.uid)); let currentTime = request.time.hour() * 100 + request.time.minute(); let start = userDoc.data.startAccess; let end = userDoc.data.endAccess; return start <= end ? (currentTime >= start && currentTime <= end) : (currentTime >= start || currentTime <= end); } // 仅允许已认证且在时间范围内的用户访问 match /{document=**} { allow read, write: if request.auth != null && isUserInAccessWindow(); } } }
三、注意事项
- 规则中使用的是Firestore服务器的UTC时间,如果需要按用户本地时区限制,需额外将用户时区信息存入文档,在规则中做时区偏移计算
- 跨天场景(如允许22:00至次日6:00)已在规则中处理,无需额外修改
- 可以通过Firestore规则模拟器调整
request.time参数,快速验证规则是否生效
内容的提问来源于stack exchange,提问作者Takeshi
相关产品推荐
相关产品推荐

