【问题标题】:Not able to iterate over array of users pulled from firebase [duplicate]无法迭代从firebase中提取的用户数组[重复]
【发布时间】:2019-12-20 00:21:09
【问题描述】:

我正在为我正在处理的网页使用 Firebase 的 Cloud Firestore。我当前设置为在添加/加入新用户时在“用户”集合中创建一个新文档。问题是当我尝试拉下用户列表以对其进行迭代时,我无法做到。

我尝试过迭代不同类型的循环。当控制台记录为 0 时,循环似乎不会以对象的长度运行。

let temp = [];
db.collection("Users").onSnapshot(res => {
  const changes = res.docChanges();
  changes.forEach(change => {
    if (change.type === "added") {
      temp.push({
        id: change.doc.id,
        email: change.doc.data().email
      });
    }
  });
});
console.log(temp);
console.log(temp.length);

我预计第二个控制台日志为 2,但它输出 0。奇怪的是,当我从上面的控制台日志中查看对象时,它显示它的长度为 2,并显示其中的当前数据:

【问题讨论】:

  • 那是因为数组被记录时是空的(因为数组填充在回调中,因此是异步的),然后,当您打开(扩展)数组时,值会更新,但不会顶层展示

标签: javascript firebase google-cloud-firestore


【解决方案1】:

数据从 Firestore 异步加载。由于这可能需要一些时间,因此您的主代码将在数据加载时继续运行。然后在加载数据时,调用你的回调函数。

您可以通过添加一些日志记录在实践中轻松看到这一点:

console.log("Before starting onSnapshot");
db.collection("Users").onSnapshot(res => {
  console.log("Got data");
});
console.log("After starting onSnapshot");

当您运行此代码时,它会记录:

在开始快照之前

启动onSnapshot后

得到数据

这可能不是您预期的顺序,但它完全解释了为什么日志语句不能按您预期的那样工作。当您记录数组长度时,尚未从数据库中加载数据。

记录数组似乎确实有效的原因是 Chrome 在数据加载后更新了日志输出。如果你把它改成console.log(JSON.stringify(temp));,你会看到它记录了一个空数组。

这意味着所有需要访问数据的代码都必须在回调中,或者从那里调用:

let temp = [];
db.collection("Users").onSnapshot(res => {
  const changes = res.docChanges();
  changes.forEach(change => {
    if (change.type === "added") {
      temp.push({
        id: change.doc.id,
        email: change.doc.data().email
      });
    }
  });
  console.log(temp);
  console.log(temp.length);
});

正如您可能想象的那样,许多不熟悉异步 API 的开发人员都会遇到这个问题。我建议研究一下之前关于这个主题的一些问题,例如:

【讨论】:

    猜你喜欢
    • 2022-01-20
    • 1970-01-01
    • 2017-12-14
    • 1970-01-01
    • 1970-01-01
    • 2020-12-16
    • 1970-01-01
    • 2021-12-05
    • 2020-12-16
    相关资源
    最近更新 更多