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

Firebase数据库类型转换异常求助:String转Results失败

解决Firebase数据库String转Results的类型转换异常

我来帮你分析下这个问题哈,你遇到的Can't convert object of type java.lang.String to type com.appmaster.akash.messageplus.Results异常,核心原因是数据库里的结构和你读取数据时期望的Results实体类结构不匹配。

先理清楚矛盾点:

  • 你保存数据时,用HashMap直接把<用户名, 分数>的键值对存到了Results节点下,导致数据库里Results的子项是一个个字符串(分数值),对应的key是用户名。
  • 但读取时,你却尝试把每个子项直接转换成Results对象——这显然行不通,因为子项本身就是String类型,不是包含Name和Score字段的对象。

下面给你两种可行的解决方案,你可以根据业务需求选择:

方案一:调整读取逻辑,适配当前数据库结构

既然数据库里Results节点是<用户名: 分数>的键值对,那读取时直接获取每个子节点的key(用户名)和value(分数),手动构建Results对象即可:

修改你的fetchResults()方法:

private void fetchResults() {
    mDatabaseReference.child("Users").child(id).child("Quiz").child("Results")
        .addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                // 获取子节点的key作为用户名,value作为分数
                String userName = dataSnapshot.getKey();
                String score = dataSnapshot.getValue(String.class);
                // 手动创建Results对象并加入列表
                Results results = new Results(userName, score);
                resultsList.add(results);
                mAdapter.notifyDataSetChanged();
            }

            @Override
            public void onChildChanged(DataSnapshot dataSnapshot, String s) {}
            @Override
            public void onChildRemoved(DataSnapshot dataSnapshot) {}
            @Override
            public void onChildMoved(DataSnapshot dataSnapshot, String s) {}
            @Override
            public void onCancelled(DatabaseError databaseError) {
                throw databaseError.toException();
            }
        });
}

方案二:调整保存逻辑,让数据库结构匹配Results实体类

如果希望数据库结构更规范(方便后续扩展,比如添加答题时间等字段),可以修改保存代码,把每个结果作为独立的Results对象存储:

修改数据保存代码:

String name = RecieversName;
Results result = new Results(name, String.valueOf(mScore));
// 用push()生成唯一ID,将每个Results对象作为独立子节点存入
mRef.child("Users").child(RecieversId).child("Quiz").child("Results")
    .push()
    .setValue(result)
    .addOnCompleteListener(new OnCompleteListener<Void>() {
        @Override
        public void onComplete(@NonNull Task<Void> task) {
            if (task.isSuccessful()) {
                Intent intent = new Intent(TakingQuiz.this, TakingQuizDone.class);
                intent.putExtra("RecieversId",RecieversId);
                intent.putExtra("Score", mScore.toString());
                startActivity(intent);
                finish();
            }
        }
    });

这样修改后,数据库里的Results节点下会是多个带唯一ID的子节点,每个子节点都包含Name和Score字段,这时候你原来的fetchResults()代码就能正常工作了,因为每个子节点的结构完全匹配Results类。

总结

  • 方案一更适合当前已有的数据库结构,不需要修改历史数据;
  • 方案二更符合Firebase的推荐数据结构,扩展性更强,适合长期维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:13:02