用户信息无法在个人资料显示,Firebase数据存储读取异常排查
问题排查:Firebase注册用户UID不匹配导致资料无法显示
问题概述
- 应用个人资料页面无法加载用户姓名、学号、邮箱及密码数据,数据来源为Firebase Realtime Database的
User节点 - Realtime Database中存储的用户节点为
-NUM格式的无效ID,而Firebase Authentication中存在合法的用户UID - 调整读取数据代码后仍无效果
相关代码
显示用户数据的方法
public void showAllUserData(String pushKey) { FirebaseAuth auth = FirebaseAuth.getInstance(); FirebaseUser user = auth.getCurrentUser(); if (user != null) { String userKey = user.getUid(); ref.child(userKey).child(pushKey).addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) { String nameString = dataSnapshot.child("userName").getValue(String.class); String studNumString = dataSnapshot.child("userStudNo").getValue(String.class); String emailString = dataSnapshot.child("userEmail").getValue(String.class); String passString = dataSnapshot.child("userPass").getValue(String.class); editname.setText(nameString); editstudentNo.setText(studNumString); editEmail.setText(emailString); editPassword.setText(passString); nameLabel.setText(nameString); studentNoLabel.setText(studNumString); } @Override public void onCancelled(@NonNull DatabaseError error) { Log.e("DatabaseError", "Error reading from database: " + error.getMessage()); } }); } }
注册用户的Student_sign_up.java代码
public void regUser(){ FirebaseAuth auth = FirebaseAuth.getInstance(); rootNode = FirebaseDatabase.getInstance(); reference = rootNode.getReference("User"); String id = tx.getText().toString().trim(); String txtName = editTextName.getText().toString().trim(); String txtStudNo = editTextStudentNo.getText().toString().trim(); String txtEmail = editTextEmail.getText().toString().trim(); String txtPass = editTextPassword.getText().toString().trim(); String userKey = auth.getUid(); User user = new User(txtName, txtStudNo, txtEmail, txtPass, id); reference.child(userKey).setValue(user).addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { if (task.isSuccessful()) { Toast.makeText(Student_sign_up.this, "User Registered Successfully", Toast.LENGTH_SHORT).show(); progressBar.setVisibility(View.GONE); Intent intent = new Intent(getApplicationContext(), Student_sign_in.class); startActivity(intent); } else { Toast.makeText(Student_sign_up.this, "User Failed to Register", Toast.LENGTH_SHORT).show(); progressBar.setVisibility(View.GONE); } } }); }
问题分析
注册环节UID获取时机错误:
在regUser()方法中,直接调用auth.getUid()时,Firebase Authentication还未完成用户创建流程,此时auth.getUid()返回null。当向Realtime Database写入reference.child(userKey)时,空值会触发Firebase自动生成-NUM格式的push ID,而非Auth的合法UID,导致数据存储路径错误。读取环节路径不匹配:
showAllUserData方法中额外添加了.child(pushKey)路径,但注册时并未将数据存入该子节点,导致读取路径与实际存储路径不一致,无法获取到数据。
修复方案
1. 修正注册逻辑,先创建Auth用户再写入数据库
修改regUser()方法,先通过createUserWithEmailAndPassword完成Auth用户注册,在成功回调中获取合法UID后再写入Realtime Database:
public void regUser(){ FirebaseAuth auth = FirebaseAuth.getInstance(); rootNode = FirebaseDatabase.getInstance(); reference = rootNode.getReference("User"); String id = tx.getText().toString().trim(); String txtName = editTextName.getText().toString().trim(); String txtStudNo = editTextStudentNo.getText().toString().trim(); String txtEmail = editTextEmail.getText().toString().trim(); String txtPass = editTextPassword.getText().toString().trim(); // 先创建Firebase Auth用户 auth.createUserWithEmailAndPassword(txtEmail, txtPass) .addOnCompleteListener(new OnCompleteListener<AuthResult>() { @Override public void onComplete(@NonNull Task<AuthResult> task) { if (task.isSuccessful()) { // 用户创建成功,获取合法UID FirebaseUser firebaseUser = auth.getCurrentUser(); if (firebaseUser != null) { String userKey = firebaseUser.getUid(); User user = new User(txtName, txtStudNo, txtEmail, txtPass, id); // 写入Realtime Database reference.child(userKey).setValue(user).addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> dbTask) { if (dbTask.isSuccessful()) { Toast.makeText(Student_sign_up.this, "User Registered Successfully", Toast.LENGTH_SHORT).show(); progressBar.setVisibility(View.GONE); Intent intent = new Intent(getApplicationContext(), Student_sign_in.class); startActivity(intent); } else { Toast.makeText(Student_sign_up.this, "Failed to save user data", Toast.LENGTH_SHORT).show(); progressBar.setVisibility(View.GONE); } } }); } } else { Toast.makeText(Student_sign_up.this, "User Failed to Register: " + task.getException().getMessage(), Toast.LENGTH_SHORT).show(); progressBar.setVisibility(View.GONE); } } }); }
2. 修正读取数据的路径
移除showAllUserData方法中的.child(pushKey),确保读取路径与存储路径一致:
public void showAllUserData() { // 可移除无用的pushKey参数 FirebaseAuth auth = FirebaseAuth.getInstance(); FirebaseUser user = auth.getCurrentUser(); if (user != null) { String userKey = user.getUid(); ref.child(userKey).addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) { String nameString = dataSnapshot.child("userName").getValue(String.class); String studNumString = dataSnapshot.child("userStudNo").getValue(String.class); String emailString = dataSnapshot.child("userEmail").getValue(String.class); String passString = dataSnapshot.child("userPass").getValue(String.class); editname.setText(nameString); editstudentNo.setText(studNumString); editEmail.setText(emailString); editPassword.setText(passString); nameLabel.setText(nameString); studentNoLabel.setText(studNumString); } @Override public void onCancelled(@NonNull DatabaseError error) { Log.e("DatabaseError", "Error reading from database: " + error.getMessage()); } }); } }
额外注意事项
- 确保Firebase Realtime Database的规则允许已认证用户读写自己的数据,避免权限问题导致的读取失败
- 不要明文存储用户密码,Firebase Auth已经负责密码管理,Realtime Database中无需存储密码字段,避免安全风险
内容的提问来源于stack exchange,提问作者michy
相关产品推荐
相关产品推荐

