【问题标题】:Firestore Rules verify timestamp with a Flutter clientFirestore 规则使用 Flutter 客户端验证时间戳
【发布时间】:2018-12-29 14:33:57
【问题描述】:

我想通过客户端发送 Firestore 文档的创建时间,并使用 Firestore 规则验证时间以避免 Cloud Functions 调用(定价)。

场景

我正在根据这样的 Firestore 规则测试来自客户端的请求:

allow create: if request.resource.data.TIMEFIELD == request.time;

请求包含一个带有时间戳的TIMEFIELD,就像request.time一样。

问题

显然请求时间和我在发送请求之前设置为字段的时间不相等,这使得无法进行比较。

以下是文档中request.time 的定义。

When the request was received by the service.

不知道有没有办法在文档中设置字段等于request.time

由于an issue with Flutter,我无法使用服务器端时间戳。
因此,我需要知道如何使用 Firestore 规则验证客户端时间戳,例如 time.now

【问题讨论】:

  • 允许创建:如果 request.resource.data.TIMEFIELD == request.time;这背后有什么原因吗?为什么要验证时间?
  • @AngusTay 因为时间戳对产品很重要,没有人应该能够操纵时间。我认为这是 Firebase 安全规则背后的主要原因。
  • 这个问题似乎是 Flutter 特有的——也许自 2018 年以来就已修复?如果是这样,您是否愿意在标题中提及 Flutter 并将其添加为标签?也许整个问题都已解决,在这种情况下,这个问题只能作为历史证据。

标签: firebase flutter google-cloud-firestore firebase-security


【解决方案1】:

您可以使用Timestamp 将约束添加到时间字段 (docs)。

以下是如何确保更改在一定秒数内的示例:

function withinSeconds(secs) {
  return request.resource.data.TIMEFIELD.seconds() - request.time.seconds() <= secs
    && request.resource.data.TIMEFIELD.seconds() - request.time.seconds() >= -secs
}

编辑

以上是用于将值设置在request.time的阈值内。

与此同时,您也可以只使用 REST API。只需发出一个包含updatetransformwrite 请求。 transform 是您设置服务器时间戳的位置。 Here 是帮助理解如何构建请求的工具。

【讨论】:

  • 是的,我误解了这个问题。我刚刚更新了答案。
  • @creativecreatorormaybenot here 是我之前用如何使用 REST API 插入时间戳的示例写的答案。它可能会帮助您了解有效负载结构。您也可以只执行 Web SDK 并查看“网络”(在控制台中)选项卡以查看生成的有效负载。
  • 这不是(最好的)方法。 FieldValue.serverTimestamp() 将提供一个完全准确的时间戳。
【解决方案2】:

这已在 Cloud Firestore 的 Flutter 插件中实现:

FieldValue.serverTimestamp()

将其用作字段的值将在服务器端为该字段分配一个等于request.time 的时间戳。

您可以在API referencecloud_firestore 中找到更多相关信息。

【讨论】:

    【解决方案3】:

    您首先必须记住创建(或上次更新)时间戳:

    firestore().collection("items").add({
        ....
        created: firebase.firestore.FieldValue.serverTimestamp()
    });
    

    为了让客户端知道您稍后尝试比较的时间戳。

    【讨论】:

    • 这个问题没有提到 Flutter,也没有提到任何平台......虽然这将是 JS 文档(证明这个值至少存在于服务器端):firebase.google.com/docs/reference/js/…
    • @creativecreator 或者可能没有提供访问权限的 Dart/Flutter 插件:github.com/pauldemarco/plugins/tree/master/packages/… ...您的业务逻辑应该考虑,服务器时间戳才是真正重要的(可能有一些相对于客户端时间戳的偏移量)。基本上,您需要更新文档,然后在客户端更新新的时间戳。只需添加一个更新一个和另一个的函数,比较这两者。类似于SyncAdapter
    猜你喜欢
    • 2021-12-01
    • 1970-01-01
    • 2018-11-27
    • 2017-11-07
    • 1970-01-01
    • 2021-02-27
    • 2011-02-06
    • 2015-11-29
    • 2019-01-29
    相关资源
    最近更新 更多