【问题标题】:How to retrieve data from ValueEventListener Firebase如何从 ValueEventListener Firebase 中检索数据
【发布时间】:2018-05-18 08:49:19
【问题描述】:

我有一个使用 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 中,因为我需要返回位图。请告诉我如何立即检索数据或从侦听器内部返回位图。

【问题讨论】:

    标签: java android firebase firebase-realtime-database


    【解决方案1】:

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

    一个快速解决这个问题的方法是仅在 onDataChange() 方法内使用这些结果,或者如果你想在外面使用它,我建议你从这个 post 我在其中解释了如何使用自定义回调来完成。您也可以看看这个 video 以获得更好的理解。

    【讨论】:

      【解决方案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) {
      
              }
          });
      

      你正试图从一个异步函数访问数据,所以如果你试图在变量之后访问 if,它可能还没有完成它的工作,所以它可能返回 null,它不确定,所以你必须在里面访问它.

      【讨论】:

      • 正如我所说,我无法在 onDataChange 中插入代码,因为我需要在函数中进一步使用这些数据
      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        您可以使用带有 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;
        

        【讨论】:

        • 据我了解,这不起作用,因为侦听器是异步的,并且在执行 getText() 时不会设置文本
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-27
        • 1970-01-01
        • 2017-10-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多