Firebase - 从数据库节点获取随机子节点 [英] Firebase - Get Random Child From Database Node
问题描述
我正在编写一个从 Android
应用调用的 Firebase Cloud Function
.该函数应该从 Database
中的用户节点获取一个随机用户(任何随机用户,但不是发送请求的用户)并将其返回给客户端.问题是数据不是以数组的形式构造的(它不应该也不可能是).
I'm writing a Firebase Cloud Function
that is called from an Android
app. The function should get a random user from the users node in the Database
(Any random user but not the one who sent the request) and return it to the client. The problem is that the data is not structured as an array (And it should not be and can't be).
所以我不能选择一个随机数并读取该节点,我也不想读取所有用户节点并对其进行迭代,因为它包含大量用户,这将耗费时间和资源.问题:
So I can't pick a random number and read that node, I also don't want to read all the users node and iterate it because it contains a lot of users and that would be time and resources-consuming. The Question:
如何获得与发送请求的用户不同的随机用户,并且每次调用函数时都会发生变化(完全随机),同时又不从数据库中查询大量数据?
How can I get a random user different from the one who sent the request, and changes with every time the function is called (completely random), while not querying a lot of data from the database?
推荐答案
主要问题:
Firebase 不会跟踪我们进行随机化所需的子项计数.然而,我们可以使用 DataSnapshot.numChildren()
.
为避免这种情况,您可以将 count
元素添加到 /users
节点,您必须手动维护该元素,使用云功能(例如,在添加用户时,增加 count
,删除时减少).
To avoid this, you can add a count
element to the /users
node, which you would have to maintain manually, using cloud functions (e.g. when adding a user, increment count
, and decrement on deletion).
另一方面,由于云函数在服务器上,firebase 会为你管理缓存,实际使用 DataSnapshot.numChildren()
没什么大不了的,因为数据会在函数第一次执行后被缓存,只有在有变化时才会更新.
On the other hand, since the cloud functions are on the server, and firebase will manage the cache for you, it is not a big deal to actually use DataSnapshot.numChildren()
, since the data will be cached once the function has been executed for the first time, and will be updated only when there are changes.
db.ref('/users').once('value').then(snapshot =>
Math.floor((Math.random() * snapshot.numChildren()))
);
或者使用 count
方法:
db.ref('/users/count').once('value').then(snapshot =>
Math.floor((Math.random() * snapshot.val()))
);
获取随机节点:
db.ref('/users').orderByKey().startAt(random).limitToFirst(1);
// https://stackoverflow.com/a/38423694/4161937
// attach permanent listener to force firebase caching (not sure if it works for this case)
db.ref('/users').on('value', () => {});
// will read #random amount of items
db.ref('/users').orderByKey().limitToFirst(random).once('value').then(users => Object.keys(users)[random]);
方法 2:
// https://stackoverflow.com/a/38423694/4161937
// attach permanent listener to force firebase caching
db.ref('/users').on('value', () => {});
db.ref('/users').once('value').then(users => Object.keys()[random])
您可以在官方文档中阅读有关查询顺序和过滤的更多信息:
You can read more about query order- and filtering in the official docs:
这篇关于Firebase - 从数据库节点获取随机子节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!