从Java中的Firebase实时数据库中选择随机条目 [英] Select random entry from Firebase Realtime Database in Java

查看:47
本文介绍了从Java中的Firebase实时数据库中选择随机条目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个Android应用程序,其中涉及将图像上传和下载到服务器.我为此使用Firebase.所有图像均使用图像哈希作为文件名存储在Firebase存储中.我还维护一个实时数据库,该数据库存储有关图片的一些信息.我需要从存储中选择一个随机图片,所以我决定从数据库中选择一个随机条目.我在SO上找到了答案(如您所见,int用Java语言编写),这将显示以下代码:

I am developing an application for Android that involves uploading and downloading images to a server. I am using Firebase for this purpose. All the images are stored in Firebase storage using the image hash as a filename. I also maintain a Realtime Database that stores some information about the pictures. I need to select a random picture from the storage, so I decided to select a random entry from the database. I found this answer on SO (as you see, int is written in Javascript), which suggests the following code:

const numberOfUsers = 15;
const randomIndex = Math.floor(Math.random() * numberOfUsers);
var ref = firebase.database().ref('companies/01/users');
ref.limitToFirst(randomIndex).limitToLast(1).once('value').then(snapshot =>
{
    var user = snapshot.val();
    // do something with the user data
});

但是当我尝试用Java构建类似的查询时

but when I try to build a similar query in Java

imgref.limitToFirst(random + 1).limitToLast(1).addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            randomHash = dataSnapshot.getKey();
            Log.e("get random name: ", randomHash);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

我收到一个错误

无法在具有预先设置的限制的查询中调用limitToLast!

因此,很明显,我无法在一个查询中使用limitToFirst和LimitToLast.所以这是我的问题:

So obviously I cannot use limitToFirst and LimitToLast in one query. So here is my question:

  1. 是否可以同时使用limitToFirst和limitToLast来使用这种获取随机条目的方法?

  1. Is it possible to use limitToFirst and limitToLast together somehow to use this method of getting a random entry?

是否还有其他方法可以从Firebase实时数据库中获取随机条目,而无需下载整个数据库或对其进行迭代(据我所知,如果我这样做,迭代效率低下)是错误的,请解释)

Is there any other method to get a random entry from a Firebase Realtime Database without downloading the whole database or iterating through it (as far as I understand, iterating is inefficient, if I am wrong, please explain)

如果无法从应用程序内部执行此操作,是否还有其他方法(例如,使用Firebase Cloud Functions)

If it is impossible to do this from inside the app, is there some other way (for example, using Firebase Cloud Functions)

推荐答案

如果您不反对在数据中添加额外的子项,则可以选择几种方法.

If you aren't against adding an extra child to your data, you have a few options.

  1. 您可以使用事务对添加的每个项目进行编号,然后使用带有 startAt(random).limitToFirst(1)的随机数.
  2. 如果要避免事务,可以向每个imgref节点写入一个随机的long.然后,您可以尝试使用新生成的随机查询,如下所示:

  1. You could use a transaction to number each item when they are added, then use a random number with startAt(random).limitToFirst(1).
  2. If you want to avoid the transaction you could write a random long to each imgref node. Then you could try querying with a newly generated random like this:

ref.orderByChild("randomLong").startAt(newRandomLong).limitToFirst(1).addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        if(dataSnapshot.getChildrenCount() > 0){
            for(DataSnapshot snap : dataSnapshot.getChildren()){
                //Do something with your random snapshot
            }
        }else
        {
         /*
         Handle case where the new random Long is after the range 
         currently in the database
         ref.orderByChild("randomLong").endAt(random).limitToLast(1)
         */
        }
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {

    }
});

请注意,#2将根据值之间的随机范围将随机权重添加到您的值中.在较大的列表上,这种效果应该不太明显,但是如果您需要平均分配,则可能需要使用选项#1.

Note that #2 will add random weights to your values based on the random ranges between values. This effect should be less noticeable on larger lists, but if you need an even distribution you probably want to go with option #1.

如果您无法更改当前数据结构,那么我不确定您是否可以像Alex的回答中那样遍历该集合.

If you can't change your current data structure then I'm not sure you can get around iterating the set as in Alex's answer.

这篇关于从Java中的Firebase实时数据库中选择随机条目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆