Android Studio Firebase登录按钮跳转至主页而非用户页求助
问题排查与修复方案
看起来你遇到的卡顿和跳转异常问题,主要源于Firebase查询结果的处理逻辑错误,同时还有一些潜在的崩溃风险。下面一步步帮你分析并给出修复后的代码:
问题核心分析
查询结果解析错误:
你用orderByChild("phone").equalTo(appPhone)查询时,返回的dataSnapshot是包含所有匹配用户的父节点,而非单个用户节点。直接调用dataSnapshot.child("pass")根本取不到正确的密码值,这会导致fbasePass为null,触发assert fbasePass != null;断言错误,进而引发Activity崩溃——系统会自动回到栈中的主页,看起来像是"跳转错误"。卡顿的原因:
断言错误引发崩溃前会有短暂的主线程阻塞,同时未处理的数据库异常也可能导致界面卡顿。未处理异常场景:
onCancelled方法为空,数据库查询失败时没有任何提示,隐藏了潜在问题。
修复后的完整代码
public class loginActivity extends AppCompatActivity { TextView signup; TextInputLayout phone, pass; Button btn_login; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); signup = findViewById(R.id.txt_signup); phone = findViewById(R.id.phone); pass = findViewById(R.id.pass); btn_login = findViewById(R.id.btn_login); btn_login.setOnClickListener(view -> loginUser(view)); } private boolean validatePhone() { String p = phone.getEditText().getText().toString().trim(); if (p.isEmpty()) { phone.setError("Field is empty!"); return false; } else { phone.setError(null); phone.setErrorEnabled(false); return true; } } private boolean validatePass() { String p = pass.getEditText().getText().toString().trim(); if (p.isEmpty()) { pass.setError("Field is empty!"); return false; } else { pass.setError(null); pass.setErrorEnabled(false); return true; } } public void loginUser(View v) { // 用短路逻辑||替代|,提升效率 if (!validatePhone() || !validatePass()) { return; } else { isUser(); } } private void isUser() { final String appPhone = Objects.requireNonNull(phone.getEditText()).getText().toString().trim(); final String appPass = Objects.requireNonNull(pass.getEditText()).getText().toString().trim(); DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("users"); Query checkUser = databaseReference.orderByChild("phone").equalTo(appPhone); checkUser.addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) { if (dataSnapshot.exists()) { phone.setError(null); phone.setErrorEnabled(false); boolean userAuthenticated = false; // 遍历查询结果,获取匹配的用户节点(假设手机号唯一) for (DataSnapshot userSnapshot : dataSnapshot.getChildren()) { String fbasePass = userSnapshot.child("pass").getValue(String.class); if (fbasePass != null && fbasePass.equals(appPass)) { // 正确提取用户信息 String uPhone = userSnapshot.child("phone").getValue(String.class); String uAadhar = userSnapshot.child("aadhar").getValue(String.class); String uCity = userSnapshot.child("city").getValue(String.class); String uFname = userSnapshot.child("fname").getValue(String.class); String uEmail = userSnapshot.child("email").getValue(String.class); // 跳转至用户主页,同时清除栈中登录页 Intent intent = new Intent(loginActivity.this, usrHome.class); intent.putExtra("phone", uPhone); intent.putExtra("aadhar", uAadhar); intent.putExtra("city", uCity); intent.putExtra("fname", uFname); intent.putExtra("email", uEmail); // 防止用户返回登录页 intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); finish(); // 关闭当前登录Activity userAuthenticated = true; break; } else { pass.setError("Wrong password"); pass.requestFocus(); } } if (!userAuthenticated) { pass.setError("Wrong password"); pass.requestFocus(); } } else { phone.setError("Please Create Account First"); phone.requestFocus(); } } @Override public void onCancelled(@NonNull DatabaseError databaseError) { // 处理数据库查询失败的情况 Toast.makeText(loginActivity.this, "Database error: " + databaseError.getMessage(), Toast.LENGTH_SHORT).show(); } }); } }
关键改进点
- 正确解析查询结果:通过
dataSnapshot.getChildren()遍历匹配的用户节点,解决了之前直接访问父节点导致的null值问题。 - 移除危险断言:用null判断替代断言,避免因null值引发崩溃。
- 优化跳转逻辑:添加
Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK清除栈中页面,调用finish()关闭登录页,防止用户返回登录界面。 - 完善错误处理:在
onCancelled中添加数据库错误提示,便于排查问题。 - 逻辑运算符优化:将
!validatePhone() | !validatePass()改为!validatePhone() || !validatePass(),短路判断更高效。
额外建议
- 优先使用Firebase Authentication:官方的Auth服务提供了更安全、便捷的登录方案(手机号、邮箱密码等),无需自己管理密码存储和验证,大幅降低出错概率。
- 密码加密存储:如果必须自行存储密码,不要明文存储,应该使用SHA-256等哈希算法加密后再存入数据库。
- 添加加载状态:登录按钮点击后显示ProgressBar,避免用户重复点击,同时提升卡顿场景下的用户体验。
内容的提问来源于stack exchange,提问作者Nilay Patel
相关产品推荐
相关产品推荐

