Android Studio底部导航栏Profile页面Firebase数据显示为空
问题分析与解决方案
核心问题
LoginActivity中使用orderByChild("username").equalTo(userUsername)查询Firebase数据后,错误地直接通过snapshot.child(userUsername)读取字段,导致获取到的nameFromDB、emailFromDB等值为null,最终传递到ProfileActivity的Intent数据为空。
当使用orderByChild进行查询时,返回的DataSnapshot是一个包含所有匹配节点的列表,即使只有一个匹配结果,也需要遍历其子节点来获取数据,而不是直接通过用户名作为子节点路径读取。
解决方案1:修复LoginActivity的数据读取逻辑
修改checkUser方法中的数据读取部分,正确遍历查询结果的子节点:
public void checkUser(){ String userUsername = loginUsername.getText().toString().trim(); String userPassword = loginPassword.getText().toString().trim(); DatabaseReference reference = FirebaseDatabase.getInstance().getReference("users"); Query checkUserDatabase = reference.orderByChild("username").equalTo(userUsername); checkUserDatabase.addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { if (snapshot.exists()){ loginUsername.setError(null); // 遍历查询结果的子节点(这里只会有一个匹配项) for (DataSnapshot userSnapshot : snapshot.getChildren()) { String passwordFromDB = userSnapshot.child("password").getValue(String.class); if (passwordFromDB != null && passwordFromDB.equals(userPassword)) { loginUsername.setError(null); String nameFromDB = userSnapshot.child("name").getValue(String.class); String emailFromDB = userSnapshot.child("email").getValue(String.class); String usernameFromDB = userSnapshot.child("username").getValue(String.class); Intent intent = new Intent(LoginActivity.this, ProfileActivity.class); intent.putExtra("name", nameFromDB); intent.putExtra("email", emailFromDB); intent.putExtra("username", usernameFromDB); intent.putExtra("password", passwordFromDB); startActivity(intent); } else { loginPassword.setError("Invalid Credentials"); loginPassword.requestFocus(); } } } else { loginUsername.setError("User does not exist"); loginUsername.requestFocus(); } } @Override public void onCancelled(@NonNull DatabaseError error) { } }); }
解决方案2:优化ProfileActivity的空值处理(可选)
在ProfileActivity中增加空值判断,避免空指针异常,同时提升用户体验:
public void showAllUserData(){ Intent intent = getIntent(); String nameUser = intent.getStringExtra("name"); String emailUser = intent.getStringExtra("email"); String usernameUser = intent.getStringExtra("username"); String passwordUser = intent.getStringExtra("password"); // 空值替换为默认文本 titleName.setText(nameUser != null ? nameUser : "未设置"); titleUsername.setText(usernameUser != null ? usernameUser : "未设置"); profileName.setText(nameUser != null ? nameUser : "未设置"); profileEmail.setText(emailUser != null ? emailUser : "未设置"); profileUsername.setText(usernameUser != null ? usernameUser : "未设置"); profilePassword.setText(passwordUser != null ? passwordUser : "未设置"); }
额外建议:避免Intent传递敏感数据
直接通过Intent传递密码存在安全风险,建议:
- 登录后保存用户的用户名到SharedPreferences
- 在ProfileActivity中直接从Firebase数据库读取当前用户的数据,无需通过Intent传递
示例(ProfileActivity修改):
@Override protected void onCreate(Bundle savedInstanceState) { // ... 原有代码 ... // 从SharedPreferences获取登录的用户名(需要在LoginActivity登录成功后保存) SharedPreferences prefs = getSharedPreferences("UserPrefs", MODE_PRIVATE); String currentUsername = prefs.getString("username", ""); // 直接从Firebase读取数据 DatabaseReference reference = FirebaseDatabase.getInstance().getReference("users").child(currentUsername); reference.addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { if (snapshot.exists()) { HelperClass user = snapshot.getValue(HelperClass.class); if (user != null) { titleName.setText(user.getName()); titleUsername.setText(user.getUsername()); profileName.setText(user.getName()); profileEmail.setText(user.getEmail()); profileUsername.setText(user.getUsername()); profilePassword.setText(user.getPassword()); } } } @Override public void onCancelled(@NonNull DatabaseError error) { } }); }
同时在LoginActivity登录成功后添加保存逻辑:
// 在startActivity(intent)之前添加 SharedPreferences prefs = getSharedPreferences("UserPrefs", MODE_PRIVATE); SharedPreferences.Editor editor = prefs.edit(); editor.putString("username", usernameFromDB); editor.apply();
内容的提问来源于stack exchange,提问作者Никита Шевchenko
相关产品推荐
相关产品推荐

