I'm using Firebase UI to populate my RecyclerView, it all works fine except when I try to change the order of list elements when a button is clicked.
Here is my adapter code:
private var query: Query = FirebaseFirestore.getInstance()
.collection("restaurant")
.orderBy("review", Query.Direction.DESCENDING)
var options: FirestoreRecyclerOptions<Restaurant> = FirestoreRecyclerOptions.Builder<Restaurant>()
.setQuery(query, Restaurant::class.java)
.build()
private var adapter: FirestoreRecyclerAdapter<*, *> =
object : FirestoreRecyclerAdapter<Restaurant, RestaurantListAdapter.ViewHolder?>(options) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RestaurantListAdapter.ViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.restaurant_card_view_design, parent, false)
return RestaurantListAdapter.ViewHolder(view)
}
@SuppressLint("ResourceAsColor")
override fun onBindViewHolder(
holder: RestaurantListAdapter.ViewHolder , position: Int, model: Restaurant
) {
val sharedPref = getPreferences(Context.MODE_PRIVATE) ?: return
val defaultValue = resources.getString(R.string.def_loc_key)
val lat = sharedPref.getFloat(getString(R.string.latitude_key), defaultValue.toFloat())
val long = sharedPref.getFloat(getString(R.string.longitude_key), defaultValue.toFloat())
model.calculateDistance(lat, long)
// sets the text to the textview from our itemHolder class
holder.distance.text = String.format("%.1f mi", model.distance)
holder.name.text = model.name
holder.reviewNum.text = String.format("()", model.numReview)
holder.review.rating = model.review
if (position == 0) {
//holder.card.setCardBackgroundColor(R.color.recommendedCard)
holder.card.setCardBackgroundColor(ContextCompat.getColor(holder.card.context, R.color.recommendedCard))
}
holder.logo.setImageResource(
resources.getIdentifier(model.logo , "drawable",
packageName
))
}
}
And here is my code for on button click (inside onCreate()):
val sortButton = findViewById<ImageButton>(R.id.sortButton)
sortButton.setOnClickListener {
query = query.orderBy("numReviews", Query.Direction.DESCENDING) // new campo
options = FirestoreRecyclerOptions.Builder<Restaurant>()
.setQuery(query, Restaurant::class.java).build()
adapter.updateOptions(options)
}
I get an error on the last line saying :
Type mismatch: inferred type is FirestoreRecyclerOptions but Nothing was expected
CodePudding user response:
When you are using the following query:
private var query: Query = FirebaseFirestore.getInstance()
.collection("restaurant")
.orderBy("review", Query.Direction.DESCENDING)
It simply means that are trying to get all documents that exist in the "restaurant" collection, ordered by "review" descending. Which is fine. However, when you are using the following line:
query = query.orderBy("numReviews", Query.Direction.DESCENDING)
It means that you are adding an additional order to your existing query. So after adding the above orderBy, your query looks like this:
private var query: Query = FirebaseFirestore.getInstance()
.collection("restaurant")
.orderBy("review", Query.Direction.DESCENDING)
.orderBy("numReviews", Query.Direction.DESCENDING)
This type of query doesn't work by default, as it requires an index.
Please note, that Cloud Firestore queries are immutable, which means that you cannot change the properties of an existing query. If you change the value by calling an "orderBy()" method, it becomes a new query. So if you only want to change the order, simply change the second query to:
query = FirebaseFirestore.getInstance()
.collection("restaurant")
.orderBy("numReviews", Query.Direction.DESCENDING)
//