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() } }
额外优化建议:
- 避免使用
!!强制非空断言,改用空安全处理:auth.currentUser?.let { user -> dataBase.child(user.uid).get().addOnCompleteListener { // ... 原有逻辑 } } ?: run { Toast.makeText(this, "用户未登录", Toast.LENGTH_LONG).show() } snapshot无需声明为类成员的lateinit变量,直接在onComplete回调中使用局部变量即可,减少不必要的内存占用。
内容的提问来源于stack exchange,提问作者CarlettoDeiSoffocotti
相关产品推荐
相关产品推荐

