Google cloud firestore 比较Firestore规则中的文档时间戳

Google cloud firestore 比较Firestore规则中的文档时间戳,google-cloud-firestore,firebase-security,Google Cloud Firestore,Firebase Security,我在编写和测试Firestore规则时遇到了一个奇怪的问题。以下是我想要实现的目标: 当应用程序启动时,用户以匿名方式登录。这个 用户开始一个新游戏 我创建了一个“会话”,它基本上只包含一个时间戳 玩家玩游戏,获得一定的高分,然后进入屏幕,在那里分数可以发送到全球高分列表。当提交高分时,我检查是否存在该玩家的现有会话,以及所经过的时间是否足够长,以使高分被视为有效 在客户端(javascript)上,我使用以下行发送文档中的时间戳: firebase.firestore.FieldValue

我在编写和测试Firestore规则时遇到了一个奇怪的问题。以下是我想要实现的目标:

  • 当应用程序启动时,用户以匿名方式登录。这个 用户开始一个新游戏
  • 我创建了一个“会话”,它基本上只包含一个时间戳
  • 玩家玩游戏,获得一定的高分,然后进入屏幕,在那里分数可以发送到全球高分列表。当提交高分时,我检查是否存在该玩家的现有会话,以及所经过的时间是否足够长,以使高分被视为有效
在客户端(javascript)上,我使用以下行发送文档中的时间戳:

firebase.firestore.FieldValue.serverTimestamp()
这是当前的规则集。您可以看到,只有当新higscore的createdAt晚于会话的createdAt时,才能创建分数

service cloud.firestore {
    match /databases/{database}/documents {
        function isValidNewScoreEntry() {
            return request.resource.data.keys().hasOnly(['createdAt', 'name', 'score']) &&
            request.resource.data.createdAt is timestamp &&
            request.resource.data.name is string &&
            request.resource.data.score is int &&
            request.resource.data.name.size() <= 20
        }

        match /highscores/{entry} {
            allow list: if request.query.limit <= 10;
            allow get: if true; 
            allow create: if isValidNewScoreEntry() &&
      request.resource.data.createdAt > get(/databases/$(database)/documents/sessions/$(request.auth.uid)).data.createdAt;
        }

        function isValidNewSession() {
            return request.resource.data.keys().hasOnly(['createdAt']) &&
            request.resource.data.createdAt is timestamp
        }

        match /sessions/{entry} {
            allow list: if false;
            allow get: if false; 
            allow create: if isValidNewSession();
            allow update: if isValidNewSession();
        }
    }
}
service cloud.firestore{
匹配/databases/{database}/documents{
函数isValidNewScoreEntry(){
return request.resource.data.keys().hasOnly(['createdAt','name','score'])&&
request.resource.data.createdAt是时间戳&&
request.resource.data.name是字符串&&
request.resource.data.score为int&&

request.resource.data.name.size()。 翻阅文档后,我发现
get()
方法返回一个
resource
resource
有一个属性
data
:一个映射。因此
get()
方法并没有像我预期的那样返回文档,而是返回一个平面JSON对象,它提供了在de数据库中找到的所有属性


我不明白这意味着什么:“由于某种原因,第二个时间戳被转换为“映射”。你在这里到底观察到了什么?我也不明白你的规则试图阻止什么。当我尝试测试规则时,它会给我一个错误,我只能在两个值的类型相同时进行“>”比较,但现在一个错误说我正在将“时间戳”与“映射”进行比较。我认为这是因为get()call给了我一些JSON等价的时间戳,而不是实际的时间戳。我试图做的是比较提交的分数createdAt是否至少晚于游戏会话createdAt的开始。请编辑问题以准确显示您试图比较的数据库的内容。听起来像您的文档doe实际上,在createdAt字段中没有包含正确的时间戳。我无法添加图像,因为这是我的第一篇文章。但我已经将图像链接添加到了文章中。正如您所看到的,两个文档都有一个有效的时间戳。它们是以完全相同的方式创建的,FieldValue.serverTimestamp()作为“createdAt”。我不太确定get()是什么方法在规则集中返回,但它没有按我预期的方式给我时间戳。也许你应该编辑问题以显示整个规则集,以及执行写入的代码。我仍然不清楚你试图解决的问题。将代码减少到一行没有帮助。任何阅读问题的人都应该是能够以最小的麻烦复制您正在做的事情。另外,请解释您如何知道某些东西正在转换为地图。那么,您是如何更改规则使其生效的?