使用Kotlin在FirestoreRecycler适配器上使用UID检索显示配置文件?

时间:2019-10-28 23:47:47

标签: kotlin google-cloud-firestore recycler-adapter

我很难从Firebase Firestore正确地为我的Recycler Adapter检索信息。我不确定自己可能做错了什么,但是我使用文档参考来获取必填字段,但现在好像只是一遍又一遍地复制相同的内容,我希望它显示每个创建的用户配置文件并将其显示在我的RecyclerAdapter上但是不确定我应该怎么做,并尝试了不同的方法,但是得到了

  

我的模型类“用户”上的“无设置器/字段错误”。

This is my Firebase Schema This is what it is outputting

这是我到目前为止的代码

[更新] 这是我导入的

import Models.User
import android.content.Intent
import android.content.res.Configuration
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.widget.Toolbar
import androidx.core.view.GravityCompat
import androidx.drawerlayout.widget.DrawerLayout
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.firebase.ui.firestore.FirestoreRecyclerAdapter
import com.firebase.ui.firestore.FirestoreRecyclerOptions
import com.google.android.material.navigation.NavigationView
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.firestore.*
import com.squareup.picasso.Picasso
import de.hdodenhof.circleimageview.CircleImageView
import kotlinx.android.synthetic.main.all_nearby_users.*
import kotlinx.android.synthetic.main.toolbar_layout.*

创建时

       auth = FirebaseAuth.getInstance()
        val customUserId = auth.currentUser!!.uid
        val db = FirebaseFirestore.getInstance()
        val userRef = db.collection("sUsers").document(customUserId)
        val userQuery = db.collection("sUsers").orderBy("Full Name", Query.Direction.DESCENDING).limit(10)

//User List Layout
        all_users_nearby_list.layoutManager = LinearLayoutManager(this)

        //Firestore
        val firestoreRecyclerOptions: FirestoreRecyclerOptions<Users> = FirestoreRecyclerOptions.Builder<Users>()
            .setQuery(userQuery, Users::class.java)
            .build()
        adapter = UserFirestoreRecyclerAdapter(firestoreRecyclerOptions)
        all_users_nearby_list.adapter = adapter

Firestore回收站适配器

private inner class UserFirestoreRecyclerAdapter internal constructor
        (firestoreRecyclerOptions: FirestoreRecyclerOptions<Users>): FirestoreRecyclerAdapter<Users, UserViewHolder>(firestoreRecyclerOptions) {

            override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder {
                val userView = LayoutInflater.from(parent.context)
                    .inflate(R.layout.display_users_profile, parent, false)

                return UserViewHolder(userView)
            }

            override fun onBindViewHolder(holder: UserViewHolder, position: Int, model: Users) {

                holder.setFullname(model.fullname)
                holder.setProfileimage(model.profileImage)

            }

        }

UserViewHolder


   private inner class UserViewHolder internal constructor (private val pView: View) : RecyclerView.ViewHolder(pView) {


        internal fun setFullname(fullname: String) {
            val username = pView.findViewById<TextView>(R.id.usernameTextView)
            val db = FirebaseFirestore.getInstance()
            val docRef = db.collection("sUsers").document(auth.currentUser!!.uid)
            docRef.get()
                .addOnSuccessListener { document ->
                    if (document != null) {
                        Log.d("HomeActivity", "DocumentSnapshot data: ${document.data}")
                        username.text = document.getString("Full Name")

                    } else {
                        Log.d("HomeActivity", "No such document")
                    }
                }
                .addOnFailureListener { exception ->
                    Log.d("HomeActivity", "get failed with ", exception)
                }


            username.text = fullname
            Log.d("HomeActivity", "Current Data: " + fullname)
        }

        internal fun setProfileimage(profileImage: String) {
            val userProfileImage = pView.findViewById<CircleImageView>(R.id.profileUserImage)
            Picasso.get().load(profileImage).into(userProfileImage)
        }

    }

模型类

package Models

    class Users(
    var fullname: String= "",
    var profileImage: String= "",
    var uid: String? = "",
    var haircut: Boolean? = null,
    var waxing: Boolean? = null,
    var nails: Boolean? = null,
    var profileRatingBar: Float? = 1.0f
)

我的onStart和onStop


   override fun onStart() {
        super.onStart()
        adapter!!.startListening()
    }

    override fun onStop() {
        super.onStop()

        if (adapter != null) {
            adapter!!.stopListening()
        }
    }

1 个答案:

答案 0 :(得分:2)

这就是我编写RecyclerView的方式。重点:

  • 不要在ViewHolder内部进行第二次FireStore查询
  • 您的Firestore模式必须 完全 与您的模型匹配
  • 使用生命周期所有者而不是onStart / onStop
  • Firebase UI不会捕获uid。因此,请手动执行此操作(请参见apply
  • ViewHolder必须将视图“保留”为字段(以避免每次都调用find)
  • 模型代表1个对象,所以我将其命名为“用户”而不是“用户”
  • 在XML中设置layoutManager以减少onCreate中的样板

布局XML

<androidx.recyclerview.widget.RecyclerView
    ...
    app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
    tools:itemCount="5"
    tools:listitem="@layout/display_users_profile"
    ... />

创建活动

val query = FirebaseFirestore.getInstance()
    .collection("sUsers") // Why not "users" ?
    .orderBy("fullname", Query.Direction.DESCENDING)
    .limit(10)

val options = FirestoreRecyclerOptions.Builder<User>()
    .setLifeCycleOwner(this)
    .setQuery(query) { it.toObject(User::class.java)!!.apply { uid = it.id } }
    .build()

all_users_nearby_list.adapter = UserFirestoreRecyclerAdapter(options)

适配器

internal class UserFirestoreRecyclerAdapter(options: FirestoreRecyclerOptions<User>) : 
    FirestoreRecyclerAdapter<User, UserViewHolder>(options) {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = 
        LayoutInflater.from(parent.context)
            .inflate(R.layout.display_users_profile, parent, false)
            .let { UserViewHolder(it) }

    override fun onBindViewHolder(holder: UserViewHolder, position: Int, model: Users) = 
        holder.bind(model)

}

ViewHolder

internal class UserViewHolder(itemView: View) : 
    RecyclerView.ViewHolder(itemView) {

    // Hold view refs
    private val usernameTextView: TextView = itemView.userNameTextView
    private val profileUserImage: ImageView = itemView.profileUserImage

    internal fun bind(model: User) {
        model.apply {
            usernameTextView.text = fullname
            Picasso.get().load(profileImage).into(profileUserImage)
        }
    }
}

模型

// Set sensible defaults here (or null if no sensible default)
data class User(
    var uid: String = "",
    var fullname: String= "",
    var profileImage: String= "",
    var haircut: Boolean = false,
    var waxing: Boolean = false,
    var nails: Boolean = false,
    var profileRatingBar: Float? = null
)