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

Android Firebase实时数据库登录时密码返回Null问题求助

问题分析与解决方案

核心错误原因

你代码里获取密码的逻辑出现了关键错误:在循环遍历单个用户节点userSnapshot时,密码是从外层的dataSnapshot(也就是User根节点)中获取的,而非当前遍历的userSnapshot(单个用户数据节点),这直接导致找不到对应password节点,返回null引发崩溃。

修正后的完整代码

loginButton = findViewById(R.id.loginButton);
loginButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        final String username2 = username.getText().toString().trim();
        final String password2 = password.getText().toString().trim();
        
        // 提前校验输入,拦截空值
        if (username2.isEmpty() || password2.isEmpty()) {
            Toast.makeText(loginPage.this, "请输入用户名和密码", Toast.LENGTH_SHORT).show();
            return;
        }

        final DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference().child("User");
        mDatabase.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                boolean loginSuccess = false;
                for (DataSnapshot userSnapshot : dataSnapshot.getChildren()) {
                    String username1 = userSnapshot.child("username").getValue(String.class);
                    // 修正:从当前用户节点获取密码
                    String password1 = userSnapshot.child("password").getValue(String.class);
                    
                    // 跳过空数据的无效用户节点
                    if (username1 == null || password1 == null) {
                        continue;
                    }
                    
                    // 用短路逻辑与&&替代&,提升判断效率
                    if (username1.equals(username2) && password1.equals(password2)) {
                        loginSuccess = true;
                        Intent intent = new Intent(loginPage.this, oyunSec.class);
                        startActivity(intent);
                        break; // 找到匹配用户后直接跳出循环
                    }
                }
                // 循环结束后统一提示错误,避免多次弹出Toast
                if (!loginSuccess) {
                    Toast.makeText(loginPage.this, "用户名或密码错误", Toast.LENGTH_SHORT).show();
                }
            }
            @Override
            public void onCancelled(@NonNull DatabaseError error) {
                // 处理数据库访问失败的情况
                Toast.makeText(loginPage.this, "数据库访问失败:" + error.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });
    }
});

额外优化点说明

  1. 提前空值校验:在发起数据库请求前先检查输入是否为空,避免无效的数据库访问
  2. 修正密码获取节点:将dataSnapshot.child("password")改为userSnapshot.child("password"),匹配你的数据库结构
  3. 优化错误提示逻辑:设置登录成功标记,循环结束后统一提示错误,避免每个不匹配用户都弹出Toast
  4. 替换逻辑运算符:将&改为&&,短路逻辑与可在第一个条件不满足时直接跳过第二个条件,提升代码效率
  5. 完善取消回调:在onCancelled中添加错误提示,便于排查数据库访问异常

进阶效率优化建议

当前遍历所有用户的方式在用户量增大时性能会下降,推荐使用Firebase的查询功能直接定位目标用户:

// 按username字段精准查询,避免遍历全量用户
mDatabase.orderByChild("username").equalTo(username2).addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
        if (dataSnapshot.exists()) {
            // 用户名唯一,取第一个匹配的用户节点
            DataSnapshot userSnapshot = dataSnapshot.getChildren().iterator().next();
            String password1 = userSnapshot.child("password").getValue(String.class);
            if (password1 != null && password1.equals(password2)) {
                Intent intent = new Intent(loginPage.this, oyunSec.class);
                startActivity(intent);
            } else {
                Toast.makeText(loginPage.this, "密码错误", Toast.LENGTH_SHORT).show();
            }
        } else {
            Toast.makeText(loginPage.this, "用户名不存在", Toast.LENGTH_SHORT).show();
        }
    }
    @Override
    public void onCancelled(@NonNull DatabaseError error) {
        Toast.makeText(loginPage.this, "数据库访问失败:" + error.getMessage(), Toast.LENGTH_SHORT).show();
    }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 21:30:27