1

I am trying to read the data that i have in my cloud firestore and to put it in an array called "urlList". The arrayList is in the onComplete and if i log the array there, it works(it's filled with the data it's suppose to have). Whenever i log the arrayList outside the onComplete, the array is empty. The problem seems to be with the onCompletelistener but i can't find what is going wrong / how to avoid the problem. I added the log of the number 5 and 6 to check where the problem is, and the log in the onCreate does see the 5, but not the 6

 public static ArrayList<String> urlList = new ArrayList<String>();
 public static ArrayList<String> groupList = new ArrayList<String>();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_middel_scherm);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    ConstraintLayout layout = (ConstraintLayout) findViewById(R.id.imageLayout);
    setSupportActionBar(toolbar);
    db = FirebaseFirestore.getInstance();
    mAuth = FirebaseAuth.getInstance();
    CurrentUser = FirebaseAuth.getInstance().getCurrentUser().getUid();
    mAuthListener = new FirebaseAuth.AuthStateListener() {
        @Override
        public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
            if (firebaseAuth.getCurrentUser() == null) {
                startActivity(new Intent(MiddelScherm.this, LoginScherm.class));
            }
        }
    };
    ivImage = (ImageView) findViewById(R.id.ivImage);

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            SelectImage();

        }
    });

    databaseDownload();
    Log.d(TAG, "egregergegre");
    Log.d(TAG, String.valueOf(urlList));
    Log.d(TAG, "egregergegre");
    showEachImage(layout);
}

public void showEachImage(ConstraintLayout layout) {
    for (String element: urlList) {
        ImageView image = new ImageView(this);
        image.setLayoutParams(new android.view.ViewGroup.LayoutParams(80,60));
        image.setMaxHeight(20);
        image.setMaxWidth(20);
        Picasso.get().load(element).into(image);
        layout.addView(image);

    }
}

public void databaseDownload() {
    urlList.add("5");
    db.collection("user").document(CurrentUser).collection("meta-data")
            .get()
            .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                @Override
                public void onComplete(@NonNull Task<QuerySnapshot> task) {
                    if (task.isSuccessful()) {
                        urlList.add("6");
                        for (DocumentSnapshot document : task.getResult()) {
                            String imageValue = document.getString("URL");
                            urlList.add(imageValue);
                            Log.d(TAG, String.valueOf(urlList));
                        }
                    } else {
                        Log.w(TAG, "Error getting documents.", task.getException());
                    }
                }
            });

    db.collection("user").document(CurrentUser).collection("Group")
            .get()
            .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                @Override
                public void onComplete(@NonNull Task<QuerySnapshot> task) {
                    if (task.isSuccessful()) {
                        for (DocumentSnapshot document : task.getResult()) {
                            String groupValue = document.getString("Group");
                            groupList.add(groupValue);
                            Log.d(TAG, String.valueOf(groupList));
                        }
                    } else {
                        Log.w(TAG, "Error getting documents.", task.getException());
                    }
                }
            });
}

I even tried to put the public void showEachImage(ConstraintLayout layout) inside the onCompletelistener but it gave an error at "this" at the line of: ImageView image = new ImageView(this): So i gave up on this structure as well

    public void databaseDownload() {
urlList.add("5");
db.collection("user").document(CurrentUser).collection("meta-data")
        .get()
        .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
            @Override
            public void onComplete(@NonNull Task<QuerySnapshot> task) {
                if (task.isSuccessful()) {
                    urlList.add("6");
                    for (DocumentSnapshot document : task.getResult()) {
                        String imageValue = document.getString("URL");
                        ImageView image = new ImageView(this);
                        image.setLayoutParams(new 
                        android.view.ViewGroup.LayoutParams(80,60));
                        image.setMaxHeight(20);
                        image.setMaxWidth(20);
                        Picasso.get().load(imageValue).into(image);
                        layout.addView(image);
                        Log.d(TAG, String.valueOf(urlList));
                    }
                } else {
                    Log.w(TAG, "Error getting documents.", task.getException());
                }
            }
        });

db.collection("user").document(CurrentUser).collection("Group")
        .get()
        .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
            @Override
            public void onComplete(@NonNull Task<QuerySnapshot> task) {
                if (task.isSuccessful()) {
                    for (DocumentSnapshot document : task.getResult()) {
                        String groupValue = document.getString("Group");
                        groupList.add(groupValue);
                        Log.d(TAG, String.valueOf(groupList));
                    }
                } else {
                    Log.w(TAG, "Error getting documents.", task.getException());
                }
            }
        });

}

Eruditee
  • 11
  • 1

2 Answers2

1

The reason you're adding an OnCompleteListener is that get() starts an asynchronous Task, which will call the onComplete() method when the query is done.

The get() method returns immediately, which means the query isn't done yet, and hence the onCreate() method won't see any data.

Any code that needs the data should be execute in/from the onComplete() method.

Andreas
  • 154,647
  • 11
  • 152
  • 247
  • Thanks for answering! Would there be a way to avoid using the onCompletelistener? For instance, just leave it out. I have to use the data from both collections in the same class so that won't work due to the code not being in the oncomplete method – Eruditee Aug 28 '18 at 09:11
  • @Eruditee See [Firebase Android: How to read from different references sequentially](https://stackoverflow.com/q/37215071/5221149) – Andreas Aug 28 '18 at 15:52
0

I think crush with ImageView happens because "this" is OnCompleteListener class in onComplete method.

samaromku
  • 560
  • 2
  • 7