【问题标题】:How to query correctly a date period in firestore and cloudfunctions如何在 firestore 和 cloudfunctions 中正确查询日期时间段
【发布时间】:2018-08-21 02:46:31
【问题描述】:

我有一个包含下一个项目的集合,它们的属性之一是日期:

id:   xxxxxx
name: xxxx
date: August 21, 2018 at 1:00:00 AM UTC+8 (timestamp)

在 Firebase 云函数中,我尝试查询某个时期的所有对象,该时期可以是日、周、年等。

我想按当前服务器日期查询项目,所以我在 Firebase Cloud Function 中执行此操作:

let auxDate = moment();
dateStart = auxDate.startOf('day').toDate();
dateEnd = auxDate.endOf('day').toDate();
await admin.firestore().collection('items')
            .where("date", ">=", dateStart)
            .where('date', '<=', dateEnd).get();

控制台打印的dateStart和dateEnd的值为:

Date start: Tue Aug 21 2018 00:00:00 GMT+0000 (UTC)
Date end:   Tue Aug 21 2018 23:59:59 GMT+0000 (UTC)

查询返回 0 个项目。但是当我将项目的日期更改为

id:   xxxxxx
name: xxxx
date: August 21, 2018 at 8:00:00 AM UTC+8 (timestamp)

查询正确返回项目。

所以现在我知道问题出在偏移量上,但我该如何解决呢?为什么 firebase 以 UTC+8 保存所有日期?

【问题讨论】:

标签: firebase google-cloud-firestore google-cloud-functions


【解决方案1】:

我找到了自己问题的答案。我会详细解释的。

了解问题:
首先要记住我们是在 Cloud Function 中执行此查询,因此我们不知道客户端时区。在 Firestore 中,所有日期都保存在 UTC+00 中。所以如果我有这样的项目:

id:   xxxxxx
name: xxxx
date: August 22, 2018 at 12:00:00 AM UTC+8 (timestamp)

表示这个日期等于August 21, 2018 at 04:00:00 PM UTC+0

所以如果我想查询以下之间的所有日期:

Date start: August 22, 2018 at 12:00:00 AM UTC+8 (timestamp) 
Date end: August 22, 2018 at 11:59:59 PM UTC+8 (timestamp) 

这意味着查询必须是这样的:

Date start: August 21, 2018 at 04:00:00 AM UTC+0 (timestamp) 
Date end: August 22, 2018 at 03:59:59 PM UTC+0 (timestamp) 

所以问题是当我执行let auxDate = moment() 时,这会创建一个没有偏移的服务器时间日期,因此 auxDate 的值例如是:August 21, 2018 at 11:23:43 PM UTC+0

所以从 auxDate 开始的日期变成:

auxDate start: August 21, 2018 at 12:00:00 AM UTC+0 (timestamp) 
auxDate end: August 21, 2018 at 11:59:59 PM UTC+0 (timestamp) 

正如我们所见,这个查询没有填满我们必须查询的范围,许多项目将被排除在外。

问题结论:
如果我们不知道客户端的时区,我们将无法正确查询。

解决方案:
现在我将客户端的当前时间传递给这个云函数并计算开始和结束日期:

const clientCurrentDateTime = "2018-08-22T11:23:15+08:00";
let startDate = moment(clientCurrentDateTime).utcOffset(clientCurrentDateTime).startOf('day').toDate();
let endDate = moment(clientCurrentDateTime).utcOffset(clientCurrentDateTime).endOf('day').toDate();

这将为不同的偏移量/时区创建正确的开始和结束日期时间

【讨论】:

    猜你喜欢
    • 2019-02-12
    • 2020-10-10
    • 1970-01-01
    • 1970-01-01
    • 2019-08-18
    • 2018-05-31
    • 1970-01-01
    • 2012-02-29
    • 2021-01-15
    相关资源
    最近更新 更多