Firebase-从数据库节点获取随机子级

时间:2018-07-26 12:45:24

标签: javascript node.js firebase firebase-realtime-database

我正在编写一个def create @task = Task.find(params[:task_id]) #@task = policy_scope(@venue.tasks).find(params[:task_id]).decorate #authorize @task if params[:images] params[:images].each do |image| @task.task_assets.create(image: image) end end @task_assets = @task.task_assets authorize @task_assets, :create? @result = [@task_assets, @venue] respond_to do |format| format.json { @task_asset.to_json } format.js{ @result } #format.js {render js: 'alert("success")'} # now you cann append that image to te image list here or create create.js.erb ...ok I have that alreday let try end end 应用调用的Firebase Cloud Function。该函数应该从Android中的users节点获取一个随机用户(任何随机用户,但不是发送请求的用户),然后将其返回给客户端。问题在于数据没有被构造成数组(它应该也不能是)。

Data structure in the database.

因此,我无法选择一个随机数来读取该节点,我也不想读取所有用户节点并对其进行迭代,因为它包含许多用户,这将浪费时间和资源。 问题:

  

我如何获得一个与发送请求的用户不同的随机用户,并在每次调用该函数时进行更改(完全随机),而又不从数据库中查询大量数据?

1 个答案:

答案 0 :(得分:1)

主要问题:

Firebase无法跟踪子计数,这是我们进行随机化所需的。但是,我们可以使用DataSnapshot.numChildren()

为避免这种情况,您可以向count节点添加一个/users元素,您必须使用云功能对其进行手动维护(例如,在添加用户时,递增count ,并在删除时减少)。

另一方面,由于云功能在服务器上,并且Firebase会为您管理缓存,因此实​​际使用DataSnapshot.numChildren()并不重要,因为一旦该功能将对数据进行缓存已第一次执行,并且仅在发生更改时才会更新。

因此,我建议使用numChildren()函数:

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);

方法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])

您可以在官方文档中了解有关查询顺序和过滤的更多信息:

Retrieving Data - How Data is Ordered