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

Kotlin读取Firebase实时数据库闪退问题求助

问题描述

我正在开发一个从Firebase读取数据并展示到TextView的项目,但打开对应Activity时应用闪退,怀疑问题出在使用.child查询数据库并通过.get获取数据的环节。

代码
class SchermataUtente : AppCompatActivity() {
    private lateinit var binding : ActivitySchermataUtenteBinding
    private lateinit var auth : FirebaseAuth
    private lateinit var dataBase : DatabaseReference
    private lateinit var snapshot: DataSnapshot

    override fun onCreate(savedInstanceState: Bundle?)
    {
        super.onCreate(savedInstanceState)
        binding = ActivitySchermataUtenteBinding.inflate(layoutInflater)
        setContentView(binding.root)

        leggiDataBase()

        auth = FirebaseAuth.getInstance()
        val disconnetti : Button = findViewById(R.id.Disconnetti)
        disconnetti.setOnClickListener {
            auth.signOut()
            val toLogin = Intent(this, Login::class.java)
            startActivity(toLogin)
            finish()
        }

    }

    private fun leggiDataBase()
    {
        dataBase = FirebaseDatabase.getInstance().getReference("Utenti")
        dataBase.child(auth.currentUser!!.uid).get().addOnCompleteListener {
            if (it.isSuccessful)
            {
                if (it.result.exists())
                {
                    snapshot = it.result
                    val textNomeUtente = snapshot.child("nome").value.toString()
                    val textCognomeUtente = snapshot.child("cognome").value.toString()
                    val textEmailUtente = snapshot.child("email").value.toString()
                    binding.SUTextNome.text = textNomeUtente
                    binding.SUTextCognome.text = textCognomeUtente
                    binding.SUTextEmail.text = textEmailUtente
                }else
                {
                    Toast.makeText(this, "L'utente non esiste!", Toast.LENGTH_LONG).show()
                }
            }else
            {
                Toast.makeText(this, "Dati non trovati!", Toast.LENGTH_LONG).show()
            }
        }
    }

    override fun onRestart() {
        super.onRestart()
        if(auth.currentUser != null)
        {
            Log.d("SchermataUtente", "torno al menu a tendina (restart)")
            val toMenuTendina = Intent(this, MenuTendina::class.java)
            startActivity(toMenuTendina)
            finish()
        }
    }

    override fun finish() {
        super.finish()
        overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right)
    }
}
报错信息
FATAL EXCEPTION: main
    Process: com.example.pizzeriadatot, PID: 30843
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.pizzeriadatot/com.example.pizzeriadatot.SchermataUtente}: kotlin.UninitializedPropertyAccessException: lateinit property auth has not been initialized
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3616)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3780)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2251)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:233)
        at android.app.ActivityThread.main(ActivityThread.java:8068)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:631)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:978)
    Caused by: kotlin.UninitializedPropertyAccessException: lateinit property auth has not been initialized
        at com.example.pizzeriadatot.SchermataUtente.leggiDataBase(SchermataUtente.kt:43)
        at com.example.pizzeriadatot.SchermataUtente.onCreate(SchermataUtente.kt:27)
        at android.app.Activity.performCreate(Activity.java:8006)
        at android.app.Activity.performCreate(Activity.java:7990)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1329)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3589)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3780) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2251) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:233) 
        at android.app.ActivityThread.main(ActivityThread.java:8068) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:631) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:978) 
解决方案

闪退原因明确:调用leggiDataBase()时,auth变量还未初始化。你在onCreate中先执行了leggiDataBase(),之后才给auth赋值auth = FirebaseAuth.getInstance(),而leggiDataBase()里用到了auth.currentUser!!.uid,此时auth还是未初始化的lateinit变量,直接触发了UninitializedPropertyAccessException。

修复步骤:

  • 将auth = FirebaseAuth.getInstance()移到leggiDataBase()调用之前,确保调用数据库方法时auth已完成初始化。

修改后的onCreate方法:

override fun onCreate(savedInstanceState: Bundle?)
{
    super.onCreate(savedInstanceState)
    binding = ActivitySchermataUtenteBinding.inflate(layoutInflater)
    setContentView(binding.root)

    // 先初始化auth
    auth = FirebaseAuth.getInstance()
    // 再调用数据库读取方法
    leggiDataBase()

    val disconnetti : Button = findViewById(R.id.Disconnetti)
    disconnetti.setOnClickListener {
        auth.signOut()
        val toLogin = Intent(this, Login::class.java)
        startActivity(toLogin)
        finish()
    }
}

额外优化建议:

  1. 避免使用!!强制非空断言,改用空安全处理:
    auth.currentUser?.let { user ->
        dataBase.child(user.uid).get().addOnCompleteListener {
            // ... 原有逻辑
        }
    } ?: run {
        Toast.makeText(this, "用户未登录", Toast.LENGTH_LONG).show()
    }
    
  2. snapshot无需声明为类成员的lateinit变量,直接在onComplete回调中使用局部变量即可,减少不必要的内存占用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 07:32:09