0

I am making an android app, in one activity there are the following two functions.

public void display(RequestData rd[],int j)
    {
        Toast.makeText(Student_see_request_status.this,j+" h"+r[0]+"",Toast.LENGTH_SHORT).show();
        //using current value of j
}
public void set()
    {
        FirebaseFirestore fs=FirebaseFirestore.getInstance();
        DocumentReference doc=fs.collection("Request").document(FirebaseAuth.getInstance().getCurrentUser().getEmail());
        doc.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
            @Override
            public void onSuccess(DocumentSnapshot documentSnapshot) {
                Map<String, Object> m = documentSnapshot.getData();
                r[0] = (long) m.get("Request Number");
                if(r[0]==0)
                {
                    Toast.makeText(Student_see_request_status.this,"NO REQUESTS HERE",Toast.LENGTH_SHORT).show();
                    return;
                }
                rd=new RequestData[(int)r[0]+2];
                for(int j[]={1};j[0]<=r[0];j[0]++)
                {
                    doc.collection("Request " + j[0]).document("Request").get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
                        @Override
                        public void onSuccess(DocumentSnapshot documentSnapshot) {
                            Map<String, Object> details = documentSnapshot.getData();
                          
                            rd[j[0]]=new RequestData();
                            rd[j[0]].setHeader("Change " + details.get("Change what") + " to " + details.get("Value"));
                            rd[j[0]].setReason((String) details.get("Reason"));
                            display(rd,j[0]);
                         }
                     });
                }
            }
         });
     }
                                
                            

Here rd and r are global variables. The code does not run properly with for loop. First, the loop in set() method gets completed and then the control moves to display() with j=r[0]. I need every value of j to reach display() Can anyone please help me with this?

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Vanshika
  • 1
  • 6
  • There is no way to make asynchronous code behave synchronously in Android/Java. Any code that needs the data from the database will need to be inside your `onSuccess` method or be called from there. For more on this, also see https://stackoverflow.com/a/51002413, https://stackoverflow.com/questions/50434836/getcontactsfromfirebase-method-return-an-empty-list/50435519#50435519, and https://stackoverflow.com/questions/33203379/setting-singleton-property-value-in-firebase-listener. – Frank van Puffelen Nov 24 '21 at 20:18
  • @FrankvanPuffelen I have called the function display() from onSuccess() still, the control goes to the display method only after the for loop is completed. Should I write the entire code of display() inside onSuccess? – Vanshika Nov 24 '21 at 21:53
  • From a quick look at the code, it looks like `display` should be called after each document that has successfully been loaded. Is that not happening for you? – Frank van Puffelen Nov 24 '21 at 21:59
  • 1
    No, for the value of r[0]=4, the loop runs 4 times... with j=1,2,3,4 and then the display method is called 4 times with its parameter j =4 all the times. – Vanshika Nov 24 '21 at 22:20
  • There is no way you can do that. Firebase API is asynchronous. So please check the duplicate to see how can you solve this using a callback. You might also be interested in reading this article, [How to read data from Cloud Firestore using get()?](https://medium.com/firebase-tips-tricks/how-to-read-data-from-cloud-firestore-using-get-bf03b6ee4953). – Alex Mamo Nov 25 '21 at 07:50
  • @AlexMamo Is there any alternative to Firebase that can be used in such a situation? – Vanshika Nov 25 '21 at 10:00
  • The initial response for all developers is to try and "fix" this asynchronous behavior, which I personally recommend against this. All modern APIs behave like that, and as soon as you accept that, you'll learn how to become productive with modern APIs. – Alex Mamo Nov 25 '21 at 10:45
  • @AlexMamo if there is no alternate, how will all the values of 'j' (1,2,3....) reach display() method? Is there any way to make the main thread wait for completion because otherwise the loop completes first entirely and display() is called afterwards, passing the same last value of j every time? – Vanshika Nov 25 '21 at 21:47
  • Have you tried to read the [article](https://medium.com/firebase-tips-tricks/how-to-read-data-from-cloud-firestore-using-get-bf03b6ee4953) or the duplicate answer? Both can help you solve that, – Alex Mamo Nov 26 '21 at 07:03

0 Answers0