How to add all data at once in a HashMap under addChildEventListener() of Firebase?

孤街醉人 提交于 2019-12-20 06:05:11

问题


I have some data at a certain reference in Firebase and I'm retrieving it using addChildEventListener() and putting it in a HashMap<String, Object> like this:

final HashMap<String, Object> map1 = new HashMap<>();
ref.child(requestID).child(key).addChildEventListener(new ChildEventListener() {
          @Override
          public void onChildAdded(DataSnapshot dataSnapshot, String s) {
              if (dataSnapshot.getValue() != null) {
                  map1.put(dataSnapshot.getKey(), dataSnapshot.getValue());
                  Log.d("map1", map1.toString());
              } else {
              }
    }
    ...
    ...
});

The problem is that the data is getting added one-by-one and Log.d is printing out:

D/map1: {key=value}
D/map1: {key=value, key=value}
D/map1: {key=value, key=value, key=value}
D/map1: {key=value, key=value, key=value, key=value}
D/map1: {key=value, key=value, key=value, key=value, key=value}

What I want is to put this data into map1 all at once and get this D/map1: {key=value, key=value, key=value, key=value, key=value} printed out.

I want to use addChildEventListener() only as I want to run the piece of code only when onChildAdded() and not every time onDataChange().

Please help me figure this out.


回答1:


A ChildEventListener is triggered for each individual child. That is a great interface if you're doing something like updating the user interface, because you can know exactly what to do: onChildAdded -> add UI element, onChildChanged -> update UI element, etc.

If you want to get all matching elements in one go, you should use a ValueEventListener:

ref.child(requestID).child(key).addValueEventListener(new ValueEventListener() {
      @Override
      public void onDataChange(DataSnapshot dataSnapshot) {
          HashMap<String, Object> map1 = new HashMap<>();
          for (DataSnapshot childSnapshot: dataSnapshot.getChildren()) {
              map1.put(childSnapshot.getKey(), childSnapshot.getValue());
          }
          Log.d("map1", map1.toString());
      }



回答2:


I don't think there is a very clean solution to exactly what you are trying to achieve. You want to get all the data at once instead of one by one, but what happens when you get a new child? You will get it one by one.

You could do something like this which would theoretically give you the entire hashmap at once, but for any subsequent children added, they too will be added one by one. You will have to use ValueEventListener, only once however, and move your old code inside it's onDataChange.

    reference.child(requestID).child(key).addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            long startChildCount = dataSnapshot.exists() ? dataSnapshot.getChildrenCount() : 0;
            int i = 0;
            HashMap<String, Object> map1 = new HashMap<>();
            ArrayList<DataSnapshot> tempSnapshots = new ArrayList<>();
            reference.child(requestID).child(key).addChildEventListener(new ChildEventListener() {
                @Override
                public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                    i++;
                    if (i < childCount) {
                        tempSnapshots.add(dataSnapshot);
                    } else if (i == childCount) {
                        for (DataSnapshot snapshot : tempSnapshots) {
                            map1.put(snapshot.getKey(), snapshot.getValue());
                        }
                    } else {
                        map1.put(dataSnapshot.getKey(), dataSnapshot.getValue());
                    }
                }
            });
        }
    });


来源:https://stackoverflow.com/questions/42469250/how-to-add-all-data-at-once-in-a-hashmap-under-addchildeventlistener-of-fireba

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!