Javascript Firebase获取特定密钥的所有值
我在Firebase上有一个Javascript Firebase获取特定密钥的所有值,javascript,firebase,firebase-realtime-database,Javascript,Firebase,Firebase Realtime Database,我在Firebase上有一个用户表,每个用户都有一封电子邮件道具 结构如下所示: Users->useruid(看起来像n8habbjgabob2ranfuabu3aaaga2af)->userobj,其中包括email道具 我想获得所有用户的电子邮件(约100万封)的数组 我怎样才能最有效地做到这一点 附言: 我试过: usersRef.startAt(0).endAt(20).once("value", function(snapshot) { console.log('FIRST 20
用户
表,每个用户都有一封电子邮件
道具
结构如下所示:
Users
->useruid
(看起来像n8habbjgabob2ranfuabu3aaaga2af
)->userobj
,其中包括email
道具
我想获得所有用户的电子邮件(约100万封)的数组
我怎样才能最有效地做到这一点
附言:
我试过:
usersRef.startAt(0).endAt(20).once("value", function(snapshot) {
console.log('FIRST 20');
console.log(snapshot.val()); // null
});
但这是失败的。在数据读取方面,最有效的方法可能是对数据进行非规范化。您可以将电子邮件地址存储在单个用户节点和
emailAddresses
节点中。然后,您可以直接查询电子邮件地址
节点以获取电子邮件列表
不过,一次大约1百万个电子邮件地址节点可能太多了。我可能会把它切成块。。。我猜
更新
“分块抓取”本质上是分页。在尝试推出自己的分页解决方案之前,我会尝试使用现成的东西
要签出的分页库:
- :这是Firebase开发的,但他们说这是实验性的,还没有准备好用于生产。但是,它可能仍然值得玩弄
- :这是一个社区成员开发的,看起来相当可靠
- @加藤在《他》一书中的回答就实时数据集分页的潜在问题提出了一个有趣的观点,但随后提供了一些很好的起始代码
- 这是关于我认为是我上面链接的firebase paginator库的一部分的代码
- 每个人在回答中都说这是一件容易的事情,但没有有效的解决方案。以下是我的想法:
usersRef.orderByChild('uid').limitToFirst(100).once('value', function (snapshot) {
var users = snapshot.val()
var uids = Object.keys(users);
var lastUid = uids[uids.length - 1];
// could be another property than uid, for example email, or username. Ps.: Consider that the last ID from the previous chunk will be duplicated.
usersRef.orderByChild('uid').startAt(lastUid).limitToFirst(100).once('value', function (snapshot) {
var users = snapshot.val()
var uids = Object.keys(users);
console.log(uids);
var lastUid = uids[uids.length - 1];
// re-run function until done
})
})
由于这是一次性交易,一个选项是简单地迭代父“数据”节点中的每个节点以捕获子数据,剥离电子邮件地址并将其转储到文件中 你想要的活动是 添加的子项:检索项目列表或侦听列表中的添加项 物品的数量。对于每个现有子级和子级,此事件将触发一次 然后,每次将新的子级添加到指定的路径时。这个 将向侦听器传递一个包含新子级数据的快照 迭代数据节点中所有子节点的代码如下
var dataRef = firebase.database().ref('myRootRef/data');
datRef.on('child_added', function(data) {
//data.val() will contain the child data, such as the email address
//append it to a text file here (for example), save to disk etc.
});
这里的关键是,该事件对每个子级触发一次,类似于对数组中的所有索引进行迭代
这将检索每个子节点并将其呈现给您的应用程序,一次一个,迭代节点中的所有子节点
有这么多节点需要花一段时间来仔细研究。使用childAdded事件迭代所有用户节点非常简单(因此一次只加载一个节点)。但更大的问题是你为什么要这么做?可能有比一次加载它们更好的方法,但我们需要了解您的使用情况。我正在我的网站上发布一份时事通讯,我需要收集所有当前的电子邮件。这是一次性的开始,因为新注册的电子邮件将在用户注册时添加。如果查询正常,我会将所有数据保存在Firebase中,每次发送时事通讯时,我都会查询+成批发送。似乎没有人真正知道如何完成这项工作。Firebase需要做大量工作,才能成为大型站点的可行数据库解决方案(100万用户并不是很大)。不管怎样,我想出了一个解决办法,一个奇怪但有效的办法。事实上,我的评论是一个非常简单和直截了当的答案。使用添加的childAdded对所有数据进行迭代。这需要一段时间,但需要大约10行代码。如何将其分块获取?如果分页使用
orderByChild
,我认为您的第一个查询也应该是:usersRef.orderByChild('uid')。limitToFirst(100)
。(目前,这并不重要,因为键和子项的顺序是相同的,但如果您使用类似子项的电子邮件
——根据您的评论——第一次查询和后续查询之间的顺序将不同。)