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

Firebase Realtime Database String类型值转换错误 管理员登录失败

问题原因

  1. 核心错误点在AccessAccount方法的反序列化逻辑:你没有区分普通用户和管理员的实体类,两类账号的数据库数据都被强制转换为Users类处理。
  2. 你的Firebase数据库中Admins节点存储的字段结构,和Users类的字段不匹配(字段名不一致、字段类型不一致、缺失必要字段、存在额外未知字段都有可能),导致反序列化失败,或者反序列化出的对象属性为null,调用getPhone()/getPassword()时触发空指针异常。
  3. 额外逻辑缺陷:当前自动登录逻辑仅记录记住我的勾选状态,没有区分用户身份,管理员账号勾选记住我后下次启动会错误跳转至普通用户的主页面。

修复方案

方案1(快速修复):对齐管理员节点和Users类结构

检查Firebase控制台中Admins节点下的所有字段,确保和Users类的字段名、字段类型完全一致,无缺失、无多余字段。比如Users类中phone为字符串类型,数据库中管理员的phone字段就不能存为数字类型。

方案2(规范修复):单独创建管理员实体类

新建和Admins节点结构完全匹配的Admin实体类,登录时根据当前登录身份选择对应的类做反序列化:

private void AccessAccount(String phone, String pass) {
    final DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
    rootRef.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            if (snapshot.child(parentDbName).child(phone).exists()) {
                if (parentDbName.equals("Admins")) {
                    Admin adminData = snapshot.child(parentDbName).child(phone).getValue(Admin.class);
                    // 加空指针防护,避免反序列化失败崩溃
                    if (adminData == null || adminData.getPhone() == null || adminData.getPassword() == null) {
                        Toast.makeText(LoginActivity.this, "账号数据异常", Toast.LENGTH_SHORT).show();
                        loadingDialog.dismiss();
                        return;
                    }
                    if (adminData.getPhone().equals(phone) && adminData.getPassword().equals(pass)) {
                        Toast.makeText(LoginActivity.this, "Admin: " + adminData.getName() + "\n工作顺利", Toast.LENGTH_SHORT).show();
                        loadingDialog.dismiss();
                        startActivity(new Intent(LoginActivity.this, AdminCategoryActivity.class));
                        finish();
                    } else {
                        Toast.makeText(LoginActivity.this, "密码错误", Toast.LENGTH_SHORT).show();
                        loadingDialog.dismiss();
                    }
                } else {
                    Users userData = snapshot.child(parentDbName).child(phone).getValue(Users.class);
                    if (userData == null || userData.getPhone() == null || userData.getPassword() == null) {
                        Toast.makeText(LoginActivity.this, "账号数据异常", Toast.LENGTH_SHORT).show();
                        loadingDialog.dismiss();
                        return;
                    }
                    // 原有普通用户校验逻辑
                    if (userData.getPhone().equals(phone) && userData.getPassword().equals(pass)) {
                        Toast.makeText(LoginActivity.this, "欢迎回来 " + userData.getName(), Toast.LENGTH_SHORT).show();
                        loadingDialog.dismiss();
                        startActivity(new Intent(LoginActivity.this, MainActivity.class));
                        finish();
                    } else {
                        Toast.makeText(LoginActivity.this, "密码错误", Toast.LENGTH_SHORT).show();
                        loadingDialog.dismiss();
                    }
                }
            } else {
                Toast.makeText(LoginActivity.this, "该手机号不存在", Toast.LENGTH_SHORT).show();
                loadingDialog.dismiss();
            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError error) {
            Toast.makeText(LoginActivity.this, "登录失败:" + error.getMessage(), Toast.LENGTH_SHORT).show();
            loadingDialog.dismiss();
        }
    });
}

额外优化建议

修改记住我的存储逻辑,新增用户身份标识字段,自动登录时根据存储的身份跳转对应页面,避免管理员账号跳错页面。同时给onCancelled方法加错误提示,方便排查网络/权限类问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 13:57:04