0

Im trying to display the scores of my users on a leaderboard using a listView. For some reason I can only the get the email and score of the first user to appear and Im not sure how to get the remaining users to appear on screen.

Perhaps they are not being added to the listview or maybe the loop is wrong?

package com.example.securityapp;

import androidx.appcompat.app.AppCompatActivity;

import android.nfc.Tag;
import android.os.Bundle;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;

import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;
import com.google.firebase.database.ValueEventListener;

import java.util.ArrayList;
import java.util.List;

import static java.lang.System.in;

public class leaderboard extends AppCompatActivity {

    DatabaseReference databaseUsers;
    FirebaseDatabase database = FirebaseDatabase.getInstance();
    FirebaseAuth mAuth;
    private static final String TAG = "leaderboard";
    String s;
    ListView listView;
    ArrayList list;
    ArrayAdapter<String> arrayAdapter;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_leaderboard);

        mAuth = FirebaseAuth.getInstance();
        FirebaseUser user = mAuth.getCurrentUser();
        listView = (ListView) findViewById(R.id.list);
        list = new ArrayList<String>();
        arrayAdapter = new ArrayAdapter<>(getApplicationContext(), android.R.layout., list);



        leaderBoard();




    }

    public void leaderBoard(){
        database.getReference().child("Scores").addValueEventListener(new ValueEventListener() {
            public void onDataChange(DataSnapshot dataSnapshot) {
                for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                    System.out.println("The score is: " + snapshot.child("Points").getValue());
                    s = s + snapshot.child("Username").getValue() + "         " + snapshot.child("Points").getValue() + "\n";
                    list.add(s);
                    listView.setAdapter(arrayAdapter);
                    arrayAdapter.notifyDataSetChanged();

                }

            }


            @Override
            public void onCancelled(DatabaseError databaseError) {
                // Getting Post failed, log a message
                Log.w(TAG, "loadPost:onCancelled", databaseError.toException());

            }


        });

    }


}

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        tools:context=".leaderboard">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="0.38">

            <TextView
                android:layout_width="420dp"
                android:layout_height="150dp"
                android:gravity="center"
                android:text="Leaderboard!"
                android:textAppearance="@style/TextAppearance.AppCompat.Body1"
                android:textColor="#0C40F1"
                android:textSize="50dp"
                android:textStyle="bold">

            </TextView>
        </RelativeLayout>

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="0.38">
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:layout_weight="1"
                android:weightSum="2">

                <TextView
                    android:layout_height="wrap_content"
                    android:layout_width="wrap_content"
                    android:text="Points"
                    android:layout_gravity="left"
                    android:textSize="20dp"
                    />

            </LinearLayout>

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="right"
                android:text="User"
                android:textSize="20dp">

            </TextView>
        </RelativeLayout>
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="0.38">

            <ListView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/list">

            </ListView>


        </RelativeLayout>


    </LinearLayout>



</ScrollView>

1 Answers1

0

You are setting adapter in a for loop

replace

for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                    System.out.println("The score is: " + snapshot.child("Points").getValue());
                    s = snapshot.child("Username").getValue() + "         " + snapshot.child("Points").getValue() + "\n";
                    list.add(s);
                    listView.setAdapter(arrayAdapter);
                    arrayAdapter.notifyDataSetChanged();

                }

with

if(dataSnapshot.exist()){
     list = new ArrayList<String>();
     for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                        System.out.println("The score is: " + snapshot.child("Points").getValue());
                       String s =  snapshot.child("Username").getValue() + "         " + snapshot.child("Points").getValue() + "\n";
                        list.add(s); 
                    }
    arrayAdapter = new ArrayAdapter<>(getApplicationContext(), android.R.layout., list);
    listView.setAdapter(arrayAdapter);

    }

As you are calling an addvalue event listener, which listen for live changes, you have to initialize your list when there is a change in data and declare "s" in loop.

Haider Saleem
  • 773
  • 1
  • 9
  • 17
  • So that works in that all users are displayed, but every iteration of the loop shows i.e the first list item is user1. The next list item is User1, User2. The next is User1, User2, User3 and so on. Is there a way to just get the last iteration of the list rather than display all? – Chloe Hamilton Mar 01 '20 at 20:17
  • yeah you can use database.getReference().child("Scores").orderByKey().limitToLast(1).ad... and dont forget to mark accepted – Haider Saleem Mar 01 '20 at 20:19
  • Hey, that only seems to show the last value of the list. What I meant was each time an item is added, the whole list is printed. I've edited the question to show what Im seeing :) Ignore the null values, there is a user with no email. – Chloe Hamilton Mar 01 '20 at 20:25
  • i have updated the answer, just remove arrayAdapter.notifyDataSetChanged(); – Haider Saleem Mar 01 '20 at 20:33
  • Unfortunately, when I remove that, I am still getting the same problem – Chloe Hamilton Mar 01 '20 at 20:43
  • i have updated, i hope it'll help better and sorry i forgot that you using addvalue event listener. – Haider Saleem Mar 01 '20 at 20:48
  • I am still getting each iteration of the loop printed :( Im not sure if maybe my loop is wrong as it seems the array is being added as a list item to my list each time – Chloe Hamilton Mar 01 '20 at 20:56
  • That "s". just declare it within the loop and remove s+. updated the answer too. – Haider Saleem Mar 01 '20 at 20:58
  • It wont run as it says variable s may not have been initialized – Chloe Hamilton Mar 01 '20 at 21:02
  • follow the code, i have updated in answer remove that s+. – Haider Saleem Mar 01 '20 at 21:03
  • Ah I see now! Thank you so much for helping with this. Can I ask one more question. I am currently showing the users' email addresses but instead want to show their usernames. I have asked the question here --> https://stackoverflow.com/questions/60289428/how-to-use-snapshot-result-in-a-firebase-transaction I can get the username but cannot put it in the right place? – Chloe Hamilton Mar 01 '20 at 21:10