【问题标题】:Firebase time duration overlap checkFirebase 持续时间重叠检查
【发布时间】:2019-12-05 02:43:44
【问题描述】:

我有一个房间预订应用程序,用户可以在其中预订房间在白天的任何时间。 如果服务器上已经存在预订,则在此期间您无法预订。

例如, Sally 从下午 1 点到下午 3 点预订房间 A。 Danny 想在下午 2 点到 4 点之间预订同一个房间。

出于显而易见的原因(即 TICTOU),我想避免客户端验证。怎么写在规则里?

我想在下面避免一个幼稚的解决方案。

  1. 客户端保存条目。
  2. Cloud 函数的 onWrite 会在当天遍历数据库,以确保没有其他事件重叠。
  3. 如果可以保存,请将数据上的“已验证”标志设置为真。如果不是,请将其设置为 false,然后删除数据。
  4. 此时,保存已合法完成。
  5. 客户端收到“validated = false”标志作为更新并显示错误消息。

【问题讨论】:

    标签: firebase firebase-realtime-database


    【解决方案1】:

    这在一定程度上取决于数据结构。例如,如果您决定只能在一小时内预订房间(从整点开始),那么您可以像这样对预订进行建模:

    reservations: {
      room1: {
        "2018-01-09": {
          "13": "UidOfSally",
          "14": "UidOfSally"
        }
      }
    }
    

    现在,当 Danny 尝试从 2 点到 4 点预订房间时,他会发送以下更新声明:

    reservations: {
      room1: {
        "2018-01-09": {
          "14": "UidOfDanny",
          "15": "UidOfDanny"
        }
      }
    }
    

    您可以使用安全规则对其进行验证,只需检查插槽是否已被声明:

    { "rules":{
      "reservations": {
        "$roomId": {
          "$date": {
            "$slot": {
              ".write": "!data.exists()"
            }
          }
        }
      }
    }}
    

    您可以使此写入规则更加先进以满足您的需求。例如:

    ".write": "
      (!data.exists() && newData.val() == auth.uid) || ( // if no one has claimed this yet, any user can claim it for themselves
      ( data.exists() && data.val() == auth.uid) // owner can delete their reservation
    )"
    

    您的代码应在一次调用中从 Danny 发送整个更新(作为事务或作为 update()),以便它始终被拒绝或全部接受。

    这种方法也适用于较小的插槽,它们不必长达一小时。但它们必须是离散的插槽。

    【讨论】:

    • 这也是我想过的另一个天真的解决方案。我的版本将时间切成 5 分钟。这是相同的方法,但它变得有点混乱/hacky。我想这只是 nosql 概念的一个限制。感谢弗兰克的精彩回答!非常感谢:)
    猜你喜欢
    • 2016-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-12
    • 1970-01-01
    • 2018-09-27
    相关资源
    最近更新 更多