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

Android开发用Firebase Realtime Database实现登录无Logcat报错问题求助

问题排查与修复方案

1. 布局XML问题(你猜测的点确实存在问题)

TextInputLayout的官方推荐子控件是TextInputEditText而非原生EditText,原生EditText可能导致getEditText()读取值异常、空指针,或者样式不匹配的问题,修改代码如下:

<com.google.android.material.textfield.TextInputLayout
    android:id="@+id/loginName"
    android:layout_width="match_parent"
    android:layout_height="60dp"
    android:layout_marginLeft="20dp"
    android:layout_marginRight="20dp"
    android:background="@drawable/bg_edit_text"
    app:boxStrokeWidth="0dp"
    app:boxStrokeWidthFocused="0dp"
    android:backgroundTint="@android:color/transparent"
    >
    <com.google.android.material.textfield.TextInputEditText
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="10dp"
        android:background="@drawable/bg_edit_text"
        android:inputType="text"
        />
</com.google.android.material.textfield.TextInputLayout>

密码对应的TextInputLayout也做同样修改,把子控件换成TextInputEditText。


2. Java代码逻辑错误

2.1 validatePassword方法低级错误

你在密码校验逻辑中,误将错误提示全部设置到了用户名控件loginName上,导致密码为空、密码错误的提示完全不会显示在密码栏,你自然看不到报错,修正代码:

private Boolean validatePassword() {
    String val = loginPw.getEditText().getText().toString();
    if (val.isEmpty()) {
        // 这里原来写的是loginName,改成loginPw
        loginPw.setError("Field cannot be empty");
        return false;
    } else {
        // 这里原来写的是loginName,改成loginPw
        loginPw.setError(null);
        loginPw.setErrorEnabled(false);
        return true;
    }
}

2.2 登录判断的逻辑运算符错误

loginUser方法中你用了按位或|,应该用短路逻辑或||,避免多余的校验执行:

public void loginUser (View view) {
    // 把 | 改成 ||
    if (!validateUsername() || !validatePassword()) {
        return;
    } else {
        isUser();
    }
}

2.3 数据库取值逻辑错误

你通过orderByChild("name")查询到的快照snapshot,它的子节点是数据库中Users节点下的用户唯一ID,不是用户名本身,直接调用snapshot.child(userEnteredUsername)根本拿不到用户数据,这是你登录无反应的核心原因,修正逻辑:

private void isUser() {
    String userEnteredUsername = loginName.getEditText().getText().toString().trim();
    String userEnteredPassword = loginPw.getEditText().getText().toString().trim();
    reference = FirebaseDatabase.getInstance().getReference("Users");
    Query checkUser = reference.orderByChild("name").equalTo(userEnteredUsername);
    checkUser.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            if (snapshot.exists()){
                loginName.setError(null);
                loginName.setErrorEnabled(false);
                // 遍历查询到的用户节点,取第一个匹配的用户
                for (DataSnapshot userSnapshot : snapshot.getChildren()) {
                    String passwordFromDb = userSnapshot.child("password").getValue(String.class);
                    if (passwordFromDb.equals(userEnteredPassword)){
                        Intent intent = new Intent(getApplicationContext(), HomeActivity.class);
                        startActivity(intent);
                        // 匹配成功直接返回,避免继续遍历
                        return;
                    } else {
                        loginPw.setError("Wrong Password");
                        loginPw.requestFocus();
                    }
                }
            } else {
                loginName.setError("No such user exists");
                loginName.requestFocus();
            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError error) {
            // 空实现会吃掉所有数据库错误,至少加个日志打印
            Log.e("LoginError", error.getMessage());
        }
    });
}

额外安全提示

不要在Realtime Database中存储明文密码,Firebase官方提供了专门的Firebase Auth服务处理用户登录注册逻辑,安全性远高于自定义存储密码的方案,建议后续切换到官方Auth方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 23:15:06