【发布时间】: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 生成)。
在我的网络应用程序中,我想:
- 获取属于特定用户的所有投资
- 然后,监听属于该用户的任何新添加的投资
我想同时获取所有现有投资的原因是我的应用程序不会在每次调用 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;
});
}, []);
但是,我担心如果用户拥有大量现有投资会发生什么。特别是,我担心两件事:
-
child_added 回调将为每个现有投资调用。我知道firebase保证 child_added 事件在 value 事件之前触发,但它可以保证 child_added 回调中的代码在代码之前执行value 里面的事件回调被执行了吗?如果不是,那么在执行所有
if (initialDataLoaded) {}行之前,initialDataLoaded是否可能设置为 true? - 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