1

I'm developing an Android app and I need to make a complex query on my Firestore database and create a FirestoreRecyclerAdapter. To create the adpater I need a FirestoreRecyclerOptions object that take in input the whole query. Reading the documentation, I can't use in my query the methods whereGreaterThan, whereLessThan, oderBy, etc, on different parameters. For example, how can I get users from db who have age greater than/less than AND who have weight greater than/less than?

For example the document's structure in my firestore database is:

Users --->UserID--->userName(String)
            --->userAge(number)
            --->userHeight(number)
            --->userWeight(number)

FirebaseFirestore db;

db = FirebaseFirestore.getInstance();

RecyclerView recyclerView;

recyclerView = (RecyclerView)findViewById(R.id.recyclerViewID);
.
.
.

Query query = db.collection("Users").//the complex query that i need

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

adapter = new UsersAdapter(options, this);//get in input options and the context

recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);

Edit: A possible solution in my last comment to answer 1

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
Luca94
  • 25
  • 5

1 Answers1

1

There are some query limitations when it comes to Firestore:

Query limitations

Cloud Firestore does not support the following types of queries:

  • Queries with range filters on different fields, as described in the previous section.

So you cannot query your database on range filters using whereGreaterThan() and whereLessThan() methods on different properties and pass it to an adapter.

Edit:

A possible solution for this issue would be to filter your records client side twice. First query the database using the first property and second using the second property. Unfortunately you cannot achieve this in a single go.

Edit2:

The solution would be to query the database using the first query, get the corresponding elements, query the database again using the second query and get the corresponding elements and then merge the results client side. Now the elements from the database were filtered twice. Pass a list of that elements to an adapter and that's it. Note, when using this solution you cannot use the Firebase-UI library anymore but this how you can get your items filtered twice.

Community
  • 1
  • 1
Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • I’m already aware of these limitations(i menzioned them in the question). Is there an alternative way to make the query that i need? – Luca94 Feb 15 '19 at 11:12
  • It can be a solution but the firestoreRecyclerOptions object takes a single object query as input – Luca94 Feb 15 '19 at 11:25
  • Yes, you're right but you pass to the adapter the second query which returns the data that was filtered twice, right? – Alex Mamo Feb 15 '19 at 11:28
  • Do you mean something like this? Query q = db.collection(“Users”).whereGreaterThan(userWeight, 75); Query x = q.whereLessThan(userAge, 15); Than the fisrestoreRefyclerOptions input will be the query object x – Luca94 Feb 15 '19 at 11:41
  • I’m sorry but i must use firebase-UI library – Luca94 Feb 15 '19 at 12:44
  • Unfortunately there is no way to achieve that. You cannot chain whereGreaterThan() and whereLessThan() on different properties. – Alex Mamo Feb 15 '19 at 12:50
  • I found a solution! I see your answer to another question https://stackoverflow.com/questions/50650224/wait-until-firestore-data-is-retrieved-to-launch-an-activity: i create a simple adapter for a recycler view ( no firebase-ui library), so i make a simple query (whereGreaterThan/whereLessThan) and on onCompleteListener method i perform the query. Then i implement a callback interface to make a list of user synchronously. Tanks a lot!!! – Luca94 Feb 15 '19 at 17:01