Android RecyclerView从Firebase取数报错:无法将String转为UserInformation
Firebase数据绑定RecyclerView时类型转换错误
Can't convert object of type java.lang.String to type com.example.poppy.UserInformation
尝试用RecyclerView从Firebase Database获取数据时,持续触发上述错误,相关代码如下:
Adapter类
public class postAdapter extends RecyclerView.Adapter<MyViewHolder> { Context context; ArrayList<UserInformation> posts; public postAdapter(Context context, ArrayList<UserInformation> posts) { this.context = context; this.posts = posts; } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.card,parent,false)); } @Override public void onBindViewHolder(MyViewHolder holder, int position) { holder.text.setText(posts.get(position).getPost()); } @Override public int getItemCount() { return posts.size(); } }
Model类
public class UserInformation { public String post_text; public String id; public UserInformation(String post_text,String id) { this.post_text = post_text; this.id=id; } //public UserInformation (){} //Getter public String getPost() { return post_text; } public String getId(){return id;} }
NewsFeed类
public class NewsFeedFragment extends Fragment { View root; RecyclerView recyclerView; postAdapter postAdapter; String firebaseAuth; DatabaseReference databaseReference; ArrayList<UserInformation> postsArray; public NewsFeedFragment() { // Required empty public constructor } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment root=inflater.inflate(R.layout.fragment_news_feed, container, false); init(); return root; } private void init() { recyclerView=root.findViewById(R.id.recycler_newsfeed); RecyclerView.LayoutManager layoutManager=new GridLayoutManager(getContext(),1); recyclerView.setLayoutManager(layoutManager); postsArray=new ArrayList<UserInformation>(); postAdapter=new postAdapter(getContext(),postsArray); recyclerView.setAdapter(postAdapter); firebaseAuth=FirebaseAuth.getInstance().getCurrentUser().getUid(); databaseReference= FirebaseDatabase.getInstance().getReference().child("Posts").child(firebaseAuth); databaseReference.addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(DataSnapshot snapshot) { if(snapshot.exists()){ for (DataSnapshot postsnapshot : snapshot.getChildren()){ UserInformation upload = postsnapshot.getValue(UserInformation.class); postsArray.add(upload); recyclerView.invalidate(); } postAdapter.notifyDataSetChanged(); } } @Override public void onCancelled(DatabaseError error) { } }); } }
Firebase JSON结构
{ "Posts": { "SnUFcmk8Llcy7xwWJ5d1fpp47wx2": { "-Nc-G0KCloNLkDBzOauf": "I'm here in my backyard with my Lamborghini ♡", "-Nc-GBc67pArbwZj_bxV": "Hey I'm here coding and it's fun yall ☺" }, "Ym0gl0vBzUV1omI7ncOeU9NdZWU2": { "-Nc5_A1W2dCn5rMGiZsP": "hey yellow" } }, "Users": { "PMJvIPKaEbR0vlgmFlIhvmvCHC92": { "email": "lisa@yahoo.com", "firstname": "Lisa", "lastname": "jim" }, "SnUFcmk8Llcy7xwWJ5d1fpp47wx2": { "email": "ssky33@ymail.com", "firstname": "Sky", "lastname": "star" }, "Ym0gl0vBzUV1omI7ncOeU9NdZWU2": { "email": "jjj@gmail.com", "firstname": "Joan", "lastname": "Lee" } } }
问题原因及修复方案
1. 核心问题:数据结构与Model不匹配
你的Firebase Posts节点下,每个帖子的值是字符串,但代码里试图将其直接转换为UserInformation对象,这必然触发类型转换错误。UserInformation期望的是包含post_text和id的对象结构,而当前Firebase存储的是纯文本。
2. 次要问题:Model缺少无参构造函数
Firebase在反序列化Java对象时,必须依赖无参构造函数,你把UserInformation的无参构造注释掉了,这也会导致反序列化失败。
具体修复步骤:
方案一:调整Firebase数据结构(推荐)
将帖子存储为对象格式,匹配UserInformation的结构:
"SnUFcmk8Llcy7xwWJ5d1fpp47wx2": { "-Nc-G0KCloNLkDBzOauf": { "post_text": "I'm here in my backyard with my Lamborghini ♡", "id": "-Nc-G0KCloNLkDBzOauf" }, "-Nc-GBc67pArbwZj_bxV": { "post_text": "Hey I'm here coding and it's fun yall ☺", "id": "-Nc-GBc67pArbwZj_bxV" } }
同时恢复UserInformation的无参构造:
// 取消注释这行 public UserInformation (){}
方案二:适配现有Firebase结构,修改代码逻辑
如果不想改动Firebase数据,直接读取字符串并手动创建UserInformation对象:
修改onDataChange中的循环逻辑:
for (DataSnapshot postsnapshot : snapshot.getChildren()){ // 直接获取字符串值 String postContent = postsnapshot.getValue(String.class); // 用帖子的key作为id,手动创建对象 UserInformation upload = new UserInformation(postContent, postsnapshot.getKey()); postsArray.add(upload); } postAdapter.notifyDataSetChanged();
同样需要恢复UserInformation的无参构造函数。
额外优化
删除循环内的recyclerView.invalidate(),只需要在循环结束后调用postAdapter.notifyDataSetChanged()即可,后者已经能通知RecyclerView更新数据。
内容的提问来源于stack exchange,提问作者StarGirl
相关产品推荐
相关产品推荐

