从Firebase中的一键获取全部值

时间:2018-07-24 15:54:16

标签: android firebase firebase-realtime-database

我想从目的地获取整个值(0〜5)

这是实时数据库中json数据的一部分

{"results" : [{
"destin_num" : 6,
"destinations" : [ "asdf", "qwwee", "zzzxcv11", "jkkk", "lkjhhg", "zxcvb" ],
"name" : "asdfasdfff",
"order" : 2,
"required_time" : "6hours"  }]}

我想在String List中放入的值,我使用ChildEventListener()将值添加到List中,但是在完成ChildEventListener()之后,该值无法放入List中.List方向上没有任何内容如何获取值?

List<String> direction=new ArrayList<String>();

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_maps);
    // Obtain the SupportMapFragment and get notified when the map is ready to be used.
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);

    DatabaseReference reference_contacts = FirebaseDatabase.getInstance().getReference("results").child("1").child("destinations");

   reference_contacts.addChildEventListener(new ChildEventListener() {
      @Override

      public void onChildAdded(DataSnapshot dataSnapshot, String s) {
          String data=dataSnapshot.getValue().toString();
          direction.add(data);
      }

      @Override
      public void onChildChanged(DataSnapshot dataSnapshot, String s) {

      }

      @Override
      public void onChildRemoved(DataSnapshot dataSnapshot) {

      }

      @Override
      public void onChildMoved(DataSnapshot dataSnapshot, String s) {

      }

      @Override
      public void onCancelled(DatabaseError databaseError) {

      }
      });


    for(int i=0;i<direction.size();i++){
        Log.e("Get data",direction.get(i));
    }

}

1 个答案:

答案 0 :(得分:1)

这是因为数据是从Firebase异步加载的。您的for循环打印值实际上是在被调用之前 onChildAdded运行。通过添加一些日志记录,最容易看到这一点:

Log.i("Firebase", "Before adding listener");
reference_contacts.addChildEventListener(new ChildEventListener() {
  @Override

  public void onChildAdded(DataSnapshot dataSnapshot, String s) {
    Log.i("Firebase", "In onChildAdded");
  }

  @Override
  public void onChildChanged(DataSnapshot dataSnapshot, String s) { }

  @Override
  public void onChildRemoved(DataSnapshot dataSnapshot) { }

  @Override
  public void onChildMoved(DataSnapshot dataSnapshot, String s) { }

  @Override
  public void onCancelled(DatabaseError databaseError) {
    throw databaseError.toException(); // don't ignore errors
  }
});
Log.i("Firebase", "After adding listener");

运行此代码时,它会打印:

  

在添加侦听器之前

     

添加侦听器后

     

在onChildAdded

这可能不是您期望的顺序。但是,这完全解释了为什么direction列表在您打印时为空,尚未加载数据,因此从未调用过onChildAdded

解决方案通常是将需要数据的代码添加到onChildAdded方法中

所以:

reference_contacts.addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String s) {
     String data=dataSnapshot.getValue().toString();
     direction.add(data);
     Log.i("Got data",direction);
  }

  @Override
  public void onChildChanged(DataSnapshot dataSnapshot, String s) {

  }

  @Override
  public void onChildRemoved(DataSnapshot dataSnapshot) {

  }

  @Override
  public void onChildMoved(DataSnapshot dataSnapshot, String s) {

  }

  @Override
  public void onCancelled(DatabaseError databaseError) {
    throw databaseError.toException(); // don't ignore errors
  }
});

如果只想在加载所有内容后显示数据,则可以改用ValueEventListener

reference_contacts.addValueEventListener(new ValueEventListener() {
  @Override

  public void onDataChange(DataSnapshot snapshot) {
    for (DataSnapshot dataSnapshot: snapshot.getChildren()) {
      String data=dataSnapshot.getValue(String.class);
      direction.add(data);
    }
    for(int i=0;i<direction.size();i++){
      Log.e("Get data",direction.get(i));
    }
  }
  @Override
  public void onCancelled(DatabaseError databaseError) {
    throw databaseError.toException(); // don't ignore errors
  }
});

请注意,对于刚接触Firebase(通常是异步API)的开发人员来说,这是一个令人难以置信的普遍困惑。我强烈建议您研究一些有关该主题的先前问题的答案: