1

I'm using firebase firestore for saving data. I want to retrieve the city of user and according to it, retrieve specific data from firestore and set the RecyclerView. The problem is: when I make a query I can't take the variable (city) outside the OnCompleteListener. In the code below (userCity) in (setUpRecyclerView()) is "" and also any where outside OnCompleteListener. What can I do?? Here is my code:

   public class chosenSubject extends AppCompatActivity {
    private FirebaseAuth mAuth=FirebaseAuth.getInstance();
    private FirebaseUser currentUser= mAuth.getCurrentUser();
    private FirebaseFirestore db = FirebaseFirestore.getInstance();
    private TextView tv;
    private String UserId =currentUser.getUid();

    private TeacherAdapter teacherAdapter;

    private static String userCity="";
    private static String city;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chosen_subject);
        tv=findViewById(R.id.tv);

        db.collectionGroup("Id").whereEqualTo("id" , UserId).get()
                .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                    @Override
                    public void onComplete(@NonNull Task<QuerySnapshot> task) {
                        if (task.isSuccessful()){
                            for (QueryDocumentSnapshot document : task.getResult()){
                                city = document.getString("city");
                            }
                        }
                        userCity = city;
                    }

                });
        setUpRecyclerView();

    }// end of onCreate


    private void setUpRecyclerView(){

        Query query =   db.collection("Users").document("Teachers").collection("Id")
                .whereEqualTo("city" , userCity);

        FirestoreRecyclerOptions < TeacherOfSubject > options = new FirestoreRecyclerOptions.Builder<TeacherOfSubject>()
                .setQuery(query, TeacherOfSubject.class)
                .build();

        teacherAdapter = new TeacherAdapter(options);

        RecyclerView recyclerView = findViewById(R.id.recycler_view);
        recyclerView.setHasFixedSize(true);    //for performane reasons
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setAdapter(teacherAdapter);
    }

    @Override
    protected void onStart() {
        super.onStart();
        teacherAdapter.startListening();
    }

    @Override
    protected void onStop() {
        super.onStop();
        teacherAdapter.stopListening();
    }
}// end of class
Mahmoud Abu Alheja
  • 3,343
  • 2
  • 24
  • 41
Salma Eng
  • 49
  • 1
  • 9

2 Answers2

1

Instead of calling setUpRecyclerView after your onCompleteListener, call it inside your onCompleteListener like so:

db.collectionGroup("Id").whereEqualTo("id" , UserId).get()
        .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
            @Override
            public void onComplete(@NonNull Task<QuerySnapshot> task) {
                if (task.isSuccessful()){
                    for (QueryDocumentSnapshot document : task.getResult()){
                        city = document.getString("city");
                    }
                }
                userCity = city;
                setUpRecyclerView()
            }

        });

Also if your operations are taking some time, consider adding a ProgressDialog beforehand and dismiss it after the database has run its query.

private ProgressDialog progress;
private void showProgress(String message) {
    progress = new ProgressDialog(this);
    progress.setMessage(message);
    progress.setIndeterminate(true);
    progress.show();
}

private void hideProgress() {
    if (progress != null) {
        progress.dismiss();
    }
}

EDIT:

private void setUpRecyclerView(){

    Query query =   db.collection("Users").document("Teachers").collection("Id")
            .whereEqualTo("city" , userCity);

    FirestoreRecyclerOptions < TeacherOfSubject > options = new FirestoreRecyclerOptions.Builder<TeacherOfSubject>()
            .setQuery(query, TeacherOfSubject.class)
            .build();

    teacherAdapter = new TeacherAdapter(options);

    RecyclerView recyclerView = findViewById(R.id.recycler_view);
    recyclerView.setHasFixedSize(true);    //for performane reasons
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    recyclerView.setAdapter(teacherAdapter);
    teacherAdapter.startListening();

}

@Override
protected void onStart() {
    super.onStart();
}
KoalaKoalified
  • 687
  • 4
  • 15
0

Just pass you var to setUpRecyclerView method when data is ready

db.collectionGroup("Id").whereEqualTo("id" , UserId).get()
                .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                    @Override
                    public void onComplete(@NonNull Task<QuerySnapshot> task) {
                        if (task.isSuccessful()){
                            for (QueryDocumentSnapshot document : task.getResult()){
                                city = document.getString("city");
                            }
                        }
                        setUpRecyclerView(city);
                    }

                });

And You method will be like this

private void setUpRecyclerView(String city){

        Query query =   db.collection("Users").document("Teachers").collection("Id")
                .whereEqualTo("city" , city);

        FirestoreRecyclerOptions < TeacherOfSubject > options = new FirestoreRecyclerOptions.Builder<TeacherOfSubject>()
                .setQuery(query, TeacherOfSubject.class)
                .build();

        teacherAdapter = new TeacherAdapter(options);

        RecyclerView recyclerView = findViewById(R.id.recycler_view);
        recyclerView.setHasFixedSize(true);    //for performane reasons
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setAdapter(teacherAdapter);
    }
Mahmoud Abu Alheja
  • 3,343
  • 2
  • 24
  • 41
  • This was not working for me because as KoalaKoalified said teacherAdapter isn't instantiated before onStart is called. It's working now, Thank you Mahmoud.. – Salma Eng Oct 28 '19 at 20:12