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

Firebase用户信息更新异常求助:提示成功但无实际变更

Firebase 用户资料更新功能异常排查

我用Firebase开发了更新用户名和头像的功能,现在遇到了问题:进度条正常显示,也弹出了更新成功的Toast,但Realtime Database和个人资料页面的数据都没变化,而且看不到明显错误。以下是我的Settings Activity代码,求帮忙排查。

class AccountSettingsActivity : AppCompatActivity()
{
    private lateinit var firebaseUser: FirebaseUser
    private var checker = ""
    private var myUrl = ""
    private var imageUri: Uri? = null
    private var storageProfilePicRef: StorageReference? = null
    private lateinit var imageView: ImageView
    companion object {
        val pickImage = 100
    }

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

        firebaseUser = FirebaseAuth.getInstance().currentUser!!
        storageProfilePicRef = FirebaseStorage.getInstance().reference.child("Profile Pictures")

        val logoutbtn = findViewById<Button>(logout_btn)

        logoutbtn.setOnClickListener {
            FirebaseAuth.getInstance().signOut()

            val intent = Intent(this@AccountSettingsActivity, SignInActivity::class.java)
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
            startActivity(intent)
            finish()
        }
        val changeImage = findViewById<TextView>(R.id.change_image_text_btn)
        val saveInfBtn = findViewById<ImageView>(R.id.save_infor_profile_btn)
        changeImage.setOnClickListener{
            pickImageGallery()
        }
        saveInfBtn.setOnClickListener {

                uploadImageAndUpdateInfo()
        }
        userInfo()
    }
    private fun pickImageGallery() {
        val gallery = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI)
        startActivityForResult(gallery, pickImage)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?)
    {
        super.onActivityResult(requestCode, resultCode, data)
        var profilepic = findViewById<ImageView>(profile_image_view_profile_frag)
        if (resultCode == RESULT_OK && requestCode == pickImage) {
            imageUri = data?.data
            profilepic.setImageURI(imageUri)

        }
    }

    private fun updateUserInfoOnly()
    {                val usernameSettings = findViewById<EditText>(username_profile_frag)

        when {
            usernameSettings.text.toString() == "" -> Toast.makeText(this, "Please write user name first.", Toast.LENGTH_LONG).show()
            else -> {
                val usersRef = FirebaseDatabase.getInstance().reference.child("Users")

                val userMap = HashMap<String, Any>()
                userMap["username"] = usernameSettings.text.toString().toLowerCase()

                usersRef.child(firebaseUser.uid).updateChildren(userMap)

                Toast.makeText(
                    this,
                    "Account Information has been updated successfully.",
                    Toast.LENGTH_LONG
                ).show()

                val intent = Intent(this@AccountSettingsActivity, MainActivity::class.java)
                startActivity(intent)
                finish()
            }
        }
    }

    private fun userInfo()
    {
        val usernameSettings = findViewById<EditText>(username_profile_frag)
        val imageSettings = findViewById<ImageView>(profile_image_view_profile_frag)

        val usersRef =
            FirebaseDatabase.getInstance().getReference().child("Users")
                .child(firebaseUser.uid)

        usersRef.addValueEventListener(object : ValueEventListener {
            override fun onDataChange(p0: DataSnapshot) {
                if (p0.exists()) {
                    val user = p0.getValue<User>(User::class.java)

                    Picasso.get().load(user!!.getImage()).placeholder(R.drawable.profile).into(imageSettings)
                    usernameSettings.setText(user!!.getUsername())

                }
            }

            override fun onCancelled(p0: DatabaseError) {

            }
        })
    }

    private fun uploadImageAndUpdateInfo()
    {            val usernameSettings = findViewById<EditText>(R.id.username_profile_frag)

        when
        {
            imageUri == null -> Toast.makeText(this, "Please select image first.", Toast.LENGTH_LONG).show()
            usernameSettings.text.toString() == "" -> Toast.makeText(this, "Please write user name first.", Toast.LENGTH_LONG).show()
            else -> {
                val progressDialog = ProgressDialog(this)
                progressDialog.setTitle("Account Settings")
                progressDialog.setMessage("Please wait, we are updating your profile...")
                progressDialog.show()

                val fileRef = storageProfilePicRef!!.child(firebaseUser!!.uid + ".jpg")

                var uploadTask: StorageTask<*>
                uploadTask = fileRef.putFile(imageUri!!)

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

                        val ref = FirebaseDatabase.getInstance().reference.child("Users")
                        val usernameSettings = findViewById<EditText>(R.id.username_profile_frag)

                        val userMap = HashMap<String, Any>()
                        userMap["username"] = usernameSettings.text.toString().toLowerCase()
                        userMap["image"] = myUrl

                        ref.child(firebaseUser.uid).updateChildren(userMap)

                        Toast.makeText(
                            this,
                            "Account Information has been updated successfully.",
                            Toast.LENGTH_LONG
                        ).show()
                        val intent = Intent(this@AccountSettingsActivity, MainActivity::class.java)
                        startActivity(intent)
                        finish()
                        progressDialog.dismiss()
                    }
                    else
                    {
                        progressDialog.dismiss()
                    }
                } )
            }
        }
    }

}

问题排查关键点

  • 数据库操作无回调监听:当前代码调用updateChildren(userMap)后没有添加成功/失败回调,根本不知道数据库操作是否真的执行了,也没法捕获潜在错误。
  • 异常处理逻辑失效:continueWithTask里throw it之后的progressDialog.dismiss()永远不会执行,而且数据库更新的异常完全没处理。
  • 重复获取控件实例:uploadImageAndUpdateInfo里多次调用findViewById拿同一个EditText,属于冗余操作。
  • 实时监听没必要:userInfo用addValueEventListener是实时监听,但你只是初始化页面时读一次数据,用单次监听更合适。

修改后的代码示例

class AccountSettingsActivity : AppCompatActivity() {
    private lateinit var firebaseUser: FirebaseUser
    private var myUrl = ""
    private var imageUri: Uri? = null
    private var storageProfilePicRef: StorageReference? = null
    private lateinit var usernameSettings: EditText
    private lateinit var profilepic: ImageView

    companion object {
        const val pickImage = 100
    }

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

        firebaseUser = FirebaseAuth.getInstance().currentUser!!
        storageProfilePicRef = FirebaseStorage.getInstance().reference.child("Profile Pictures")

        // 提前初始化所有需要的控件,避免重复查找
        usernameSettings = findViewById(R.id.username_profile_frag)
        profilepic = findViewById(R.id.profile_image_view_profile_frag)
        val logoutbtn = findViewById<Button>(R.id.logout_btn)
        val changeImage = findViewById<TextView>(R.id.change_image_text_btn)
        val saveInfBtn = findViewById<ImageView>(R.id.save_infor_profile_btn)

        logoutbtn.setOnClickListener {
            FirebaseAuth.getInstance().signOut()
            val intent = Intent(this@AccountSettingsActivity, SignInActivity::class.java)
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
            startActivity(intent)
            finish()
        }

        changeImage.setOnClickListener {
            pickImageGallery()
        }

        saveInfBtn.setOnClickListener {
            uploadImageAndUpdateInfo()
        }

        userInfo()
    }

    private fun pickImageGallery() {
        val gallery = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI)
        startActivityForResult(gallery, pickImage)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode == RESULT_OK && requestCode == pickImage) {
            imageUri = data?.data
            profilepic.setImageURI(imageUri)
        }
    }

    private fun updateUserInfoOnly() {
        when {
            usernameSettings.text.toString().isEmpty() -> {
                Toast.makeText(this, "请先输入用户名", Toast.LENGTH_LONG).show()
            }
            else -> {
                val usersRef = FirebaseDatabase.getInstance().reference.child("Users")
                val userMap = HashMap<String, Any>()
                userMap["username"] = usernameSettings.text.toString().lowercase()

                // 添加数据库更新回调,明确知道操作结果
                usersRef.child(firebaseUser.uid).updateChildren(userMap)
                    .addOnSuccessListener {
                        Toast.makeText(this, "账户信息更新成功", Toast.LENGTH_LONG).show()
                        val intent = Intent(this@AccountSettingsActivity, MainActivity::class.java)
                        startActivity(intent)
                        finish()
                    }
                    .addOnFailureListener { e ->
                        Toast.makeText(this, "更新失败:${e.message}", Toast.LENGTH_LONG).show()
                    }
            }
        }
    }

    private fun userInfo() {
        val usersRef = FirebaseDatabase.getInstance().getReference().child("Users").child(firebaseUser.uid)
        // 用单次监听代替实时监听,节省资源
        usersRef.addListenerForSingleValueEvent(object : ValueEventListener {
            override fun onDataChange(p0: DataSnapshot) {
                if (p0.exists()) {
                    val user = p0.getValue<User>(User::class.java) ?: return
                    Picasso.get().load(user.getImage()).placeholder(R.drawable.profile).into(profilepic)
                    usernameSettings.setText(user.getUsername())
                }
            }

            override fun onCancelled(p0: DatabaseError) {
                Toast.makeText(this@AccountSettingsActivity, "读取用户信息失败:${p0.message}", Toast.LENGTH_LONG).show()
            }
        })
    }

    private fun uploadImageAndUpdateInfo() {
        when {
            imageUri == null -> {
                Toast.makeText(this, "请先选择图片", Toast.LENGTH_LONG).show()
            }
            usernameSettings.text.toString().isEmpty() -> {
                Toast.makeText(this, "请先输入用户名", Toast.LENGTH_LONG).show()
            }
            else -> {
                val progressDialog = ProgressDialog(this)
                progressDialog.setTitle("账户设置")
                progressDialog.setMessage("请稍候,我们正在更新你的资料...")
                progressDialog.show()

                val fileRef = storageProfilePicRef!!.child(firebaseUser.uid + ".jpg")
                val uploadTask = fileRef.putFile(imageUri!!)

                uploadTask.continueWithTask(Continuation<UploadTask.TaskSnapshot, Task<Uri>> { task ->
                    if (!task.isSuccessful) {
                        task.exception?.let { throw it }
                    }
                    return@Continuation fileRef.downloadUrl
                }).addOnCompleteListener { task ->
                    if (task.isSuccessful) {
                        val downloadUrl = task.result ?: run {
                            progressDialog.dismiss()
                            Toast.makeText(this, "获取图片链接失败", Toast.LENGTH_LONG).show()
                            return@addOnCompleteListener
                        }
                        myUrl = downloadUrl.toString()

                        val ref = FirebaseDatabase.getInstance().reference.child("Users")
                        val userMap = HashMap<String, Any>()
                        userMap["username"] = usernameSettings.text.toString().lowercase()
                        userMap["image"] = myUrl

                        // 给数据库更新加回调,捕获结果
                        ref.child(firebaseUser.uid).updateChildren(userMap)
                            .addOnSuccessListener {
                                Toast.makeText(this, "账户信息更新成功", Toast.LENGTH_LONG).show()
                                val intent = Intent(this@AccountSettingsActivity, MainActivity::class.java)
                                startActivity(intent)
                                finish()
                                progressDialog.dismiss()
                            }
                            .addOnFailureListener { e ->
                                Toast.makeText(this, "更新失败:${e.message}", Toast.LENGTH_LONG).show()
                                progressDialog.dismiss()
                            }
                    } else {
                        progressDialog.dismiss()
                        Toast.makeText(this, "图片上传失败:${task.exception?.message}", Toast.LENGTH_LONG).show()
                    }
                }
            }
        }
    }
}

关键修改说明

  1. 添加数据库操作回调:给updateChildren加上成功和失败监听,能明确知道数据库操作是否成功,还能拿到错误信息。
  2. 修复异常处理:移除无效的progressDialog.dismiss(),在任务失败分支正确关闭进度条并提示错误。
  3. 提前初始化控件:在onCreate里一次性获取所有控件,避免重复调用findViewById。
  4. 优化监听方式:把实时监听改成单次监听,没必要一直盯着数据库变化。
  5. 空安全优化:获取图片下载链接时加空判断,避免空指针异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 06:23:08