【问题标题】:How to reverse timestamp to order documents by latest in firestore如何通过最新的firestore反转时间戳以订购文档
【发布时间】:2021-09-27 00:41:07
【问题描述】:

((已解决))

希望得到一些帮助来解决这个奇怪的问题,首先我是 JS 和 Firebase 的新手,所以我可能在这里错过了明显的东西。在任何情况下,我都在尝试将时间戳转换为负数,以便对文档进行排序,如果我在查询调用中限制它们,则始终获取最新的 10 个。

但是,下面的代码尝试在 Cloud Functions 中运行时会引发错误。

如果我 console.log (-Math.abs(timestamp)) 客户端但是,我得到一个负数就好了。有人在这里帮助解决这个问题和/或提供解决方法吗?

// create welcome post on new user signup
exports.createWelcomePost = functions.auth.user().onCreate((user) => {
  const uid = user.uid;
  const userName = user.displayName;
  const photoURL = user.photoURL;
  const timestamp = admin.firestore.FieldValue.serverTimestamp();
  const order = -Math.abs(timestamp);

  const db = admin.firestore();
  const docRef = db.collection('posts');

  docRef.add({
    order: order,
    created: timestamp,
    createdBy: uid,
    userName: displayName,
    userImage: photoURL,

    content: "...just joined the Startly Community, let's give him a warm welcome!",
    featuredImage: "assets/img/welcome_post.jpg"
  })
  .then((docRef) => {
      console.log("Welcome post created with ID: ", docRef.id);
  })
  .catch((error) => {
      console.error("Error creating post: ", error);
  });
  // ...
});

【问题讨论】:

  • 您能否分享一下您想要获取最新 10 个的查询?您不需要将时间戳添加为负数。

标签: javascript node.js firebase google-cloud-firestore google-cloud-functions


【解决方案1】:

doc 中所述,serverTimestamp 返回一个标记,与set()update() 一起使用,以在写入的数据中包含服务器生成的时间戳。

术语哨兵意味着确切的值是在后端计算的,即在将文档写入 Firestore 时在 Firestore 平台上。这就是为什么您不能将此值用于例如-Math.abs().

使用serverTimestamp 代替客户端生成的时间戳值(例如Date.now())的优点是该值独立于用户计算机的设置和时区。将始终考虑服务器时间。


总之,您应该按照定义的方式保留 timestamp 值,删除 order 字段,并在查询时使用 .orderBy("created", "desc"),如 Dharmaraj 的回答中所述。

【讨论】:

  • 非常感谢!这非常快速和简洁,所以确实只是一个菜鸟错误:)
【解决方案2】:

如果您在文档中添加 UNIX 时间戳(或 serverTimestamp),您应该能够按降序对它们进行排序。

db.collection("posts")
  .orderBy("created", "desc")
  .limit(10)
  .get()

此查询应获取 10 个最新文档,即按已创建字段的值以降序对文档进行排序,并限制为前 10 个结果。

添加文档时,可以这样添加时间戳:

const timestamp = Date.now()

docRef.add({
  created: timestamp,
  ...otherFields
})

您可以使用 serverTimestamp 本身,因为它比 @Renaud 解释的 Date.now() 有几个好处。当您获取文档时,created 字段将是一个对象,如下所示:

{
  created: {
    seconds: 1627370100,
    nanoseconds: 0
  }
}

然后您可以使用 toDate 方法将其转换为 Javascript 日期。

const {created} = snapshot.val()
console.log(created.toDate()) // JS Date object
console.log(Date.parse(created.toDate())) // Timestamp in milliseconds

题外话,但您应该在云函数中返回承诺,因此添加 return 关键字:

return docRef.add({}).then(() => {
^^^^^^
  console.log("Doc added")
  return
}).catch((e) => {
  console.log(e)
  return null
})

【讨论】:

  • 非常感谢您提供这个深入的答案,我用谷歌搜索通过 desc 订购。而所有出现的是那个firestore“不能”这样做,这对我来说似乎很奇怪! - 我马上就开裂了:)
  • @DavidGriffin 也许你在寻找不支持它的sorting in realtime database ;)
猜你喜欢
  • 2018-10-31
  • 1970-01-01
  • 2019-11-25
  • 2021-02-07
  • 2011-05-24
  • 2018-11-07
  • 1970-01-01
  • 2020-02-08
  • 2020-12-26
相关资源
最近更新 更多