一旦时间戳上指示的时间过去了,如何使数据不可读?

Bwa*_*ya 1 time firebase-realtime-database

假设某个用户向Firebase数据库写了一个事件,该用户写的内容带有时间戳,其他用户可以使用FirebaseListAdapter读取列表视图中的内容。一旦时间戳上的时间过去,是否有办法使用户写入的数据不可读?

Fra*_*len 5

无论您是单个项目还是项目列表,这里都有很大的不同。

确保对单个节点的访问

如果数据库中只有一个这样的节点:

"content": {
  "expiresAt": 1565275079920,
  "content": "This content is only readable until Thu Aug 08 2019 07:37:59 GMT-0700"
}
Run Code Online (Sandbox Code Playgroud)

您可以使用以下规则确保该节点仅在其到期时间戳之前可读:

{
  "rules": {
    "content": {
      ".read": "data.child('expiresAt').val() < now"
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

当有人将监听器附加/content到到期时间戳之前,将允许该监听器,之后将拒绝任何新的监听器。


确保对节点列表的访问

但是当您具有以下数据列表时,事情会变得更加复杂:

  1. 如果您具有对所有数据的读取访问权限,则只能读取/查询数据。
  2. 拥有对某个节点的读取访问权后,就可以对该节点下的所有数据进行读取访问。

结合这两个事实,就意味着不能使用安全规则来过滤数据。

因此,如果您在上面有这些节点的列表:

"content": {
  "-Ldshdh13...": {
    "expiresAt": 1565275079920,
    "content": "This content is only readable until Thu Aug 08 2019 07:37:59 GMT-0700"
  },
  "-Ldshdh13...": {
    "expiresAt": 1565277079920,
    "content": "This content is only readable until Thu Aug 08 2019 08:11:19 GMT-0700"
  },
  ...
}
Run Code Online (Sandbox Code Playgroud)

为了能够查询此数据,用户必须具有的读取权限/content。而且,一旦他们对拥有完全读取权限/content,就不能阻止他们读取其中的某些节点。

使此方案起作用的唯一方法是使用查询和验证此查询的安全规则的组合。

步骤1:仅查询允许读取的数据

因此,如果您只能读取将来过期的数据:

var ref = firebase.database().ref('content');
ref.orderByChild('expiresAt').startAt(Date.now()).once('value',...
Run Code Online (Sandbox Code Playgroud)

步骤2:使用安全规则仅允许对此查询进行读取

安全规则现在将检查用户是否将正确的orderBy值传递给他们的查询,以便他们仅访问未过期的数据:

{
  "rules": {
    "content": {
      ".read": "query.orderByChild == 'expiresAt' &&
                query.startAt >= now"
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

还有几件事要注意:

  • 连接侦听器时将应用安全性。因此,now仅在该时刻检查的值,此后不会对其进行任何修改。这通常不是安全问题,但是这意味着在附加侦听器之后,您也将需要删除应用程序代码中的过时数据。
  • 您可能需要稍微调整一下规则,因为Date.now()客户端中的和now中的规则可能并不完全相同。在安全规则中添加几秒钟可能是一个好主意。

为了进一步阅读,我强烈建议: