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
相关产品推荐
相关产品推荐

