从Firebase检索聊天消息时出现问题

时间:2020-08-22 18:18:07

标签: android firebase kotlin firebase-realtime-database

我正在尝试构建一个聊天应用程序,但是每当我单击任何一个用户时,它就会崩溃。

class MessegeActivity : AppCompatActivity() {

    var userIdVisit: String = ""
    var currentUserId : FirebaseUser?=null
    var chatsAdpater:ChatAdpater?=null
    var mChatList:List<Chat>?=null
    lateinit var recycler_view_chat:RecyclerView


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_messege)

        intent = intent
        userIdVisit = intent.getStringExtra("visit_id")
        currentUserId =FirebaseAuth.getInstance().currentUser!!

        recycler_view_chat =findViewById(R.id.recycler_view_chat)
        recycler_view_chat.setHasFixedSize(true)
        var linearLayoutManager =LinearLayoutManager(applicationContext)
        linearLayoutManager.stackFromEnd =true
        recycler_view_chat.layoutManager =linearLayoutManager

        //showing other username and profile dp

        val reference = FirebaseDatabase.getInstance().reference
            .child("Users").child(userIdVisit)

        reference.addValueEventListener(object : ValueEventListener {
            override fun onDataChange(p0: DataSnapshot) {
                val user: Users? = p0.getValue(Users::class.java)

                username_mchat.text = user!!.getFullName()
                Picasso.get().load(user.getImg()).into(profile_image_mchat)

                retreiveMsg(currentUserId!!.uid,userIdVisit,user.getImg())

            }

            override fun onCancelled(error: DatabaseError) {

            }
        })


        send_messege_btn.setOnClickListener {
            val messege = text_messege.text.toString()
            if (messege == "") {
                Toast.makeText(this@MessegeActivity, "Please write something!!", Toast.LENGTH_SHORT)
                    .show()
            } else {
                sendMessegeToUser(currentUserId!!.uid, userIdVisit, messege)
            }
            text_messege.setText("")
        }

        attach_image_file.setOnClickListener {
            val intent = Intent()
            intent.action = Intent.ACTION_GET_CONTENT
            intent.type = "image/*"
            startActivityForResult(Intent.createChooser(intent, "Pick Image"), 198)
        }

    }


    private fun sendMessegeToUser(senderId: String, receiverId: String?, messege: String) {

        val reference = FirebaseDatabase.getInstance().reference
        val messegeKey:String = reference.push().key!!

        val messegeHashMap = HashMap<String, Any?>()
        messegeHashMap["sender"] = senderId
        messegeHashMap["messege"] = messege
        messegeHashMap["receiver"] = receiverId
        messegeHashMap["isseen"] = "false"
        messegeHashMap["url"] = ""
        messegeHashMap["messegeId"] = messegeKey
        reference.child("Chats").child(messegeKey).setValue(messegeHashMap)
            .addOnCompleteListener { task ->
                if (task.isSuccessful) {
                    val ChatsListRefernce =
                        FirebaseDatabase.getInstance().reference.child("ChatLists").child(currentUserId!!.uid).child(userIdVisit)

                    ChatsListRefernce.addListenerForSingleValueEvent(object :ValueEventListener{
                        override fun onDataChange(p0: DataSnapshot) {
                            if(!p0.exists())
                            {
                                ChatsListRefernce.child("id").setValue(userIdVisit)
                            }

                            val ChatsListReceiverRefernce =
                                FirebaseDatabase.getInstance().reference.child("ChatLists").child(userIdVisit).child(currentUserId!!.uid)
                            ChatsListReceiverRefernce.child("id").setValue(currentUserId!!.uid)


                        }

                        override fun onCancelled(error: DatabaseError) {

                        }
                    })


                    //notification


                //    val reference = FirebaseDatabase.getInstance().reference
                   //     .child("Users").child(currentUserId!!.uid)


                }
            }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        if (requestCode == 198 && resultCode ==RESULT_OK && data!=null && data.data != null) {
            val progressBar = ProgressDialog(this)
            progressBar.setMessage("Please wait")
            progressBar.show()

            val fileUri = data.data
            val storageRef = FirebaseStorage.getInstance().reference.child("Chat Images")
            val ref = FirebaseDatabase.getInstance().reference
            val messegeId = ref.push().key
            val filepath = storageRef.child("$messegeId.jpg")

            var uploadTask: StorageTask<*>
            uploadTask = filepath.putFile(fileUri!!)

            uploadTask.continueWithTask(Continuation<UploadTask.TaskSnapshot, Task<Uri>> { task ->
                if (!task.isSuccessful) {
                    task.exception?.let {
                        throw it
                    }
                }
                return@Continuation filepath.downloadUrl
            }).addOnCompleteListener { task ->
                val downloadUrl = task.result
                val url = downloadUrl.toString()

                val messegeHashMap = HashMap<String,Any?>()
                messegeHashMap["sender"] = currentUserId!!.uid
                messegeHashMap["messege"] = "sent you an image"
                messegeHashMap["receiver"] = userIdVisit
               messegeHashMap["isseen"] = "false"
                messegeHashMap["url"] = url
                messegeHashMap["messegeId"] = messegeId.toString()

                ref.child("Chats").child(messegeId!!).setValue(messegeHashMap)

                progressBar.dismiss()
            }
        }
    }

    private fun retreiveMsg(senderId: String, receiverId: String?, recieverimgUrl: String?) {
        mChatList =ArrayList()
        val reference =FirebaseDatabase.getInstance().reference.child("Chats")

        reference.addValueEventListener(object:ValueEventListener{
            override fun onDataChange(p0: DataSnapshot) {
                (mChatList as ArrayList<Chat>).clear()
                for (snapshot in p0.children)
                {
                    val chat= snapshot.getValue(Chat::class.java)
                    if(chat!!.getReceiver().equals(senderId)&& chat.getSender().equals(receiverId) ||
                        chat.getReceiver().equals(receiverId)&& chat.getSender().equals(senderId))
                    {
                        (mChatList as ArrayList<Chat>).add(chat)
                    }
                    chatsAdpater = ChatAdpater(this@MessegeActivity,(mChatList as ArrayList<Chat>),recieverimgUrl!!)
                    recycler_view_chat.adapter =chatsAdpater
                }

            }

            override fun onCancelled(error: DatabaseError) {
                TODO("Not yet implemented")
            }
        })

    }

    }


   




    package com.insidecoderz.trails2.Model
    class Chat {
    private var sender:String =""
    private var messege:String =""
    private var receiver:String =""
    private var isseen :Boolean= false
    private var url:String =""
    private var messegeId:String =""

    constructor()
    constructor(
        sender: String,
        messege: String,
        receiver: String,
        isseen:Boolean,
        url: String,
        messegeId: String
    ) {
        this.sender = sender
        this.messege = messege
        this.receiver = receiver
        this.isseen = isseen
        this.url = url
        this.messegeId = messegeId
    }

    fun getSender(): String?{
        return sender
    }
    fun setSender(sender: String){
        this.sender =sender
    }

    fun getMessege(): String?{
        return messege
    }
    fun setMessege(messege: String){
        this.messege =messege
    }

    fun getReceiver(): String?{
        return receiver
    }
    fun setReceiver(receiver: String){
        this.receiver =receiver
    }

    fun isIsSeen(): Boolean {
        return isseen
    }
    fun setIsSeen(isseen: Boolean){
        this.isseen =isseen
    }

    fun getUrl(): String?{
        return url
    }
    fun setUrl(url: String){
        this.url =url
    }
   fun getMessegeId(): String?{
        return messegeId
    }
    fun setMessegeId(messegeId: String){
        this.messegeId =messegeId
    }

}

我一次又一次面对这个问题,每当我在模拟器中的应用程序中运行该应用程序时,它就会崩溃并显示此错误。

2020-08-22 23:19:59.920 17005-17005/com.insidecoderz.trails2 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.insidecoderz.trails2, PID: 17005
com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.Boolean to type com.insidecoderz.trails2.Model.Chat
    at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertBean(CustomClassMapper.java:435)
    at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToClass(CustomClassMapper.java:231)
    at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertToCustomClass(CustomClassMapper.java:79)
    at com.google.firebase.database.DataSnapshot.getValue(DataSnapshot.java:203)
    at com.insidecoderz.trails2.MessegeActivity$retreiveMsg$1.onDataChange(MessegeActivity.kt:202)
    at com.google.firebase.database.core.ValueEventRegistration.fireEvent(ValueEventRegistration.java:75)
    at com.google.firebase.database.core.view.DataEvent.fire(DataEvent.java:63)
    at com.google.firebase.database.core.view.EventRaiser$1.run(EventRaiser.java:55)
    at android.os.Handler.handleCallback(Handler.java:873)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:224)
    at android.app.ActivityThread.main(ActivityThread.java:7134)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:536)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:876)

1 个答案:

答案 0 :(得分:3)

如果使用以下代码val reference = FirebaseDatabase.getInstance().reference.child("Users").child(userIdVisit)访问用户的ID,然后尝试将数据作为模型Chat获取,则不能这样做,而请尝试FirebaseDatabase.getInstance().reference.child("Users")。这样,您就可以将数据作为模型Chat获得,但它不是您想要的ID,如果在节点"Users"上您有更多的用户,那么您将获得所有使用模型Chat

的用户信息

如果您需要userIdVisit的信息,则可以执行以下操作

snapshot.child("userInfo1").getValue();
snapshot.child("userInfo2").getValue();

这是Java的示例,您应该将其改编为kotlin,很抱歉没有在kotlin中提供该示例,但我不熟悉