无法从Firebase的User库获取学生信息并存储至StoreInfo库求助
Firebase获取用户字段为null的修复方案
核心问题分析
你的代码主要存在数据库路径错误、异步操作时序问题、字段名不匹配这几个关键问题,导致无法正确获取用户数据。以下是针对性修复步骤:
1. 修复数据库引用路径(最关键)
你当前直接读取User根节点,而Firebase用户数据通常存储在User/{用户UID}路径下,未指定UID导致读取的是整个节点的根,自然找不到userName和userStudNum字段。
修复代码(在两个类的saveUser方法中修改):
private void saveUser() { FirebaseAuth auth = FirebaseAuth.getInstance(); FirebaseUser user = auth.getCurrentUser(); // 先判断用户是否登录 if (user == null) { Toast.makeText(this, "用户未登录", Toast.LENGTH_SHORT).show(); return; } // 加上当前用户UID,定位到具体用户的节点 DatabaseReference ref = FirebaseDatabase.getInstance().getReference("User").child(user.getUid()); ref.addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) { // 确认数据库字段名和代码一致,此处假设数据库字段是userStudNum String nameString = dataSnapshot.child("userName").getValue(String.class); String studNumString = dataSnapshot.child("userStudNum").getValue(String.class); name.setText("" + nameString); studNum.setText("" + studNumString); } @Override public void onCancelled(@NonNull DatabaseError databaseError) { // 添加错误提示,方便调试 Log.e("Firebase", "获取用户信息失败: " + databaseError.getMessage()); Toast.makeText(scanner.this, "获取用户信息失败", Toast.LENGTH_SHORT).show(); } }); }
2. 修正字段名不匹配
你需求中要获取的是userStudNum,但代码里写的是userStudNo,如果数据库字段是userStudNum,必须把代码中的userStudNo替换成userStudNum,否则会返回null。
3. 解决异步操作时序问题
在qrscanner的handleResult方法中,你调用saveUser()后立刻读取静态TextView的值,但Firebase数据获取是异步的,此时TextView还未被赋值,拿到的还是空值。
修复方法:把存储StoreInfo的逻辑放到saveUser的回调里,确保数据获取完成后再执行存储:
@Override public void handleResult(Result result) { String data = result.getText().toString(); Date dateAndTime = Calendar.getInstance().getTime(); SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy", Locale.getDefault()); SimpleDateFormat timeFormat = new SimpleDateFormat("hh:mm:ss", Locale.getDefault()); String date = dateFormat.format(dateAndTime); String time = timeFormat.format(dateAndTime); String deviceId = Settings.Secure.getString(this.getContentResolver(), Settings.Secure.ANDROID_ID); getLocation(); // 把存储需要的参数传给saveUser saveUser(data, date, time, deviceId); } private void saveUser(String data, String date, String time, String deviceId) { FirebaseAuth auth = FirebaseAuth.getInstance(); FirebaseUser user = auth.getCurrentUser(); if (user == null) { Toast.makeText(this, "用户未登录", Toast.LENGTH_SHORT).show(); onBackPressed(); return; } DatabaseReference ref = FirebaseDatabase.getInstance().getReference("User").child(user.getUid()); ref.addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) { String nameString = dataSnapshot.child("userName").getValue(String.class); String studNumString = dataSnapshot.child("userStudNum").getValue(String.class); // 检查字段是否为空 if (nameString == null || studNumString == null) { Toast.makeText(qrscanner.this, "用户信息不完整", Toast.LENGTH_SHORT).show(); onBackPressed(); return; } String locationString = scanner.address.getText().toString(); StoreInfo storeInfo = new StoreInfo(data, date, time, deviceId, locationString, nameString, studNumString); dbref.push().setValue(storeInfo).addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { if (task.isSuccessful()) { scanner.qrtext.setText("Course: " + data); scanner.date.setText("Date: " + date); scanner.arrival.setText("Arrival time: " + time); scanner.id.setText("Device Id: " + deviceId); scanner.address.setText("Location: " + locationString); scanner.name.setText("Name: " + nameString); scanner.studNum.setText("Student Number: " + studNumString); } else { Toast.makeText(qrscanner.this, "存储失败", Toast.LENGTH_SHORT).show(); } onBackPressed(); } }); } @Override public void onCancelled(@NonNull DatabaseError databaseError) { Log.e("Firebase", "获取用户信息失败: " + databaseError.getMessage()); Toast.makeText(qrscanner.this, "获取用户信息失败", Toast.LENGTH_SHORT).show(); onBackPressed(); } }); }
4. 优化静态TextView的使用(可选)
用静态TextView传递数据容易引发内存泄漏,建议改用SharedPreferences存储用户信息:
- 在
scanner的saveUser回调中存储:
SharedPreferences sp = getSharedPreferences("UserInfo", MODE_PRIVATE); sp.edit() .putString("userName", nameString) .putString("userStudNum", studNumString) .apply();
- 在
qrscanner中直接读取:
SharedPreferences sp = getSharedPreferences("UserInfo", MODE_PRIVATE); String nameString = sp.getString("userName", ""); String studNumString = sp.getString("userStudNum", "");
内容的提问来源于stack exchange,提问作者michy
相关产品推荐
相关产品推荐

