如何从Firebase读取所有数据到列表视图

时间:2019-04-18 18:36:45

标签: android firebase firebase-realtime-database

我正在尝试将所有存储的数据从Firebase读取到列表视图中。首先,我无法弄清楚如何引用通过push()创建的自动生成的键;这意味着我无法使用getter和setter,因为它始终是唯一的。对于如何遍历所有歌曲,我也可以提供一些帮助。 任何帮助表示赞赏。

我的getter和setter类获取所需的字段,但无法获取密钥。

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 个答案:

答案 0 :(得分: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);
        }

答案 1 :(得分:1)

就像弗兰克的答案一样,您在POJO中也可以有一个String歌曲ID,并且当您使用getKey()检索每个键时,可以将该键存储到数组中,因此,当您为每一行的视图充气时,您可以单击它们,并为列表中的每首歌曲分配唯一的键。

示例(从弗兰克的答案中,您可以获得密钥)

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

以此,您可以为列表中的每首歌曲分配其唯一ID,因此,每当在列表中单击它们时,您都可以访问其特定ID来检索所需的数据。

编辑

我认为该列表没有显示任何内容,因为在初始化ArrayAdapter时,您没有传递获取的数据,请看一下this构造函数

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类型,并将适配器更改为自定义适配器,但就目前而言,我认为它应该可以正常工作。