查询 Firestore 中时间戳早于今天的项目

mic*_*ers 5 firebase google-cloud-firestore

在新的 Cloud Firestore 中,您可以在创建对象期间使用以下行在我的消息对象上设置服务器时间戳:

showtime: firebase.firestore.FieldValue.serverTimestamp()
Run Code Online (Sandbox Code Playgroud)

这对于来自任何用户的消息都很有用,因为它不依赖于每个用户的本地时钟。

我面临的挑战是事后查询和设置放映时间字段。我想做的是查找任何显示时间早于“现在”的消息。在我的应用程序中,许多消息被推送到未来。我只希望今天之前放映的作品能够被退回并展示。

这是我的查询:

  var query = firebase.firestore()
                  .collection('messages')
                  .where('owner','==',userID)
                  .where('showtime','<',timenow)
                  .orderBy('showtime', 'desc')
                  .limit(25);
Run Code Online (Sandbox Code Playgroud)

挑战是我不知道如何获取当前时间(在服务器上)以在查询中使用。Firebase 中有一个对 Timestamp 类型的 now() 调用,但我不确定如何调用它,并且根据此处的其他一些问题,我不确定 Firebase 时间戳是否与 Cloud Firestore 时间戳匹配!

所以问题是:如何将名为 timenow 的变量设置为服务器上的当前时间,并在查询中使用它来提取之前的 25 条消息?(在客户端的 Javascript 中以及在服务器上的函数中获得额外的积分)

一个快速跟进的问题是如何将放映时间时间戳更新为比现在晚一周?

希望 Stackoverflow 上有一些 Firebase / Cloud Firestore 专家!

** 选择下面的答案并附带功能请求的说明:在 Firebase 中调用服务器以请求当前时间戳,以便客户端代码可以在一个标准时钟下工作。**

Ale*_*lop 0

您是对的serverTimestamp(),正是为了在服务器上获取时间戳,而不是依赖于用户本地时钟。需要注意的一件事是,通常发送消息并从用户本地时钟获取时间戳是可以的,因为消息时间戳对时间不太敏感。当然,您想知道消息何时发送,但如果在 1-2 秒内发送,则在大多数情况下都不是问题。

如果您在客户端执行查询,则查询不应基于服务器时间,而应基于客户端。因为它是客户端查询而不是服务器查询。

这是您正在寻找的客户查询。

const currentTime = new Date();
const query = firebase.firestore()
                  .collection('messages')
                  .where('owner','==',userID)
                  .where('showtime','<',currentTime)
                  .orderBy('showtime', 'desc')
                  .limit(25);
Run Code Online (Sandbox Code Playgroud)

此查询将在客户端上的当前时间之后获取 25 条带有“showtime”的消息。

现在,如果消息需要对时间极其敏感,并且您确实需要基于服务器时间戳的消息,我建议您不要像上面那样在客户端上进行查询,而是设置一个云函数 api。如果您之前没有直接调用云函数,请查看 firebase 文档。

您希望云函数如下所示:

import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
admin.initializeApp()

exports.getUserMessages = functions.https.onCall((data, context) => {
    const uid = context.auth.uid;
    const firestore = admin.firestore();
    firestore.collection('messages')
             .where('owner', '==', uid)
             .where('showtime', '<', new Date())
             .orderBy('showtime', 'desc')
             .limit(25)
             .get()
             .then(snapshot => {
                return snapshot;
             });
});
Run Code Online (Sandbox Code Playgroud)

这将根据服务器时间戳获取消息。需要注意的一件事是,除非您需要对时间极其敏感,否则这不是一个好主意。因为每次调用此调用时都必须进行额外的不必要的调用。因为您正在调用云函数,然后正在查询 firestore 数据库。我建议不要根据服务器时间执行此操作,而是根据客户端时间戳执行此操作。百分之九十九的客户端和服务器之间的时间差不值得您进行额外的两次调用,尤其是当您考虑在获得更多用户时扩展所有内容时。

希望回答了您的问题:)

  • 用户可以通过更改本地日期并发布帖子或评论来在许多应用程序中获得优势。在构建一个强大的应用程序时,关键是要有一个明确的时间源,并且应该是服务器而不是客户端。构建一个类似于 SnapChat、Instagram 或任何现代社交网络的功能良好的应用程序需要此功能。 (2认同)