You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确获取DatabaseReference并在用户资料中显示子节点

解决Firebase Database获取用户资料节点及展示问题

核心问题分析

从你的代码和数据库截图来看,存在两个关键不匹配点:

  1. 节点路径不匹配:你用firebaseUser.getUid()作为Users下的子节点键,但数据库中Users下的节点是用户邮箱(如xxx@gmail.com),导致无法定位到正确的用户数据。
  2. 字段名大小写不匹配:数据库中存储的字段是Birthday、Discount(首字母大写),但ReadWriteUserDetails类里是birthday、discount(全小写),Firebase自动映射大小写敏感,会导致数据解析失败。

解决方案

方案1:适配现有数据库结构(用邮箱作为节点键)

Firebase路径不允许包含@和.,所以存储时通常会转义这些字符(比如@替换为%40,.替换为%2E),修改代码如下:

private void showUserProfile(FirebaseUser firebaseUser) {
    String userEmail = firebaseUser.getEmail();
    // 按存储时的规则转义邮箱特殊字符
    String escapedEmail = userEmail.replace(".", "%2E").replace("@", "%40");

    DatabaseReference referenceProfile = FirebaseDatabase.getInstance().getReference("Users");
    referenceProfile.child(escapedEmail).addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            if (snapshot.exists()) { // 先判断节点是否存在
                ReadWriteUserDetails readUserDetail = snapshot.getValue(ReadWriteUserDetails.class);
                if (readUserDetail != null) {
                    fullname = firebaseUser.getDisplayName();
                    email = firebaseUser.getEmail();
                    doB = readUserDetail.birthday;
                    discount = readUserDetail.discount;

                    textViewFullName.setText(fullname);
                    textViewEmail.setText(email);
                    textViewDoB.setText(doB);
                    textViewDiscount.setText(discount);
                }
            } else {
                Log.d("Profile", "用户数据不存在");
            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError error) {
            // 必须实现该方法捕获数据库访问错误
            Log.e("Profile", "数据库读取失败: " + error.getMessage());
        }
    });
}

同时修正实体类的字段映射,用注解匹配数据库字段名:

import com.google.firebase.database.PropertyName;

public class ReadWriteUserDetails {
    @PropertyName("Birthday")
    public String birthday;
    @PropertyName("Discount")
    public String discount;

    public ReadWriteUserDetails(){};

    public ReadWriteUserDetails(String textBirthday, String textDiscount){
        this.birthday = textBirthday;
        this.discount = textDiscount;
    }
}

方案2:改用UID作为节点键(推荐规范做法)

邮箱可能被用户修改,而UID是Firebase用户的唯一永久标识,更适合作为节点键:

  1. 调整数据存储逻辑,将用户数据存到Users/{UID}路径下。
  2. 保留你原始代码的节点路径部分,仅修正字段名映射(同上方案的实体类修改),并完善错误处理逻辑即可。

调试建议

  • 在onDataChange中打印snapshot.toString(),查看获取到的原始数据,确认是否定位到正确节点。
  • 检查Firebase数据库规则,确保当前用户有Users节点的读取权限(比如设置规则:"Users": { ".read": "auth != null" })。

内容的提问来源于stack exchange,提问作者Chichi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 21:15:31