0

I have a collection of users and a collection of recipesenter image description here

And I'm using FirestorePagingAdapter to display and paginate data, I want to show recipes (title and image..) with user details(name and photo)

I could display recipes, but I couldn't get user details in the same query(there is no join in Firestore)

This is my code :

fun setUpHomeAdapter(){
    var mQuery: Query = firestore.collection("recipes")
    // Init Paging Configuration
    val config = PagedList.Config.Builder()
        .setInitialLoadSizeHint(5)
        .setEnablePlaceholders(true)
        .setPrefetchDistance(5)
        .setPageSize(5)
        .build()
    // Init Adapter Configuration
    val options = FirestorePagingOptions.Builder<Recipe>()
        .setLifecycleOwner(this)
        .setQuery(mQuery, config, Recipe::class.java)
        .build()

    mAdapter = RecipesHomePagingAdapter(options, this)

    homeRecyclerView.adapter = mAdapter
}

My Adapter :

class RecipesHomePagingAdapter(
options: FirestorePagingOptions<Recipe>,
val listener: RecipesHomeViewHolder.OnItemRecipeClickListener) : FirestorePagingAdapter<Recipe, 
                                                                 RecipesHomeViewHolder>(options) {


override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecipesHomeViewHolder {
    val view =
            LayoutInflater.from(parent.context).inflate(
                R.layout.fragment_recipe_home_item,
                parent,
                false
            )

    return RecipesHomeViewHolder(view, listener)
}


override fun onBindViewHolder(holder: RecipesHomeViewHolder, position: Int, recipe: Recipe) {
    holder.bind(recipe)
}

My ViewHolder :

 class RecipesHomeViewHolder(itemView: View, private val listener: OnItemRecipeClickListener) :
RecyclerView.ViewHolder(itemView), View.OnClickListener {

private var imageRecipe: ImageView = itemView.findViewById(R.id.image_recipe)
private var title: TextView = itemView.findViewById(R.id.title)
private var nameuser: TextView = itemView.findViewById(R.id.user_name)
private var calories: TextView = itemView.findViewById(R.id.calories_textview)
private var layout_image_recipe: RelativeLayout =
    itemView.findViewById(R.id.layout_image_recipe)
private  var id_recipe: String?=null

fun bind(recipe: Recipe) {
    Glide
        .with(imageRecipe.context)
        .load(recipe.imageUrl)
       // .diskCacheStrategy(DiskCacheStrategy.ALL)
        .placeholder(R.drawable.ic_recipe_placeholder)
        .error(R.drawable.ic_recipe_placeholder)
        .into(imageRecipe)

    calories.text = recipe.calories.toString() + " Calories"
    title.text = recipe.title
    //nameuser.text = recipe.user_uid

}

init {
    layout_image_recipe.setOnClickListener(this)
}

override fun onClick(v: View?) {
    val position = adapterPosition
    if (position != RecyclerView.NO_POSITION) {
        listener.onViewClick(v!!, position, id_recipe)

    }
}

interface OnItemRecipeClickListener {
    fun onViewClick(v: View, position: Int, id_recipe:String?)

}

}

Thanks for any help to resolve the problem!

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
Seddik Fredj
  • 123
  • 2
  • 13

1 Answers1

1

Unfortunately, you cannot pass two queries to FirestorePagingOptions, only one is allowed. The simplest thing I can think of is to add user details as properties in your Recipe object. If you cannot do that, there is another option in which you can create two separate queries and pass the result to an adapter, but in that case, you won't be able to use FirestorePagingAdapter anymore. However, pagination can still be archived by combining query cursors with the limit() method. For that, I recommend you check my answer from the following post:

And take a look at this video for a better understanding.

If you want to want to use the modern Paging 3 library, please check the following article:

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • Yes sure, thanks for your help, but i have question .. i worked with your first suggestion but do you think isnt bad idea to store same information twice?.. its redundant – Seddik Fredj Feb 24 '21 at 20:58
  • **No, it's not!** This practice is called denormalization and is a common practice when it comes to Firebase. So, I recommend you see, [Denormalization is normal with the Firebase Database](https://stackoverflow.com/questions/50947856/firebase-how-to-retrieve-two-values-for-the-same-key-query/). It's for the Realtime Database, but the same rules apply also in case of Cloud Firestore. I think you might be also interested in this answer [What is denormalization in Firebase Cloud Firestore?](https://stackoverflow.com/questions/54258303/what-is-denormalization-in-firebase-cloud-firestore/). – Alex Mamo Feb 25 '21 at 07:56