Android Studio Firebase登录后无法显示自身Realtime Database数据求助
问题排查与解决方案
从你的代码和安全规则来看,登录后无数据展示的核心问题是查询路径与Firebase权限规则不匹配,再加上可能的数据结构适配问题,下面一步步帮你解决:
1. 核心问题:查询请求被安全规则拦截
你的Firebase规则设置为仅允许用户读取自己的users/$uid子节点:
{ "rules": { "users": { "$uid": { ".read": "auth != null && auth.uid == $uid" } } } }
但代码中却直接查询整个users根节点:
options = new FirebaseRecyclerOptions.Builder<Post>() .setQuery(databaseReference,Post.class) // 查询的是users根节点,无权限访问 .build();
Firebase会直接拒绝这个查询请求——用户没有读取整个users节点的权限,只能访问自己的$uid子节点,自然不会返回任何数据。
2. 快速修复:调整查询路径到当前用户节点
修改displayComment方法中的查询逻辑,让它指向当前用户的UID子节点:
private void displayComment() { // 调整查询路径,精准指向当前用户的专属节点 options = new FirebaseRecyclerOptions.Builder<Post>() .setQuery(databaseReference.child(uid_number), Post.class) .build(); adapter = new FirebaseRecyclerAdapter<Post, MyRecyclerViewHolder>(options) { @Override protected void onBindViewHolder(@NonNull MyRecyclerViewHolder holder, int position, @NonNull Post model) { holder.txt_name.setText(model.getName()); holder.txt_email.setText(model.getEmail()); } @NonNull @Override public MyRecyclerViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { View itemView = LayoutInflater.from(getBaseContext()).inflate(R.layout.post_item,viewGroup,false); return new MyRecyclerViewHolder(itemView); } // 新增错误监听,方便排查问题 @Override public void onError(@NonNull DatabaseError error) { super.onError(error); Log.e("FirebaseError", "数据加载失败: " + error.getMessage()); } }; adapter.startListening(); recyclerView.setAdapter(adapter); }
3. 额外优化:单条数据无需使用RecyclerView
因为每个用户只有一条个人数据,用RecyclerView展示单条数据有点大材小用,你可以改用ValueEventListener直接查询,代码更简洁高效:
步骤1:布局中添加显示数据的TextView
在activity_main.xml里添加两个TextView:
<TextView android:id="@+id/tv_user_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="18sp"/> <TextView android:id="@+id/tv_user_email" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="16sp" android:layout_marginTop="8dp"/>
步骤2:替换原displayComment方法为loadUserData
private void loadUserData() { databaseReference.child(uid_number).addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { if (snapshot.exists()) { // 解析数据库数据到Post对象 Post userData = snapshot.getValue(Post.class); // 显示数据到TextView TextView tvName = findViewById(R.id.tv_user_name); TextView tvEmail = findViewById(R.id.tv_user_email); assert userData != null; tvName.setText(userData.getName()); tvEmail.setText(userData.getEmail()); } else { Toast.makeText(Documentation.this, "未找到你的个人数据", Toast.LENGTH_SHORT).show(); } } @Override public void onCancelled(@NonNull DatabaseError error) { // 打印错误日志,方便排查问题 Log.e("FirebaseError", "读取数据失败: " + error.getMessage()); Toast.makeText(Documentation.this, "数据加载失败,请检查网络", Toast.LENGTH_SHORT).show(); } }); }
步骤3:在onCreate中调用loadUserData
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); firebaseDatabase=FirebaseDatabase.getInstance(); databaseReference=firebaseDatabase.getReference("users"); user= FirebaseAuth.getInstance().getCurrentUser(); assert user != null; uid_number=user.getUid(); // 替换原displayComment调用 loadUserData(); }
4. 必查验证项
- Post类结构:必须包含无参构造函数和对应的getter方法(Firebase序列化要求):
public class Post { private String name; private String email; // 必须有无参构造函数,否则Firebase无法解析数据 public Post() {} // 可选:带参构造函数,用于写入数据 public Post(String name, String email) { this.name = name; this.email = email; } // getter方法必须存在,用于读取数据 public String getName() { return name; } public String getEmail() { return email; } // 可选:setter方法,如需写入数据则添加 public void setName(String name) { this.name = name; } public void setEmail(String email) { this.email = email; } } - 数据库结构:确保你的Realtime Database是按UID分类存储的:
users |-- 你的用户UID |-- name: "张三" |-- email: "hi@gmail.com"
内容的提问来源于stack exchange,提问作者Núria Martín Xifré
相关产品推荐
相关产品推荐

