如何从ValueEventListener Firebase检索数据

时间:2018-05-18 08:49:20

标签: java android firebase firebase-realtime-database

我有一个使用Google Firebase的Android应用。

我需要下载带有随机ID的图片。

我有一个必须返回随机图片位图的函数。在这个函数中,我从一个单独的数据库条目中读取图片数量,然后生成一个从1到图片数量的随机ID。这是代码:

    Random rand = new Random();
    DatabaseReference amountRef = dbref.child("amount");
    amountRef.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            amount = dataSnapshot.getValue(Long.class);

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
    long random = rand.nextLong() % amount + 1;

该函数稍后下载图像并生成并返回位图。问题是Listener代码是与其他代码和行

并行执行的
long random = rand.nextLong() % amount + 1;

产生除零错误,因为数量变量尚未更新。我也无法将所有代码放在OnDataChange中,因为我需要返回位图。请告诉我如何立即检索数据或从侦听器内部返回位图。

4 个答案:

答案 0 :(得分:2)

你必须像这样使用它

Random rand = new Random();
    DatabaseReference amountRef = dbref.child("amount");
    amountRef.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            amount = dataSnapshot.getValue(Long.class);
            // add Random rand = new Random(); here if you need new random objects everytime.
            long random = rand.nextLong() % amount + 1;
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

您正在尝试从异步函数访问数据,因此如果您尝试访问变量之后,它可能尚未完成其工作,因此它可能返回null,它不确定,因此您必须在内部访问它

答案 1 :(得分:2)

您现在无法返回尚未加载的内容。换句话说,您不能简单地使用amount方法之外的onDataChange()对象,因为此方法的异步行为始终为null。这意味着当您尝试在该方法之外使用该结果时,数据尚未从数据库中完成加载,这就是无法访问的原因。

快速解决此问题的方法是仅在onDataChange()方法中使用这些结果,或者如果您想在外面使用它,我建议您从 {{看到我的anwser的最后一部分3}} 我已经解释了如何使用自定义回调来完成它。您还可以查看此 post ,以便更好地理解。

答案 2 :(得分:0)

您可以使用 visibility = gone 的文本视图(这样它就不会在您的活动中显示)。使用setText()为其设置值。 从Value Event Listener中退出后,使用getText()获取您的值。 这只是一个技巧,对您有很大帮助。 您的代码将如下所示:

 TextView textview=findViewById(R.id.textView);
Random rand = new Random();
    DatabaseReference amountRef = dbref.child("amount");
    amountRef.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            amount = dataSnapshot.getValue(Long.class);
textview.setText(""+amount);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
int amount=Integer.parseInt(textview.getText());
    long random = rand.nextLong() % amount + 1;

希望这会有所帮助:)

答案 3 :(得分:0)

面对这个挑战,我仍然没有解决的办法。我想在onChangeMethod之外使用变量。

相关问题