如何在Firebase实时数据库中使用结束日期时间

时间:2017-11-07 15:01:28

标签: android datetime firebase firebase-realtime-database google-cloud-functions

在我们的应用中,保存新数据的结束日期时间非常重要。

例如,如果要编写新邮件,我希望用户只能看到十个小时。随着休息api&在SQL数据库中,我可以轻松地创建服务器时间(+十小时)的结束日期时间并将消息保存在数据库中。为用户加载消息时,我可以选择结束日期时间之前的所有消息。

如何使用Firebase实时数据库执行此操作?也许使用Firebase云功能?我不想使用客户时间。

1 个答案:

答案 0 :(得分:5)

这实际上是云功能的一个很好的用法示例。

将邮件保存到数据库时,您可以使用ServerValue.TIMESTAMP自动插入Firebase服务器的时间戳,这样您就可以执行以下操作:

public void saveMessage(String content) {
    DatabaseReference messagesRef = FirebaseDatabase.getInstance().getReference("messages");

    HashMap<String, Object> message = new HashMap<>();
    message.put("content", content);
    message.put("startTime", ServerValue.TIMESTAMP);

    messagesRef.push().setValue(message);
}

然后,您可以将云功能附加到messages位置以侦听新数据。此函数可以执行向startTime值添加10个小时并将其endTime保存回同一个孩子的逻辑,如:

exports.calculateEndTime = functions.database
    .ref('/messages/{messageId}').onCreate(event => {
      const message = event.data.val();

      // Only calculate endTime if it doesn't already exist.
      if (message && !message.endTime) {
        // Add 10 hours (in milliseconds) to the startTime to obtain the endTime.
        const endTime = message.startTime + (10 * 3600000);

        // Update the Firebase Database with the new endTime value.
        return event.data.adminRef.update({
          endTime: endTime
        });
      }
    });

最后,要查询消息列表以仅获取endTime尚未通过的消息列表,您可以执行以下操作:

// Obtain the server time using the .info/serverTimeOffset value.
DatabaseReference offsetRef = FirebaseDatabase.getInstance().getReference(".info/serverTimeOffset");
offsetRef.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot snapshot) {
        // Calculate the estimated server time based on the offset.
        double offset = snapshot.getValue(Double.class);
        double estimatedServerTimeMs = System.currentTimeMillis() + offset;

        // Use this server time to get the messages.
        getMessages(estimatedServerTimeMs);
    }

    @Override
    public void onCancelled(DatabaseError error) { }
});

public void getMessages(double endTime) {
    DatabaseReference messagesRef = FirebaseDatabase.getInstance().getReference("messages");

    // Create a query to limit results where endTime is greater than the current time.
    Query messagesQuery = messagesRef.orderByChild("endTime").startAt(endTime);

    messagesRef.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for (DataSnapshot message : dataSnapshot.getChildren()) {
                // ...
            }
        }

        @Override
        public void onCancelled(FirebaseError firebaseError) { }
    });
}

此示例首先获取clock skew value (from .info/serverTimeOffset)以计算估计的当前服务器时间,然后在startAt()查询中使用此选项仅返回当前时间之后endTime的消息。

可能还有其他一些方法可以解决这个问题,比如获取服务器时间戳并在保存邮件时执行上述逻辑,甚至只需查询startTime(使用startAt 10小时前)。

但是,使用Cloud Functions路由是确保在服务器端计算endTime的好方法,可以快速执行新消息的保存,并且消息实际上包含endTime值数据库。