android - 在 Android Kotlin 聊天应用程序中显示聊天列表时出现数据库异常
问题描述
我一直在使用 Kotlin 和 Firebase 在 Android 中开发一个聊天应用程序。注册,搜索和发送消息给用户,这一切都成功了。但我无法生成一个聊天列表,它是用户最近聊天的列表。用户可以点击它来访问特定的聊天,就像任何其他聊天应用程序一样。
用户存储在用户模型中,数据以相同的格式注册到数据库中。
我可以使用 addValueEventListener 方法显示用户的个人资料图片,但是当为聊天列表调用类似方法时,它会引发错误 - com.google.firebase.database.DatabaseException:无法转换 java 类型的对象。 lang.String 类型 kushwaha.samir.boop.models.User
这是发生错误的代码 -
val user = snapshot.getValue<User>(User::class.java!!)
存在于函数中 - chatList()
MainActivityChat 代码 >
class MainActivityChat : Fragment() {
lateinit var profile_image: CircleImageView
lateinit var firebaseUser: FirebaseUser
lateinit var reference: DatabaseReference
lateinit var referenceusers: DatabaseReference
lateinit var referenceuserschats: DatabaseReference
lateinit var referencechatlist: DatabaseReference
var root: View? = null
lateinit var auth: FirebaseAuth
lateinit var fragment: Fragment
var recyclerView: RecyclerView? = null
var userAdapter: UserAdapter? = null
var mUsers: MutableList<User>? = null
var fuser: FirebaseUser?=null
private var usersList: MutableList<Chatlist>? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
root = inflater.inflate(R.layout.activity_mainchat, container, false)
setHasOptionsMenu(true)
firebaseUser = FirebaseAuth.getInstance().currentUser!!
val uid = firebaseUser.uid
val floatingActionButton = root!!.findViewById(R.id.searchPerson) as FloatingActionButton
floatingActionButton.setOnClickListener {
val intent = Intent(activity, SearchActivity::class.java)
startActivity(intent)
}
fuser = FirebaseAuth.getInstance().currentUser!!
usersList = ArrayList()
reference = FirebaseDatabase.getInstance().getReference("Chatlist").child(fuser!!.uid)
referencechatlist = FirebaseDatabase.getInstance().getReference("Chatlist").child(fuser!!.uid)
profile_image = root!!.findViewById(R.id.profile_image)
firebaseUser = FirebaseAuth.getInstance().currentUser!!
FirebaseDatabase.getInstance().reference.child("Users").child(uid)
.addValueEventListener(object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
val user = dataSnapshot.getValue(User::class.java)
// usernamedisplay.text = user!!.username
if (user!!.profileImageUrl == "default") {
profile_image.setImageResource(R.mipmap.ic_launcher)
Log.d(ProfileFragment.TAG, "No image retrieved/found")
} else {
//change this
context?.let { Glide.with(it).load(user.profileImageUrl).into(profile_image) }!!
Log.d(ProfileFragment.TAG, "Image set")
}
}
override fun onCancelled(databaseError: DatabaseError) {
}
})
reference = FirebaseDatabase.getInstance().getReference("Chats")
reference.addValueEventListener(object : ValueEventListener {
override fun onCancelled(p0: DatabaseError) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun onDataChange(dataSnapshot: DataSnapshot) {
var unread = 0
for (snapshot in dataSnapshot.children) {
val chat = snapshot.getValue<Chat>(Chat::class.java!!)
if (chat!!.receiver == firebaseUser!!.uid && !chat!!.isIsseen!!) {
unread++
}
}
reference = FirebaseDatabase.getInstance().getReference("Chatlist").child(fuser!!.uid)
reference.addValueEventListener(object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
usersList!!.clear()
for (snapshot in dataSnapshot.children) {
val chatlist = snapshot.getValue<Chatlist>(Chatlist::class.java!!)
usersList!!.add(chatlist!!)
}
chatList()
}
override fun onCancelled(databaseError: DatabaseError) {
}
})
}
})
updateToken(FirebaseInstanceId.getInstance().token)
return root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
recyclerView = view!!.findViewById(R.id.recycler_viewmain)
recyclerView!!.setHasFixedSize(true)
recyclerView!!.layoutManager = LinearLayoutManager(context)
}
private fun updateToken(token: String?) {
val reference = FirebaseDatabase.getInstance().getReference("Tokens")
val token1 = Token(token!!)
reference.child(fuser!!.uid).setValue(token1)
}
private fun chatList() {
mUsers = ArrayList()
reference = FirebaseDatabase.getInstance().getReference("Users")
reference.addValueEventListener(object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
mUsers!!.clear()
for (snapshot in dataSnapshot.children) {
**val user = snapshot.getValue<User>(User::class.java!!)**
for (chatlist in usersList!!) {
if (user!!.id == chatlist.id) {
mUsers!!.add(user)
}
}
}
userAdapter = UserAdapter(context!!, mUsers!!, true)
recyclerView!!.adapter = userAdapter
}
override fun onCancelled(databaseError: DatabaseError) {
}
})
}
private fun status(status: String) {
reference = FirebaseDatabase.getInstance().getReference("Users").child(firebaseUser!!.uid)
val hashMap = HashMap<String, Any>()
hashMap["status"] = status
reference.updateChildren(hashMap)
}
override fun onResume() {
super.onResume()
status("online")
}
override fun onPause() {
super.onPause()
status("offline")
}
companion object {
val TAG = "MainActivityChat"
}
}
用户模型
class User {
var id: String? = null
var phoneno: String? = null
var profileImageUrl: String? = null
var search: String? = null
var status: String? = null
var username: String? = null
constructor(id: String, phoneno: String, profileImageUrl: String, search: String, status: String, username: String) {
this.id = id
this.phoneno = phoneno
this.profileImageUrl = profileImageUrl
this.search = search
this.status = status
this.username = username
}
constructor() {
}
}
聊天列表模型
import android.os.Parcelable
import kotlinx.android.parcel.Parcelize
@Parcelize
class Chatlist(val id: String):
Parcelable {
constructor() : this("")
}
日志猫
2019-03-02 22:20:52.446 20562-20562/kushwaha.samir.boop E/AndroidRuntime: FATAL EXCEPTION: main
Process: kushwaha.samir.boop, PID: 20562
com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.String to type kushwaha.samir.boop.models.User
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertBean(com.google.firebase:firebase-database@@16.0.5:423)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToClass(com.google.firebase:firebase-database@@16.0.5:214)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertToCustomClass(com.google.firebase:firebase-database@@16.0.5:79)
at com.google.firebase.database.DataSnapshot.getValue(com.google.firebase:firebase-database@@16.0.5:212)
at kushwaha.samir.boop.MainActivityChat$chatList$1.onDataChange(MainActivityChat.kt:187)
at com.google.firebase.database.core.ValueEventRegistration.fireEvent(com.google.firebase:firebase-database@@16.0.5:75)
at com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:firebase-database@@16.0.5:63)
at com.google.firebase.database.core.view.EventRaiser$1.run(com.google.firebase:firebase-database@@16.0.5:55)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6762)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
解决方案
根据您的评论,您说当您尝试记录snapshot
对象的内容时,您会得到:
{ key = status, value = offline }
这显然意味着您使用了错误的参考。所以你得到这个结果是因为你在数据库中获得了status
String 类型的属性的引用,这就是你得到那个错误的原因:
com.google.firebase.database.DatabaseException:无法将 java.lang.String 类型的对象转换为 kushwaha.samir.boop.models.User 类型
要解决此问题,请更改以下代码行:
reference.addValueEventListener(object : ValueEventListener {}
到
val rootRef = FirebaseDatabase.getInstance().getReference()
val usersRef = rootRef.child("Users")
usersRef.addValueEventListener(object : ValueEventListener {}
推荐阅读
- azure - 您如何以编程方式删除资源组中除特定资源之外的所有内容?
- javascript - Javascript 文件适用于一个 HTML 文件,但不适用于另一个
- python-3.x - 如何指定函数的函数的参数类型
- python - 根据命令行参数运行 pytest 标记
- android - 无法将 Android AAR(带有 JNI 绑定)与 Jitpack 上的源关联
- excel - 如何使用 VBA 进行 Excel 循环
- ubuntu - 如何在 .awk 脚本中编写多个命令?
- php - 如何在 PHP 中为 SQLite3 启用预写日志?
- javascript - Bcrypt比较问题nodejs
- reactjs - 来自下一个/图像的 400 错误请求