Firebase无法获取当前用户数据问题求助(MyAccount Fragment)
解决Firebase获取用户数据返回Null的问题
我来帮你排查下问题哈,你遇到的null值问题主要是数据存储路径和读取路径不匹配,加上没有关联Firebase用户UID导致的,咱们一步步来解决:
问题根源分析
- 数据存储时未关联用户UID:你插入数据用了
push(),这会在data节点下生成随机ID的子节点,但没有和当前登录用户的UID绑定,导致后续无法通过UID精准定位到当前用户的数据。 - 读取数据的路径错误:你直接读取整个
data节点的value并转成Map,但data下是多个随机ID的子节点,不是单个用户的键值对,自然拿不到有效数据。 - 类型转换风险:直接把
DataSnapshot转成Map<String, String>容易出错,不如直接用Firebase的对象映射功能转成User2实体类。
解决方案步骤
第一步:修改数据插入代码,关联用户UID
把原来用push()存储数据的逻辑,改成用当前登录用户的UID作为节点名,这样每个用户的数据都存在data/{uid}路径下:
// 在注册按钮的点击事件里,先获取当前登录用户的UID FirebaseUser currentUser = FirebaseAuth.getInstance().getCurrentUser(); if (currentUser != null) { String uid = currentUser.getUid(); // 替换原来的push(),用UID作为子节点 mDatabase.child("data").child(uid).setValue(user2); startActivity(new Intent(Main5Activity.this, Main8navigation.class)); flag = 1; break; } else { // 处理用户未登录的情况(注册流程里应该先完成登录?这里根据你的业务调整) Toast.makeText(getApplicationContext(), "请先完成登录", Toast.LENGTH_LONG).show(); }
第二步:修改MyAccountFragment的读取逻辑,精准获取当前用户数据
调整读取数据的路径,直接指向data/{当前用户UID},并通过Firebase的对象映射功能把数据转成User2对象:
public class MyAccountFragment extends Fragment { private static final String TAG = "MyAccountFragment"; DatabaseReference ref; FirebaseAuth auth; FirebaseUser user; Toolbar toolbar; @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_myaccount, container, false); toolbar = view.findViewById(R.id.toolbar); // 初始化TextView TextView acc_name = view.findViewById(R.id.acc_name); TextView acc_mobile = view.findViewById(R.id.acc_mobile); TextView acc_email = view.findViewById(R.id.acc_email); TextView acc_dob = view.findViewById(R.id.acc_dob); TextView acc_gender = view.findViewById(R.id.acc_gender); TextView acc_city = view.findViewById(R.id.acc_city); TextView acc_state = view.findViewById(R.id.acc_state); TextView acc_sml = view.findViewById(R.id.acc_sml); TextView acc_syp = view.findViewById(R.id.acc_syp); TextView acc_aadhar_no = view.findViewById(R.id.acc_aadhar_no); // 初始化Firebase Auth和当前用户 auth = FirebaseAuth.getInstance(); user = auth.getCurrentUser(); if (user != null) { String uid = user.getUid(); Log.i(TAG,"Uid :"+uid); // 直接指向当前用户的数据节点 ref = FirebaseDatabase.getInstance().getReference("data").child(uid); ref.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) { // 把DataSnapshot转成User2对象,自动映射字段 User2 user2 = dataSnapshot.getValue(User2.class); if (user2 != null) { // 获取字段值(注意User2类的字段名要和数据库存储的完全一致) String name = user2.name1; String email = user2.emailid1; String phone = user2.phone1; String gender = user2.gender2; String dob = user2.dob1; String state = user2.state1; // 其他字段同理 Log.v("E_VALUE","Name:"+name); Log.v("E_VALUE","Email:"+email); Log.v("E_VALUE","Phone:"+phone); Log.v("E_VALUE","Gender:"+gender); // 设置到TextView上 acc_name.setText(name); acc_email.setText(email); acc_mobile.setText(phone); acc_gender.setText(gender); acc_dob.setText(dob); acc_state.setText(state); // 其他TextView依次设置 } else { Log.v("E_VALUE", "未找到当前用户的数据"); } } @Override public void onCancelled(@NonNull DatabaseError databaseError) { Log.e(TAG,"数据库错误: " + databaseError.getMessage()); } }); } else { Log.v("E_VALUE", "用户未登录,请先登录"); // 这里可以跳转到登录页面,比如: // startActivity(new Intent(getActivity(), LoginActivity.class)); } return view; } }
第三步:检查数据库规则(重要)
确保Firebase数据库的规则允许认证用户读取自己的数据,测试阶段可以暂时开放,上线后要严格限制:
// 测试用规则(开放读写,上线后替换) { "rules": { ".read": true, ".write": true } } // 上线用规则(仅允许认证用户读写自己的数据) { "rules": { "data": { "$uid": { ".read": "$uid === auth.uid", ".write": "$uid === auth.uid" } } } }
额外注意事项
- User2类字段名要和数据库一致:比如你User2里的性别字段是
gender2,那么数据库里存储的键也是gender2,读取的时候要对应,不能写错。 - 处理用户未登录的情况:在Fragment里要判断
user != null,避免空指针异常。 - 移除无用代码:你原来的
super.onCreate(savedInstanceState);放在onCreateView里是错误的,Fragment的onCreate是另一个生命周期方法,这里不需要调用。
内容的提问来源于stack exchange,提问作者Mahima Awasthi
相关产品推荐
相关产品推荐

