在我们的应用中,保存新数据的结束日期时间非常重要。
例如,如果要编写新邮件,我希望用户只能看到十个小时。随着休息api&在SQL数据库中,我可以轻松地创建服务器时间(+十小时)的结束日期时间并将消息保存在数据库中。为用户加载消息时,我可以选择结束日期时间之前的所有消息。
如何使用Firebase实时数据库执行此操作?也许使用Firebase云功能?我不想使用客户时间。
答案 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
值数据库。