是否可以在Firestore中读取文档然后将其锁定,以便其他人都无法阅读?

时间:2019-03-30 19:58:27

标签: javascript firebase google-cloud-firestore locking document

我正在构建一个应用程序,用户可以在其中旋转命运之轮。 当他们幸运并进入特定领域时,他们可以赢得优惠券。

我想将这些优惠券存储在具有以下属性的Firebase Firestore中:

{
"code" : 381939,
"expire_date" : xxx,
"value" : 5,
"currency" : "EUR"
}

我的想法是,当有人转动命运之轮时,将从数据库中选择一个随机的优惠券/文件。 如果没有优惠券,那么命运之轮应该无效。 因此,我认为我需要放置一个按钮“检查优惠券的可用性”或类似的按钮,以检查是否还有剩余的优惠券。如果有的话,方向盘将被设置为活动状态。

然后有两种情况: 1)他们赢了:优惠券将分配给用户并从数据库中删除 2)它们松散:优惠券将存储回数据库中。

不幸的是,当许多用户想同时使用命运之轮时,我认为这种方法不能很好地工作,因为多个用户可以读取同一文档/优惠券。

那么可以“锁定”文档,以便在有人阅读后没有人可以阅读它吗? 还是我如何确保每个用户都将从数据库中读取不同的优惠券/文档,所以没有用户共享此优惠券?

希望您能理解我的问题。

如果您需要更多信息,请告诉我。

2 个答案:

答案 0 :(得分:0)

您可以使用Cloud Firestore的服务器端安全性规则限制对文件的访问。由于您正在谈论将优惠券/文档与用户相关联,因此这也是对安全规则进行建模的好方法。

例如,假设您已将owner字段添加到具有用户UID的文档中,如果他们已经领取了优惠券:

{
  "code" : 381939,
  "expire_date" : xxx,
  "value" : 5,
  "currency" : "EUR"
  "owner" : "uidOfOwner"
}

现在,我们将确保:

  1. 用户只有在没有所有者的情况下才能阅读文档,如果是所有者,则只能阅读
  2. 用户只能在尚无所有者的情况下写文档。

我们可以使用以下规则做到这一点:

match /databases/{database}/documents {
  match /coupons/{coupon} {
    allow read: if !resource.data.keys().hasAll(['owner']) || resource.data.owner == request.auth.uid;
    allow write: if !resource.data.keys().hasAll(['owner']);
  }
}

这里需要注意的几件事:

  • 使用上述规则,您可以控制对单个文档的访问,但是用户将无法再读取/查询整个coupons集合。如果您仍然希望允许这样做,请查看securing queries
  • 使用上述规则,用户可以在没有所有者(或所有者)的情况下修改文档所需的任何内容。您可能希望进一步限制写许可权,以便用户只能写所有者字段。在checking if a field is modified上查看此答案。

答案 1 :(得分:0)

我认为您应该出于安全考虑使用firebase云功能,因为您的用户不应该能够在优惠券上书写。 当用户获胜时,调用一个云函数,该函数会随机将ownerId添加到可用的优惠券中:

{
  "code" : 381939,
  "expire_date" : xxx,
  "value" : 5,
  "currency" : "EUR"
  "owner" : "ownerId"
}

在客户端,您可以收听查询,该查询将获得与用户相关联的优惠券。这样,当用户获胜时,就会通过您的听众得到通知。

别忘了添加安全规则,这样您的用户就只能获取与其关联的优惠券:

 match /databases/{database}/documents {
      function authenticated() { return request.auth.uid != null }
      function isMyCoupons () { return request.auth.uid == resource.data.owner }

      match /coupons/{coupon} {
        allow read: authenticated() && isMyCoupons();
      }
    }