如何在Firestore和CloudFunctions中正确查询日期期限

时间:2018-08-21 02:46:32

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

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

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中?

1 个答案:

答案 0 :(得分:2)

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

了解问题所在:
首先要记住,我们是在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();

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