安卓从Java中的Firebase实时数据库中选择随机条目
我正在为Android开发一个应用程序,包括上传和下载图像到服务器。我使用Firebase来实现这个目的。所有图像都使用图像哈希作为文件名存储在Firebase存储器中。我还维护了一个实时数据库,其中存储了一些有关图片的信息。我需要从存储器中随机选择一张图片,所以我决定从数据库中随机选择一个条目。我发现了this答案(如您所见,int是用Javascript编写的),这表明以下代码:
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构建类似的查询时
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) {
}
});
我收到一个错误
Can't call limitToLast on query with previously set limit!
所以很明显,我不能在一个查询中使用limitToFirst和LimitToLast。所以我的问题是:
有没有可能同时使用limitToFirst和limitToLast来获得一个随机条目
有没有其他方法可以从Firebase实时数据库中获取随机条目,而无需下载整个数据库或对其进行迭代(据我所知,迭代效率很低,如果我错了,请解释)
如果无法从应用程序内部执行此操作,是否有其他方法(例如,使用Firebase云功能)
# 1 楼答案
你需要知道你的模型是如何获得一个随机密钥的。如果它是
1,2,3,4,5
id,你可以像现在一样使用它,这样你就可以比较它了。 最好的方法是将所有键值存储在一个数组中,根据数组大小选择一个随机数,然后选择随机数的索引。他们使用类似答案中的代码dataSnapshot.getKey();
# 2 楼答案
如果你不反对在数据中添加额外的子项,你有几个选择
startAt(random).limitToFirst(1)
的随机数李>如果想要避免该事务,可以向每个imgref节点写入一个随机的long。然后,您可以尝试使用新生成的随机数据进行查询,如下所示:
请注意#2将根据值之间的随机范围为值添加随机权重。这种影响在较大的列表上应该不那么明显,但如果你需要一个均匀的分布,你可能希望选择#1
如果您不能更改当前的数据结构,那么我不确定您是否可以像Alex的回答中那样迭代集合