Как прочитать все данные из Firebase в listview

#android #firebase #firebase-realtime-database

# #Android #firebase #firebase-база данных в реальном времени

Вопрос:

Я пытаюсь прочитать все мои сохраненные данные из firebase в виде списка. Во-первых, я не могу понять, как ссылаться на автоматически сгенерированный ключ, который создается с помощью push(); это означает, что я не могу использовать getter amp; setter, поскольку он всегда уникален. Мне также не помешала бы некоторая помощь в том, как перебирать все песни. Любая помощь приветствуется.

мой класс getter и setter получает необходимые поля, но не может получить ключ.

Структура Firebase

 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);
    }
}
 

Ответ №1:

Чтобы получить ключ DataSnapshot вызова getKey() на этом снимке. Итак:

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

Обратите внимание, что эта строка не делает ничего полезного:

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

Вы, вероятно, ищете это:

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

    ...

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

            showData(dataSnapshot);
        }
 

Ответ №2:

Как и в ответе Фрэнка, у вас также может быть идентификатор строковой песни в вашем POJO, и когда вы извлекаете каждый ключ с getKey() помощью, вы можете сохранить этот ключ в массиве, поэтому, когда вы раздуваете представления каждой строки, вы можете щелкнуть их, и у них будет уникальный ключ, назначенный каждой песне на вашем POJO.список.

Пример (из ответа Фрэнка вы получаете ключ)

 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
 

С помощью этого вы можете назначить каждой песне в списке свой уникальный идентификатор, поэтому всякий раз, когда вы нажимаете на них в своем списке, вы можете получить доступ к их конкретному идентификатору для получения необходимых вам данных.

Редактировать

Я думаю, что список ничего не показывает, потому что при инициализации ArrayAdapter вы не передаете данные, полученные в него, взгляните на этот конструктор

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

И взгляните на свой

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

Вам не хватает данных для адаптера, измените их на это

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

Поскольку он находится внутри цикла for, вы увидите, что элементы заполняются один за другим; если вы хотите просто собрать все элементы вместе одновременно, переместите эти две строки за пределы цикла for

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

Кроме того, что-то очень важное — не создавать новый массив каждый раз, когда вы выполняете цикл внутри своих данных, вам нужно создавать новые объекты, которые будут в массиве, но нет необходимости создавать новый массив каждый раз, когда ваш цикл получает объект.

Поэтому переместите объявление ArrayList за пределы цикла for

 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);
 

Кроме того, массив должен иметь тип Songs и изменить адаптер на пользовательский, но пока, я думаю, он должен работать нормально.

Комментарии:

1. я обновил код, добавив это, но, похоже, он выводит «Исполнители», «Общедоступные пользователи» и «Песни» в качестве ключа в logcat

2. Это потому, что вам нужно пойти на один уровень глубже с вашей ссылкой, посмотрите на ответ Фрэнка

3. спасибо, что сработало и печатает ключ, однако, похоже, он не заполняет listview какими-либо данными

4. поместите точку останова в свои данные arraylist и посмотрите, что внутри, как только он закончит извлекать данные из Firebase, если у вас есть все данные внутри этого массива, тогда он должен работать

5. Я думаю, я знаю, почему ничего не отображается, позвольте мне отредактировать мой ответ