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

Android中Firebase数据库按钮点击读取数据失败排查

Firebase Realtime Database 数据读取失败问题分析

问题背景

Firebase数据库结构如下:

{
  "User": {
    "mail@gmail::com": {
      "-NKTbcSqxmB4XImNrpDq": {
        "Q": 0,
        "W": 0,
        "QW": 0,
        "WQ": 0
      }
    },
    "mail@gmail:com": {
      "-NKTbcTUBxMsXYopKMO-": {
        "Q1": 0,
        "W1": 0,
        "QW1": 0,
        "WQ1": 0
      }
    }
  }
}

点击按钮时尝试读取两个用户数据并存入SharedPreferences,但读取失败且无异常输出,原按钮监听代码如下:

btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
database.child("User").child(getMail1).get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
    @Override
    public void onComplete(@NonNull Task<DataSnapshot> task) {
        if (task.isSuccessful()) {
            User value = dataSnapshot.child("User").child(getEmail1).getValue(User.class);
            PreferenceConfig.Q1(getApplicationContext(), Q1);
            PreferenceConfig.W1(getApplicationContext(), W1);
            PreferenceConfig.QW1(getApplicationContext(), QW1);
            PreferenceConfig.WQ1(getApplicationContext(), WQ1);
        }
    });
database.child("User").child(getMail1).get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
    @Override
    public void onComplete(@NonNull Task<DataSnapshot> task) {
        if (task.isSuccessful()) {
            User value = dataSnapshot.child("User").child(getEmail).getValue(User.class);
            PreferenceConfig.Q(getApplicationContext(), Q);
            PreferenceConfig.W(getApplicationContext(), W);
            PreferenceConfig.QW(getApplicationContext(), QW);
            PreferenceConfig.WQ(getApplicationContext(), WQ);
        }
    });
});

核心错误点

  • 未从Task中获取DataSnapshot实例:原代码直接使用dataSnapshot变量,但该变量未通过task.getResult()获取,属于未定义变量,实际运行时会引发错误
  • 节点路径重复定位:第一个请求已经通过database.child("User").child(getMail1)定位到用户节点,后续无需再通过dataSnapshot.child("User").child(getEmail1)重复查找,路径层级错误
  • 第二个请求节点路径错误:第二个请求错误使用getMail1作为子节点,应该使用getEmail
  • 数据解析层级错误:用户节点下还有一层随机生成的key(如-NKTbcSqxmB4XImNrpDq),直接用User.class解析会失败,需要先获取该子节点的数据
  • 未从解析对象中取值:保存SharedPreferences时直接使用Q1、W1等未定义变量,未从解析后的对象中提取对应字段值

修正后的代码

btn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        // 读取第一个用户数据
        database.child("User").child(getEmail1).get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
            @Override
            public void onComplete(@NonNull Task<DataSnapshot> task) {
                if (task.isSuccessful()) {
                    DataSnapshot dataSnapshot = task.getResult();
                    // 遍历随机key子节点
                    for (DataSnapshot childSnapshot : dataSnapshot.getChildren()) {
                        User user = childSnapshot.getValue(User.class);
                        if (user != null) {
                            // 保存到SharedPreferences
                            PreferenceConfig.Q(getApplicationContext(), user.getQ());
                            PreferenceConfig.W(getApplicationContext(), user.getW());
                            PreferenceConfig.QW(getApplicationContext(), user.getQW());
                            PreferenceConfig.WQ(getApplicationContext(), user.getWQ());
                        }
                    }
                } else {
                    Log.e("TaskError", "读取第一个用户失败: " + task.getException());
                }
            }
        });

        // 读取第二个用户数据
        database.child("User").child(getEmail).get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
            @Override
            public void onComplete(@NonNull Task<DataSnapshot> task) {
                if (task.isSuccessful()) {
                    DataSnapshot dataSnapshot = task.getResult();
                    // 遍历随机key子节点
                    for (DataSnapshot childSnapshot : dataSnapshot.getChildren()) {
                        User1 user1 = childSnapshot.getValue(User1.class);
                        if (user1 != null) {
                            // 保存到SharedPreferences
                            PreferenceConfig.Q1(getApplicationContext(), user1.getQ1());
                            PreferenceConfig.W1(getApplicationContext(), user1.getW1());
                            PreferenceConfig.QW1(getApplicationContext(), user1.getQW1());
                            PreferenceConfig.WQ1(getApplicationContext(), user1.getWQ1());
                        }
                    }
                } else {
                    Log.e("TaskError", "读取第二个用户失败: " + task.getException());
                }
            }
        });
    }
});

配套实体类说明

需要对应两个用户的数据结构创建实体类:

// 对应mail@gmail::com节点下的数据结构
public class User {
    private int Q;
    private int W;
    private int QW;
    private int WQ;

    // Firebase解析必须的无参构造函数
    public User() {}

    // getter方法
    public int getQ() { return Q; }
    public int getW() { return W; }
    public int getQW() { return QW; }
    public int getWQ() { return WQ; }
}

// 对应mail@gmail:com节点下的数据结构
public class User1 {
    private int Q1;
    private int W1;
    private int QW1;
    private int WQ1;

    // Firebase解析必须的无参构造函数
    public User1() {}

    // getter方法
    public int getQ1() { return Q1; }
    public int getW1() { return W1; }
    public int getQW1() { return QW1; }
    public int getWQ1() { return WQ1; }
}

额外说明

  • Firebase Realtime Database实体类必须包含无参构造函数,否则Gson无法完成解析
  • 如果随机key是唯一的,也可以通过dataSnapshot.getChildren().iterator().next()直接获取第一个子节点,无需遍历
  • 建议添加失败回调的日志输出,方便排查问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 23:45:29