I am trying to read all of my stored data in from firebase into a list view. Firstly I cannot figure out how to reference the auto-generated key that is created off push(); which means I am not able to use a getter & setter as it is always unique. I could also do with some help with how to iterate through all of the songs. Any help is appreciated.

my getter and setter class gets the fields needed but unable to get the key.

Firebase Structure

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_added_songs);

        firebaseAuth = FirebaseAuth.getInstance();


        listView = (ListView)findViewById(R.id.songsListView);
        databaseReference = FirebaseDatabase.getInstance().getReference();
        databaseReference.child("Songs").child("Added Songs").push().getKey();

        authStateListener = new FirebaseAuth.AuthStateListener() {
            @Override
            public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
                FirebaseUser user = firebaseAuth.getCurrentUser();
                if (user != null) {
                    // User is signed in
                    Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid());
                } else {
                    // User is signed out
                    Log.d(TAG, "onAuthStateChanged:signed_out");
                }

            }
        };

        databaseReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

                showData(dataSnapshot);
            }

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

            }
        });

    }

   private void showData(DataSnapshot dataSnapshot){
    for (DataSnapshot ds : dataSnapshot.getChildren()){
        System.out.println(ds.getKey());
        Songs songs = new Songs();
        songs.setSongId(ds.getKey()); // --> Set the song ID that is requested
        songs.setArtist_name(ds.getValue(Songs.class).getArtist_name());
        songs.setGenre(ds.getValue(Songs.class).getGenre());
        songs.setLocation(ds.getValue(Songs.class).getLocation());
        songs.setSong_link(ds.getValue(Songs.class).getSong_link());
        songs.setSong_name(ds.getValue(Songs.class).getSong_name());

        ArrayList<String> array = new ArrayList<>();
        array.add(songs.getArtist_name());
        array.add(songs.getGenre());
        array.add(songs.getLocation());
        array.add(songs.getSong_link());
        array.add(songs.getSong_name());
        array.add(songs.getSongId()); // --> Set the ID to the song
        ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_dropdown_item_1line);
        listView.setAdapter(adapter);
    }
}

2 Answers

1
Frank van Puffelen On

To get the key of a DataSnapshot call getKey() on that snapshot. So:

private void showData(DataSnapshot dataSnapshot){
    for (DataSnapshot ds : dataSnapshot.getChildren()){
        System.out.println(ds.getKey());

Note that this line doesn't do anything useful:

databaseReference.child("Songs").child("Added Songs").push().getKey();

You're probably looking for this:

    databaseReference = FirebaseDatabase.getInstance().getReference();
    databaseReference = databaseReference.child("Songs").child("Added Songs");

    ...

    databaseReference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

            showData(dataSnapshot);
        }
1
Gastón Saillén On

Like Frank's answer, you can also have a String song id in your POJO, and when you retrieve each key with getKey() you can store that key into the array, so, when you inflate the views of each row, you can click them and they will have the unique key assigned to each song on the list.

Example (From Frank's answer, you get the key)

private void showData(DataSnapshot dataSnapshot){
    for (DataSnapshot ds : dataSnapshot.getChildren()){
        System.out.println(ds.getKey());
        Songs songs = new Songs();
        songs.setSongId(ds.getKey()); // --> Set the song ID that is requested
        ArrayList<String> array = new ArrayList<>();
        array.add(songs.getSongId()); // --> Set the ID to the song

With this, you can assign to each song in the list their unique ID, so whenever you click them in your list, you can access to their specific ID to retrieve the data you need.

Edit

I think that the list is not showing nothing because when you initialize your ArrayAdapter you are not passing the data fetched to it, take a look at this constructor

ArrayAdapter(Context context, int resource, List<T> objects)

And take a look at yours

ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_dropdown_item_1line);

You are missing the data for the adapter, change it to this

ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_dropdown_item_1line,array);

Since it's inside the for loop, you will see the items being populated one by one; if you want to just pop all the items together at the same time, move this two lines outside your for loop

for (DataSnapshot ds : dataSnapshot.getChildren()){
//...
}
ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_dropdown_item_1line,array);
listView.setAdapter(adapter);

Also, something very important is to not create a new array each time you loop inside your data, you need to create new objects that will be in the array, but there is no need to create a new array each time your loop to get an object.

So move your ArrayList declaration outside your for loop

ArrayList<String> array = new ArrayList<>();
for (DataSnapshot ds : dataSnapshot.getChildren()){
    //...
    }
    ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_dropdown_item_1line,array);
    listView.setAdapter(adapter);

Also, the array should be of type Songs and change the adapter to a custom one, but for now, I think it should work fine.