Firebase持续时间重叠检查

时间:2018-01-10 00:47:45

标签: firebase firebase-realtime-database

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

例如, 莎莉从下午1点到下午3点预订A室。 丹尼想要从下午2点到下午4点预订同一个房间。

由于显而易见的原因(即TICTOU),我想避免客户端验证。我将如何在规则中写出来?

我有一个天真的解决方案,我想在下面避免。

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

1 个答案:

答案 0 :(得分:3)

这取决于数据结构。例如,如果您决定只能在一小时的时段(从小时开始)预订房间,那么您可以像这样预订模型:

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

现在当丹尼试图从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
)"

您的代码应该通过一次通话(作为交易或作为update())从Danny发送整个更新,以便始终被拒绝或全部接受。

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