Android Firestore compound query - java

I am developing a car rental android application in Android Studio. I am working on a "Filter" option, so the users can filter available cars (for example they can choose to see only diesel cars with 5 seats or they can choose to see only all-wheel-drive cars, etc.). I have an activity called FilterCars where the user for example can filter by 4 components: fuel, traction, seats, gearbox. After they submit the filter, the cars are shown based on their preference. I pass those filters to Cars activity(where the cars are shown in a RecyclerView) with bundle extras with success, so I have in Cars.java stored with success user's filter in variables "fuelType, tractionType, seatsType, gearboxType".
With those filters I can pass to the recyclerview adapter a query like:
FirebaseFirestore.getInstance().collection("Cars").whereEqualTo("fuel", fuelType).whereEqualTo("traction", tractionType).whereEqualTo("seats", seatsType).whereEqualTo("gearbox", gearboxType)
which is working just fine.
My problem is the following: I don't want to force the users to complete all the filter fields, so for example, if they want to filter only by fuel and seats, they can do it. How can I make a compound query which only contains the filters chosen by the user? One way I thought about it but I can't resolve it is if, for example, the user doesn't want to filter by traction, to store in tractionType something like " " (empty), and in the compound query instead of tractionType query "whereEqualTo" to put something which returns all the cars, so the compound query will filter only by the chosen filters.
Any suggestion on how to do it? Or is there a better way in which I can avoid putting the empty answers in the compound query?
Thank you!

The following query:
FirebaseFirestore.getInstance().collection("Cars")
.whereEqualTo("fuel", fuelType)
.whereEqualTo("traction", tractionType)
.whereEqualTo("seats", seatsType)
.whereEqualTo("gearbox", gearboxType);
Will filter your collection "Cars" by the value of four properties.
I don't want to force the users to complete all the filter fields, so for example if they want to filter only by fuel and seats
There are two ways in which you can solve this issue. Taking as an example, the above query, you can remove the calls to ".whereEqualTo("traction", tractionType)" and ".whereEqualTo("gearbox", gearboxType)" and you'll have the desired result. Or, you can do as following, as it makes more sense in my opinion.
When the user opens the app for the first time, simply display all available cars that exist within your "Cars" collection:
Query query = FirebaseFirestore.getInstance().collection("Cars")
If there are too many, add a limit() call, or implement pagination. Then simply add the possibility to select the car filters. For example, add 4 check-boxes for each filtering option. Once an option is selected, add it to your Query object like so:
query = query.whereEqualTo("fuel", fuelType)
If the user selects all options, then the query will look like the first one.
Please also remember, that Firestore queries are immutable. For more info, please check my answer from the following post:
FireStore date query not working as expected
If are using for example Firebase-UI library for Android, don't forget to start/stop listening after you set a new Query. If you aren't using the library, don't forget to notify the adapter about the changes.

Related

How do I get a list of every category inside a table of books?

I have a "Books" table that looks like this:
I'm trying to make a Spring Boot app where all these books are listed, but you can filter them by category. For this, I want to show a list of every category there is so the user can click on the one they want.
What would be the better way to get this list of categories? For example, in the case of the picture above, I would like to show a list like this:
XXX (only once)
YYY
ZZZ
You can check the
#Query annotation as #lemon provided the solution
#Query("SELECT DISTINCT category FROM Books")
List<String> categories();
Also you can check this

Firestore order a collection based on likes

Is it possible to order my ListView of posts based on the likes (the most liked post must be displayed above)?
I already know how I can order it based on timestamp. But as you can see the likes is a collection in Posts.
Timestamp code:
Query firstQuery = firebaseFirestore.collection("Posts").orderBy("timestamp", Query.Direction.DESCENDING).limit(3);
If you already know how to order based on timestamp, then you should do in the same way to order by likes. So to solve this, you need to add a new property under each post named likes and use the following line of code to query:
Query firstQuery = firebaseFirestore.collection("Posts").orderBy("likes", Query.Direction.DESCENDING).limit(3);
To update a the likes property, I recomment you using Firestore Transactions.
You can count the number of documents within a collection but in your case, the best option is to add a new property, as explained above.

It is possible to retrieve data from Firebase manually at need and how combine querys?

I have a Firebase Realtime Database with a set of Items who related to locations on a Googlemap. So every child in the Firebase have a data structure like this.
-item
latitude:"5511231165654"
longitude:"516891812013216"
postalcode: "10013"
cityname: "New York"
In my app every item from the database, where added to the related location on the Googlemap in form of a marker.
Now i think it is not a good idea to send all Items to all users. It´s more efficiently to send the user´s only these items that are relevant for them. These items are that one who are in the same area with the user, in this case same area means same postal code.
To handle this i build this Query
Query sortedByLocation = myRef.orderByChild("postalcode").equalTo(currentpostalcode);
sortedByLocation.addListenerForSingleValueEvent(
new ValueEventListener() {
.
. do something
.
}
i got the currentpostalcode from a Geocoder also the cityname. Now the problem is sometimes the Geocoder can´t decode the postal code and return null for it, but it allways return a cityname. So i changed the query to
Query sortedByLocation = myRef.orderByChild("cityname").equalTo(currentcity);
So how can i combine these two querys ? I want to do something like this:
is postalcode == null than check for cityname
The other Question will be, it is possible to retrieve data manually at need ?
Imagine the user start the app, the app now get all items who are in the same area with the user, but now the user left this area and go into a other area.
How can i trigger to retrieve the new data for this new area without to restart the app ?
Firebase Queries can only contain a single sort/filter condition.
Sometimes you can combine multiple values into a single property to get the behavior you want. For an example of that, see my answer here: Query based on multiple where clauses in firebase
But in general it sounds like you might be better off using GeoFire, which uses GeoHashes (a way of combining longitude and latitude into a single property) to allow filtering items based on their distance to a point. Note that at this moment, the updated version of GeoFire for Java is still in the works.

Dynamically applying filter to list of products in ecommerce application

I need some of your inputs in deciding a right approach in following case.
I am currently working on a ecommerce application ( An online shopping website).
Here, on homepage of application, I have to display a list of products available in shop.
The end user has a facility of applying a filter to products list so that only the products satisfying the applied filter will be displayed.( Filter like display products with selected company,price range and so on ).
So, my question is regarding the logic for applying the filter.
I have following ideas in mind to implement this requirement.
As user selects different criterias on page, generate SQL query dynamically( By appending a string with required where clauses) and fire the generated SQL on each request.
Set up all possible combinations of SQLs in database already ( say in a stored procedure ). As user changes the criteria, select the appropriate SQL in stored procedure to run.
Can anyone please guide me, if there is any better way to handle this requirement ?
Any input is highly appreaciated.
Please let me know if more information is required in this context.
Thanks.
I would do the first one, but you've got to be wary of SQL injection attacks.
I don't like your second option because stored procedures are usually written in a language that I consider worse than java. That's pure opinion, but that's my opinion. They also aren't database agnostic.
Alternatively, you can use JPA for this. For example, there are Hibernate Filters.
Something that works well for sites like yours is to not change the query to retrieve different items to offer for sale but, instead, to offer the all the same items but to change the order they appear on the site.
So, if the user wants items priced $100-$500, you still show the items under $100 and over $500 but the ones in that range appear first, then the ones outside the range in some sort of random order. Or, if there are multiple criteria, you may show items meeting all but one of the criteria.
This also solves the problem of the user asking for coffee mugs over $500. If there are no matches, you don't give the user 0 items to select from but you give them some of the other items with preference to coffee mugs of any price. Presenting the user with no items to purchase is a lost chance that they might see something they want.
You can implement this in either of the ways you mentioned except you are varying the "order by" clause.
My personal preference is to NOT use stored procedures.
But, if you are working with a large group with experts in database use in the group that can optimize the database usage and keep the stored procedures in top shape, that might be an option.
If its a single person or small team of java developers, don't expect them to be experts in Java and SQL/Database as well. Play to your teams strengths.

java web application - model design for displaying list with a sql join

I am authoring a javabean and would like to know if it should include properties to set values obtained from a sql join?
Say I have database tables for Products and Orders. These are also my java bean names.
Now I want to display a list of all products but in addition to all the product properties, I want to have columns to display last purchase date and last purchased by
My db query to get the product list would need to do joins to gather the additional info. It does not seem correct to have setters and getters for `last purchase date and last purchased by' in Product.java model. I may want to have a 3rd column so constantly adding new columns to my bean doesn't make sense.
How do you go about this? I seem to encounter this when needing to display lists of models in my view.
Have a Map in Product. Upon firing the sql, store hte results of the join as key value pair in the Map. K=lastpurchasedby(columnName) and V= the value
So no need to add individual attributes. They all come in key-value pairs.

Categories