You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin+Android Studio:Firebase存储用户信息时User对象输出异常

问题描述

尝试将uid、username和profileImageUrl保存到Firebase数据库时,除User对象外其他变量都能输出预期值,但User对象日志显示为letsbuildthatapp.com.User@41cb40,怀疑User对象逻辑存在问题。

保存用户至数据库的函数:

private fun saveUserToFirebaseDatabase(profileImageUrl: String) {
    val uid = FirebaseAuth.getInstance().uid ?: ""
    val ref = FirebaseDatabase.getInstance().getReference("/users/$uid")

    val user = User(uid, username_edittext_register.text.toString(), profileImageUrl)

    ref.setValue(user)
            .addOnSuccessListener {
                    Log.d("RegisterActivity", "Finally we saved the user to Firebase Database")

                    val intent = Intent(this,LatestMessagesActivity::class.java)
                    intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TASK.or(Intent.FLAG_ACTIVITY_NEW_TASK)
                    startActivity(intent)
            }
            .addOnFailureListener{
                    Log.d("RegisterActivity", "Failed to set value to database: ${it.message}")
            }
            Log.d("saveUserToDatabase","Task completed? User: $user")
}

User类:

class User(val uid: String,val username: String,val profileImageUrl: String) {
    constructor() : this("", "", "")
}

完整代码:

package letsbuildthatapp.com

import android.app.Activity
import android.content.ContentValues.TAG
import android.content.Intent
import android.graphics.drawable.BitmapDrawable
import android.net.Uri
import android.os.Bundle
import android.provider.MediaStore
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.database.FirebaseDatabase
import com.google.firebase.storage.FirebaseStorage
import kotlinx.android.synthetic.main.activity_register.*
import java.util.*


class RegisterActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_register)

        register_button_register.setOnClickListener {
            performRegister()
        }

        already_have_account_text_view.setOnClickListener {
            Log.d("RegisterActivity", "Try to show login activity")

            //Launch the login activity somehow
            val intent = Intent(this, LoginActivity::class.java)
            startActivity(intent)
        }

        selectphoto_button_register.setOnClickListener {
            Log.d("RegisterActivity", "Try to show photo selector")

            val intent = Intent(Intent.ACTION_PICK)
            intent.type = "image/*"
            startActivityForResult(intent, 0)
        }
    }

    var selectedPhotoUri: Uri? = null

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

        if (requestCode == 0 && resultCode == Activity.RESULT_OK && data != null) {
            Log.d("RegisterActivity", "Photo was selected")

            selectedPhotoUri = data.data

            val bitmap = MediaStore.Images.Media.getBitmap(contentResolver,selectedPhotoUri)

            select_photo_imageView_register.setImageBitmap(bitmap)
            selectphoto_button_register.alpha = 0f
        }
    }

    private fun performRegister() {
        val username = username_edittext_register.text.toString()
        val email = email_edittext_register.text.toString()
        val password = password_edittext_register.text.toString()

        if (email.isEmpty() || password.isEmpty()) {
            Toast.makeText(this,"Please enter text in email/password", Toast.LENGTH_SHORT).show()
            return
        }

        Log.d("RegisterActivity", "Username: $username")
        Log.d("RegisterActivity", "Email is: $email")
        Log.d("RegisterActivity", "Password: $password")

        // Firebase Authentication to create a user with email and password
        FirebaseAuth.getInstance().createUserWithEmailAndPassword(email, password)
        .addOnCompleteListener{
        if (!it.isSuccessful) return@addOnCompleteListener

                //else if successful
                Log.d("RegisterActivity", "Successfully created user with uid: ${it.result.user!!.uid}")
                        uploadImageToFirebaseStorage()
                }
                .addOnFailureListener{
                        Log.d("RegisterActivity","Failed to create user: ${it.message}")
                        Toast.makeText(this,"Failed to create user: ${it.message}", Toast.LENGTH_SHORT).show()
                }
        }

    private fun uploadImageToFirebaseStorage() {
        if (selectedPhotoUri == null) return

        val filename = UUID.randomUUID().toString()
        val ref = FirebaseStorage.getInstance().getReference("/images/$filename")

        ref.putFile(selectedPhotoUri!!)
                .addOnSuccessListener {
                        Log.d("RegisterActivity", "Successfully uploaded image: ${it.metadata?.path}")

                        ref.downloadUrl.addOnSuccessListener {
                                Log.d("RegisterActivity", "File Location: $it")

                                saveUserToFirebaseDatabase(it.toString())
                        }
                }
                .addOnFailureListener{
                        Log.d("RegisterActivity", "Failed")
                        Toast.makeText(this,"Failed: ${it.message}", Toast.LENGTH_SHORT).show()
                }
    }

    private fun saveUserToFirebaseDatabase(profileImageUrl: String) {
        val uid = FirebaseAuth.getInstance().uid ?: ""
        val ref = FirebaseDatabase.getInstance().getReference("/users/$uid")

        val user = User(uid, username_edittext_register.text.toString(), profileImageUrl)

        ref.setValue(user)
                .addOnSuccessListener {
                        Log.d("RegisterActivity", "Finally we saved the user to Firebase Database")

                        val intent = Intent(this,LatestMessagesActivity::class.java)
                        intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TASK.or(Intent.FLAG_ACTIVITY_NEW_TASK)
                        startActivity(intent)
                }
                .addOnFailureListener{
                        Log.d("RegisterActivity", "Failed to set value to database: ${it.message}")
                }
                Log.d("saveUserToDatabase","Task completed? User: $user")
    }
}

class User(val uid: String,val username: String,val profileImageUrl: String) {
    constructor() : this("", "", "")
}

问题分析与解决

问题根源

  1. 日志显示问题:直接打印User对象时,默认调用Any类的toString()方法,输出格式为包名.类名@哈希值,仅代表对象内存标识,而非实际属性数据。
  2. Firebase序列化隐患:普通Kotlin类未满足Firebase Realtime Database的序列化要求,虽然有默认构造函数,但字段无法被自动识别序列化,可能导致数据库写入异常。

解决方案

1. 自定义toString()方法(解决日志显示)

修改User类,添加自定义toString()方法,让日志输出对象的实际属性值:

class User(val uid: String, val username: String, val profileImageUrl: String) {
    constructor() : this("", "", "")

    override fun toString(): String {
        return "User(uid='$uid', username='$username', profileImageUrl='$profileImageUrl')"
    }
}

2. 改用Kotlin Data Class(推荐,双重解决问题)

Kotlin的Data Class会自动生成toString()、equals()等方法,同时Firebase能更友好地处理其序列化逻辑:

data class User(val uid: String, val username: String, val profileImageUrl: String) {
    constructor() : this("", "", "")
}

修改后,打印User对象会直接输出所有属性值,同时Firebase能正确将字段写入数据库。

3. 验证结果

重新运行代码,查看日志中User对象的输出内容,同时登录Firebase控制台,检查/users/[uid]路径下是否存在uid、username、profileImageUrl三个字段的正确数据。

内容的提问来源于stack exchange,提问作者Andrey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 18:39:22