How to extract a list of objects from Firebase DataSnapshot on android

AndroidFirebaseFirebase Realtime-Database

Android Problem Overview


I want to convert all Firebase DataSnapshot children to a list in android.

Something like this:

mFirebaseRef = new Firebase(FIREBASE_URL);

mFirebaseRef.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        List<String> td = (ArrayList<String>) dataSnapshot.getValue();
        //notifyDataSetChanged();
    }

    @Override
    public void onCancelled(FirebaseError firebaseError) {

    }
});

Android Solutions


Solution 1 - Android

I hope below code works

Firebase ref = new Firebase(FIREBASE_URL);
  
  ref.addValueEventListener(new ValueEventListener() {
      @Override
      public void onDataChange(DataSnapshot snapshot) {
          Log.e("Count " ,""+snapshot.getChildrenCount());
          for (DataSnapshot postSnapshot: snapshot.getChildren()) {
            <YourClass> post = postSnapshot.getValue(<YourClass>.class);
            Log.e("Get Data", post.<YourMethod>());
          }
      }
      @Override
      public void onCancelled(FirebaseError firebaseError) {
          Log.e("The read failed: " ,firebaseError.getMessage());
      }
  });

Solution 2 - Android

Firebase stores a sequence of values in this format:

"-K-Y_Rhyxy9kfzIWw7Jq": "Value 1"
"-K-Y_RqDV_zbNLPJYnOA": "Value 2"
"-K-Y_SBoKvx6gAabUPDK": "Value 3"

If that is how you have them, you are getting the wrong type. The above structure is represented as a Map, not as a List:

mFirebaseRef = new Firebase(FIREBASE_URL);

mFirebaseRef.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        Map<String, Object> td = (HashMap<String,Object>) dataSnapshot.getValue();

        List<Object> values = td.values();

        //notifyDataSetChanged();
    }

    @Override
    public void onCancelled(FirebaseError firebaseError) {

    }
});

Solution 3 - Android

FirebaseDatabase mFirebaseDatabase = FirebaseDatabase.getInstance();
 DatabaseReference databaseReference =    mFirebaseDatabase.getReference(FIREBASE_URL);
        databaseReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

                for (DataSnapshot childDataSnapshot : dataSnapshot.getChildren()) {
                    Log.v(TAG,""+ childDataSnapshot.getKey()); //displays the key for the node
                    Log.v(TAG,""+ childDataSnapshot.child(--ENTER THE KEY NAME eg. firstname or email etc.--).getValue());   //gives the value for given keyname
                }
            }
        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

Hope it helps!

Solution 4 - Android

as Frank said Firebase stores sequence of values in the format of "key": "Value" which is a Map structure

to get List from this sequence you have to

  1. initialize GenericTypeIndicator with HashMap of String and your Object.
  2. get value of DataSnapShot as GenericTypeIndicator into Map.
  3. initialize ArrayList with HashMap values.

GenericTypeIndicator<HashMap<String, Object>> objectsGTypeInd = new GenericTypeIndicator<HashMap<String, Object>>() {};
Map<String, Object> objectHashMap = dataSnapShot.getValue(objectsGTypeInd);
ArrayList<Object> objectArrayList = new ArrayList<Object>(objectHashMap.values());

Works fine for me, Hope it helps.

Solution 5 - Android

I did something like this :

Firebase ref = new Firebase(FIREBASE_URL);
ref.addValueEventListener(new ValueEventListener() {
 
@Override
public void onDataChange(DataSnapshot snapshot) {
    Map<String, Object> objectMap = (HashMap<String, Object>)    
             dataSnapshot.getValue();
    List<Match> = new ArrayList<Match>();
    for (Object obj : objectMap.values()) {
        if (obj instanceof Map) {
            Map<String, Object> mapObj = (Map<String, Object>) obj;
            Match match = new Match();
            match.setSport((String) mapObj.get(Constants.SPORT));
            match.setPlayingWith((String) mapObj.get(Constants.PLAYER));
            list.add(match);
        }
    }
  }
  @Override
  public void onCancelled(FirebaseError firebaseError) {
      
  }
});

Solution 6 - Android

In my case only given solution worked fine.

Screenshot of Firebase ArrayList structure:

enter image description here

How to fetch whole list from Firebase from DataSnapshot.

GenericTypeIndicator<Map<String, List<Education>>> genericTypeIndicator = new GenericTypeIndicator<Map<String, List<Education>>>() {};
Map<String, List<Education>> hashMap = dataSnapshot.getValue(genericTypeIndicator);

for (Map.Entry<String,List<Education>> entry : hashMap.entrySet()) {
      List<Education> educations = entry.getValue();
        for (Education education: educations){
             Log.i(TAG, education.Degree);
         }
}

Education.java: (Model class).

public class Education implements Serializable{

    public String Degree;
    public String Result;
}

Hope this would works fine.

Solution 7 - Android

    @Override
       public void onDataChange(DataSnapshot dataSnapshot) {
           for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
               User user = postSnapshot.getValue(User.class);
               list.add(user);
           }
           for (int i=0;i<list.size();i++)
           {
               Log.e("Name",list.get(i).getname());
               Log.e("Phone",list.get(i).getphone());

           }
       }
       @Override
       public void onCancelled(FirebaseError firebaseError) {
       Log.e("error",firebaseError.getMessage());
       }
   });

Class model

class User{

String name;

String phone;

public String getname() {
    return name;
}

public void setname(String name) {
    this.name = name;
}


public String getphone() {
    return phone;
}

public void setphone(String phone) {
    this.phone = phone;
}
}

List binding

List<User> list= new ArrayList <>();

this work for you

Solution 8 - Android

If you use Kotlin, the next one is a good solution:

myRef.addListenerForSingleValueEvent(object : ValueEventListener {
  override fun onDataChange(dataSnapshot: DataSnapshot) {
      val list = dataSnapshot.children.map { it.getValue(YourClass::class.java)!! }
      Log.d("TAG", "Value is: $list")
}

Solution 9 - Android

Saving and Retriving data to - from Firebase ( deprecated ver 2.4.2 )

Firebase fb_parent = new Firebase("YOUR-FIREBASE-URL/");
Firebase fb_to_read = fb_parent.child("students/names");
Firebase fb_put_child = fb_to_read.push(); // REMEMBER THIS FOR PUSH METHOD

//INSERT DATA TO STUDENT - NAMES  I Use Push Method
fb_put_child.setValue("Zacharia"); //OR fb_put_child.setValue(YOUR MODEL) 
fb_put_child.setValue("Joseph"); //OR fb_put_child.setValue(YOUR MODEL) 
fb_put_child.setValue("bla blaaa"); //OR fb_put_child.setValue(YOUR MODEL) 

//GET DATA FROM FIREBASE INTO ARRAYLIST
fb_to_read.addValuesEventListener....{
    public void onDataChange(DataSnapshot result){
        List<String> lst = new ArrayList<String>(); // Result will be holded Here
        for(DataSnapshot dsp : result.getChildren()){
            lst.add(String.valueOf(dsp.getKey())); //add result into array list
        }
        //NOW YOU HAVE ARRAYLIST WHICH HOLD RESULTS
    



for(String data:lst){ 
         Toast.make(context,data,Toast.LONG_LENGTH).show; 
       }
    }
}

Solution 10 - Android

mDatabase.child("token").addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
              for (DataSnapshot snapshot:dataSnapshot.getChildren())
              {
                 String key= snapshot.getKey();
                 String value=snapshot.getValue().toString();
              }
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                Toast.makeText(ListUser.this,databaseError.toString(),Toast.LENGTH_SHORT).show();
            }
        });

Only work If child have no SubChild

enter image description here

Solution 11 - Android

Works Like a Charm

final DatabaseReference senderDb = FirebaseDatabase.getInstance().getReference(Constant.NODE_MESSAGE).child(myId + "_" + otherId);

    senderDb.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            Map<String, Object> td = (HashMap<String,Object>) dataSnapshot.getValue();

            for (DataSnapshot childDataSnapshot : dataSnapshot.getChildren()) {
                DatabaseReference objRef = senderDb.child( childDataSnapshot.getKey());
                Map<String,Object> taskMap = new HashMap<String,Object>();
                taskMap.put("is_read", "1");
                objRef.updateChildren(taskMap); //should I use setValue()...?
                Log.v("Testing",""+ childDataSnapshot.getKey()); //displays the key for the node
            }

            //notifyDataSetChanged();
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }

    });

Solution 12 - Android

You Need to write a custom Deserializer and then loop it and get the values of the hasmap.

Custom Deserializer:-

public class UserDetailsDeserializer implements JsonDeserializer<AllUserDetailsKeyModel> {
  /*
    bebebejunskjd:{
      "email": "[email protected]",
          "mobileNum": "12345678",
          "password": "1234567",
          "username": "akhil"}*/
  @Override public AllUserDetailsKeyModel deserialize(JsonElement json, Type typeOfT,
      JsonDeserializationContext context) throws JsonParseException {

    final JsonObject jsonObject = json.getAsJsonObject();

    Gson gson = new Gson();

    Type AllUserDetailsResponseModel =
        new TypeToken<HashMap<String, AllUserDetailsResponseModel>>(){}.getType();

    HashMap<String, AllUserDetailsResponseModel> user =
        gson.fromJson(jsonObject, AllUserDetailsResponseModel);
    AllUserDetailsKeyModel result = new AllUserDetailsKeyModel();
    result.setResult(user);
    return result;
  }


}

The code in comments is my object model and u should replaceAllUserDetailsKeyModel with your model class and add this to the rest client like below:-

private Converter.Factory createGsonConverter() {
    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.registerTypeAdapter(AllUserDetailsKeyModel.class, new UserDetailsDeserializer());
    Gson gson = gsonBuilder.create();
    return GsonConverterFactory.create(gson);
  }

This the custom Convertor for Retrofit.

In your onResponse you just loop with hasmaps and get value by key and my model class looks like below:-

public class AllUserDetailsKeyModel {

  private Map<String, AllUserDetailsResponseModel> result;

  public Map<String, AllUserDetailsResponseModel> getResult() {
    return result;
  }

  public void setResult(Map<String, AllUserDetailsResponseModel> result) {
    this.result = result;
  }

}

probably you need to give a Type T where T is your data Type and my model consists only of a hashmap and getters and setters for that.

And finally set Custom Convertor to retrofit like below:- .addConverterFactory(createGsonConverter())

Let me know if you need more clarifications.

Solution 13 - Android

Use GenericTypeIndicator to get List of Child Node from Firebase ArrayList structured DataBase

   //Start of Code
   Firebase ref = new Firebase(FIREBASE_URL);
   ref.addValueEventListener(new ValueEventListener(){
      @Override
      public void onDataChange(DataSnapshot snapshot){
         GenericTypeIndicator<List<YourClassName>> t = new GenericTypeIndicator<List<YourClassName>>{};
         List<YourClassName> messages = snapshot.getValue(t);
         Log.d("Get Data Size", messages.size());
          }
      }
      @Override
      public void onCancelled(FirebaseError firebaseError){
          Log.e("The read failed: ",firebaseError.getMessage());
      }
   });

Solution 14 - Android

your problem is why your code doesn't work.

this your code:

> Firebase ref = new Firebase(FIREBASE_URL); >
> ref.addValueEventListener(new ValueEventListener() { > @Override > public void onDataChange(DataSnapshot snapshot) { > Log.e("Count " ,""+snapshot.getChildrenCount()); > for (DataSnapshot postSnapshot: snapshot.getChildren()) { > post = postSnapshot.getValue(.class); > Log.e("Get Data", post.()); > } > } > @Override > public void onCancelled(FirebaseError firebaseError) { > Log.e("The read failed: " ,firebaseError.getMessage()); > } > })

you miss the simplest thing: getChildren()

FirebaseDatabase db = FirebaseDatabase.getInstance();
DatabaseReference reference = FirebaseAuth.getInstance().getReference("Donald Trump");

reference.addValueEventListener(new ValueEventListener() {
   @Override
   public void onDataChange(DataSnapshot dataSnapshot) {
            
            int count = (int) dataSnapshot.getChildrenCount(); // retrieve number of childrens under Donald Trump
            
            String[] hairColors = new String[count];

            index = 0;
            for (DataSnapshot datas : dataSnapshot.getChildren()){
                
                hairColors[index] = datas.getValue(String.class);
                
            }
            index ++
        
            for (int i = 0; i < count; i++)
            Toast(MainActivity.this, "hairColors : " + hairColors[i], toast.LENGTH_SHORT).show();
           
            }

    }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }

    });
       

Solution 15 - Android

ArrayList<String> keyList = new ArrayList<String>();
mKeyRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for (DataSnapshot childDataSnapshot : dataSnapshot.getChildren()) {
                String temp = childDataSnapshot.getKey();
                keyList.add(temp);
                i = keyList.size();

            }
        }
        @Override
        public void onCancelled(DatabaseError databaseError) {
            throw databaseError.toException();
        }
    });

This code is working fine to add all firebase key into arraylist, you can do it with firebase values, of other static values.

Solution 16 - Android

DatabaseReference mRootRef = FirebaseDatabase.getInstance().getReference();
        DatabaseReference mMainMenuRef = mRootRef.child("tut_master");//main
        DatabaseReference mSubMenuRef = mMainMenuRef.child("english");//sub
        List<Tutorial>   tutorialNames=new ArrayList<>();
        mSubMenuRef.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

                for(DataSnapshot ds : dataSnapshot.getChildren()) {
                    long id = ds.child("id").getValue(Long.class);
                    String name = ds.child("name").getValue(String.class);
                                 
                    Tutorial tut = new Tutorial();
                    tut.setTutId(id+"");
                    tut.setTutName(name);
                    tutList.add(tut);
                    
                }
                   
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }


        });

Solution 17 - Android

 private FirebaseDatabase firebaseDatabase=  FirebaseDatabase.getInstance();
    private DatabaseReference databaseReference=  firebaseDatabase.getReference();
    private DatabaseReference mChildReference= databaseReference.child("data");
   
  mChildReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                for(DataSnapshot ds : dataSnapshot.getChildren()) {
                    User commandObject = ds.getValue(User.class);
                    Log.d("TAG", commandObject.getMsg());
                }
                Toast.makeText(MainActivity.this,dataSnapshot.toString(),Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });

This will help you, you just have to create a model class containing String msg.

Solution 18 - Android

Use Gson is my favorite solution.

mFirebaseRef.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        Type StringListType = new TypeToken<List<String>>(){}.getType();
        List<String> td = new Gson().fromJson(dataSnapshot.getValue(), StringListType);
    }
});

if you think the code to get TypeToken is unintuitive. You can write a class to contain all types you need. So next time, you can get those types quickly.

class TypeTokens{
    static public final Type StringListType = new TypeToken<List<String>>(){}.getType();
    static public final Type StringMapType = new TypeToken<Map<String, String>>(){}.getType();
    static public final Type LongMapType = new TypeToken<Map<String, Long>>(){}.getType();
    static public final Type DateMapType = new TypeToken<Map<String, Date>>(){}.getType();
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionParth VyasView Question on Stackoverflow
Solution 1 - AndroidNilesh SentaView Answer on Stackoverflow
Solution 2 - AndroidFrank van PuffelenView Answer on Stackoverflow
Solution 3 - AndroidPramod GargView Answer on Stackoverflow
Solution 4 - AndroidMamdouh El NakeebView Answer on Stackoverflow
Solution 5 - AndroidruchitaView Answer on Stackoverflow
Solution 6 - AndroidHiren PatelView Answer on Stackoverflow
Solution 7 - AndroidRahul sharmaView Answer on Stackoverflow
Solution 8 - AndroidDavid MendañoView Answer on Stackoverflow
Solution 9 - Androidugali softView Answer on Stackoverflow
Solution 10 - Androiddsc clgView Answer on Stackoverflow
Solution 11 - AndroidArun PrajapatiView Answer on Stackoverflow
Solution 12 - Androidbv akhilView Answer on Stackoverflow
Solution 13 - AndroidThe Black HorseView Answer on Stackoverflow
Solution 14 - AndroidvaianaView Answer on Stackoverflow
Solution 15 - AndroidBHargav D PatelView Answer on Stackoverflow
Solution 16 - AndroidSreejesh K NairView Answer on Stackoverflow
Solution 17 - AndroidPrateek GuptaView Answer on Stackoverflow
Solution 18 - AndroidWu Yuan ChunView Answer on Stackoverflow