【问题标题】:How to load data once, then listen for new data with child_added event?如何加载一次数据,然后使用 child_added 事件监听新数据?
【发布时间】:2021-06-06 14:33:37
【问题描述】:

我在 Firebase 实时数据库中有一些数据,如下所示:

users: {
    $user1: {
        email: "person@gmail.com"
        name: "Bob"
    },
    $user2: {
        email: "otherperson@gmail.com"
        name: "Sally"
    },
    ...
}

investments: {
  $investment1: {
    user: $user1,
    ticker: "GOOG",
    name: "Google Inc",
    ...
  },
  $investment2: {
    user: $user1,
    ticker: "AAPL",
    name: "Apple Inc",
    ...
  },
  $investment3: {
    user: $user2,
    ticker: "TSLA",
    name: "Tesla Inc",
    ...
  },
  ...
}

其中$user1 表示user1 的id(由firebase 生成)。

在我的网络应用程序中,我想:

  1. 获取属于特定用户的所有投资
  2. 然后,监听属于该用户的任何新添加的投资

我想同时获取所有现有投资的原因是我的应用程序不会在每次调用 child_added 侦听器回调时重新呈现。

对于少量投资,以下代码应该可以正常工作。

const userId = "..."; // userId of logged in user

let initialDataLoaded = false;

// For newly added investments
database
  .ref("investments")
  .orderByChild("user")
  .equalTo(userId)
  .on("child_added", (snapshot) => {
    if (initialDataLoaded) {
      const newlyAddedInvestment = snapshot.val();
      /* add new row to table */
    }
  });

// For existing investments
database
  .ref("investments")
  .orderByChild(userId)
  .equalTo(userId)
  .once("value", (snapshot) => {
    const existingInvestments = snapshot.val();
    /* display existing investments in a table */
    initialDataLoaded = true;
  });
}, []);

但是,我担心如果用户拥有大量现有投资会发生什么。特别是,我担心两件事:

  1. child_added 回调将为每个现有投资调用。我知道firebase保证 child_added 事件在 value 事件之前触发,但它可以保证 child_added 回调中的代码在代码之前执行value 里面的事件回调被执行了吗?如果不是,那么在执行所有 if (initialDataLoaded) {} 行之前,initialDataLoaded 是否可能设置为 true?
  2. child_added 回调将为每个现有投资调用。这可能会占用大量带宽。

我在另一个SO post 中读到,我可以为所有投资添加createdAt 时间戳,然后使用ref.orderByChild('createdAt').startAt(Firebase.ServerValue.TIMESTAMP); 查询仅获取新添加的投资。我喜欢这个解决方案,因为它可以扩展到大型数据集,但是,因为我已经通过user 订购,我不相信我可以使用这种方法(如果我错了,请纠正我)。如果有办法只检索在Firebase.ServerValue.TIMESTAMP 之后开始的用户投资,这也将回答我的问题。如果这是实时数据库的限制,我可能会尝试 Cloud Firestore,因为我知道它支持更复杂的查询,这将解决这个问题。

我可能想多了,但我想要一个可靠的解决方案,不会导致不必要的重新渲染,也不会导致不必要的事件触发。

【问题讨论】:

    标签: firebase firebase-realtime-database google-cloud-firestore


    【解决方案1】:

    阅读您的帖子我可以帮助您,我想我可以帮助您提供一些信息。

    关于您问的第一个问题,您是否可以保证 child_add 的回调中的代码会在他的值回调中的代码之前执行。响应将视情况而定,取决于您在每个回调中输入的代码,一个可能会比另一个需要更长的时间,但这取决于。

    关于第二个问题,您可以查看page,这将帮助您准确找出占用带宽的引用(包括子代)并检查占用了这么多带宽的代码部分。

    对于最后一个问题,您也许可以将 Firebase.ServerValue.TIMESTAMP 与用户过滤器一起使用,但在寻找一段时间后,实施起来可能有点复杂,也许更简单的解决方案是使用 Cloud Firestore因为像你说的那样处理更复杂的查询。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-20
      • 2011-04-24
      • 2018-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多