1

enter image description here

I just wrote a basic code to get multiple documents from Firestore database. The task is getting successful and you could see the document.getId() & document.getData() value in Log, but after that when I use document.getString(), it gives a blank output. I have been trying to find my error but I am unable to and I have a project submission due tomorrow. Ignore all the textview declaration in the given code below:

    private FirebaseFirestore db;
private int month,year;
private Calendar calendar;
private  String email;
private String name,points;
private int i,j;
private String q,p,r;
public String[][] data= new String[10][10];
private TextView rankingTextView,a,b;
public TextView t01,t02,t03,t10,t11,t12,t20,t21,t22,t30,t31,t32,t40,t41,t42,t50,t51,t52,t60,t61,t62,t70,t71,t72,t80,t81,t82,t90,t91,t92;

private static final String TAG = "MyApp";
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_leaderboard);
    calendar=Calendar.getInstance();
    t01=(TextView)findViewById(R.id.t00);
    t02=(TextView)findViewById(R.id.t01);
    t03=(TextView)findViewById(R.id.t02);
    t10=(TextView)findViewById(R.id.t10);
    t11=(TextView)findViewById(R.id.t11);
    t12=(TextView)findViewById(R.id.t12);
    t20=(TextView)findViewById(R.id.t20);
    t21=(TextView)findViewById(R.id.t21);
    t22=(TextView)findViewById(R.id.t22);
    t30=(TextView)findViewById(R.id.t30);
    t31=(TextView)findViewById(R.id.t31);
    t32=(TextView)findViewById(R.id.t32);
    t40=(TextView)findViewById(R.id.t40);
    t41=(TextView)findViewById(R.id.t41);
    t42=(TextView)findViewById(R.id.t42);
    t50=(TextView)findViewById(R.id.t50);
    t51=(TextView)findViewById(R.id.t51);
    t52=(TextView)findViewById(R.id.t52);
    t60=(TextView)findViewById(R.id.t60);
    t61=(TextView)findViewById(R.id.t61);
    t62=(TextView)findViewById(R.id.t62);
    t70=(TextView)findViewById(R.id.t70);
    t71=(TextView)findViewById(R.id.t71);
    t72=(TextView)findViewById(R.id.t72);
    t80=(TextView)findViewById(R.id.t80);
    t81=(TextView)findViewById(R.id.t81);
    t82=(TextView)findViewById(R.id.t82);
    db= FirebaseFirestore.getInstance();
    email = getIntent().getStringExtra("email");
    month = calendar.get(Calendar.MONTH);
    month = month + 1;
    year = calendar.get(Calendar.YEAR);
    i=0;
    j=0;
    dothis();
    Toast.makeText(this, "MO", Toast.LENGTH_SHORT).show();
    t01.setText(data[0][0]);
    t02.setText(data[0][1]);
    t11.setText(data[1][0]);
    t12.setText(data[1][1]);
    t21.setText(data[2][0]);
    t22.setText(data[2][1]);
    t31.setText(data[3][0]);
    t32.setText(data[3][1]);
    t41.setText(data[4][0]);
    t42.setText(data[4][1]);
    t51.setText(data[5][0]);
    t52.setText(data[5][1]);
    }
private void dothis()
{i=0;
j=0;

    db.collection("users")
           // .whereGreaterThanOrEqualTo("points" + Integer.toString(month) + Integer.toString(year), "0")
            .orderBy("points" + Integer.toString(month) + Integer.toString(year)).limit(10)
            .get()
            .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                @Override
                public void onComplete(@NonNull Task<QuerySnapshot> task) {
                    if (task.isSuccessful()) {
                        for (QueryDocumentSnapshot document : task.getResult()) {
                            if(document.exists()) {
                                Log.d(TAG, document.getId() + " => " + document.getData() + " ");
                                data[i][j] = document.getString("username");
                                data[i][j + 1] = document.getString("points" + Integer.toString(month) + Integer.toString(year));
                                i++;
                                Toast.makeText(Leaderboard.this, "OK", Toast.LENGTH_SHORT).show();
                            }
                        }
                    } else {
                        Log.d(TAG, "Error getting documents: ", task.getException());
                    }
                }
            });

}

}

Please don't duplicate my question. I searched a lot before putting.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193

1 Answers1

1

According to your comment, you say that when are you calling the following line of code:

t01.setText(data[0][0]);

Nothing is set to your t01 TextView and this is the normal behaviour since the data that is coming from the Firebase database is asynchronous. This means that the onComplete() method returns immediately after it's invoked, and the callback from the Task it returns, will be called some time later.

There are no guarantees about how long it will take. So it may take from a few hundred milliseconds to a few seconds before that data is available. Because this method returns immediately, the value of your data[0][0] variable you're trying to use outside the onComplete() method, will not have been populated from the callback yet.

Basically, you're trying to use a value synchronously from an API that's asynchronous. That's not a good idea. You should handle the APIs asynchronously as intended.

A quick solve for this problem would be set all those texts to your TextViews only inside the onComplete() method. If you need to set them outside, I recommend dive into the asynchronous worlds and see the last part of my anwser from this post in which I have explained how it can be done using a custom callback. You can also take a look at this video for a better understanding.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193