Firebase数据库数据类型转换错误



我正在做一个项目,得到了这个错误:

Fatal Exception: com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.String to type com.example.codechat.InstantMessage
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertBean(CustomClassMapper.java:436)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToClass(CustomClassMapper.java:232)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertToCustomClass(CustomClassMapper.java:80)
at com.google.firebase.database.DataSnapshot.getValue(DataSnapshot.java:203)
at com.example.codechat.CustomAdapter.getItem(CustomAdapter.java:77)
at com.example.codechat.CustomAdapter.getView(CustomAdapter.java:96)
at android.widget.AbsListView.obtainView(AbsListView.java:3073)
at android.widget.ListView.measureHeightOfChildren(ListView.java:1305)
at android.widget.ListView.onMeasure(ListView.java:1212)
at android.view.View.measure(View.java:20236)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:716)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:462)
at android.view.View.measure(View.java:20236)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6333)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at androidx.appcompat.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:146)
at android.view.View.measure(View.java:20236)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6333)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:747)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:629)
at android.view.View.measure(View.java:20236)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6333)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at android.view.View.measure(View.java:20236)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6333)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:747)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:629)
at android.view.View.measure(View.java:20236)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6333)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at com.android.internal.policy.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:3140)
at android.view.View.measure(View.java:20236)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2704)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1656)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1948)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1544)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7607)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
at android.view.Choreographer.doCallbacks(Choreographer.java:686)
at android.view.Choreographer.doFrame(Choreographer.java:622)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7402)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

这是我的自定义适配器:

package com.example.codechat;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import java.util.ArrayList;
public class CustomAdapter extends BaseAdapter {
private Activity myActivity;
private DatabaseReference myDB;
private String username;
private ArrayList<DataSnapshot> dataSnapshots;
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference chatsRef = rootRef.child("Chats");
ValueEventListener valueEventListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
dataSnapshots.add(dataSnapshot);
notifyDataSetChanged();
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {

}
};




public CustomAdapter(Activity activity, DatabaseReference ref, String name){
myActivity = activity;
myDB = ref.child("Chats");
username = name;
dataSnapshots = new ArrayList<>();
myDB.addListenerForSingleValueEvent(valueEventListener);
}
static class ViewHolder{
TextView sender;
TextView message;
LinearLayout.LayoutParams layoutParams;
}
@Override
public int getCount() {
return dataSnapshots.size();
}
@Override
public InstantMessage getItem(int i) {
DataSnapshot snapshot = dataSnapshots.get(i);
return snapshot.getValue(InstantMessage.class);
}
@Override
public long getItemId(int i) {
return 0;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
if(view == null){
LayoutInflater layoutInflater = (LayoutInflater) myActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = layoutInflater.inflate(R.layout.chat_list_view, viewGroup, false);
final ViewHolder viewHolder = new ViewHolder();
viewHolder.sender = view.findViewById(R.id.text);
viewHolder.message = view.findViewById(R.id.textView2);
viewHolder.layoutParams = (LinearLayout.LayoutParams) viewHolder.sender.getLayoutParams();
view.setTag(viewHolder);
}
final InstantMessage message = getItem(i);
final ViewHolder viewHolder = (ViewHolder) view.getTag();
boolean isMe = message.getUser().equals(username);//Error
row_style(isMe, viewHolder);
String messager = message.getMessage();
String author = message.getUser();
viewHolder.sender.setText(author);
viewHolder.message.setText(messager);
return view;
}
private void row_style(boolean ism, ViewHolder hold){
if(ism){
hold.layoutParams.gravity = Gravity.START;
hold.sender.setTextColor(Color.BLUE);
hold.message.setBackgroundResource(R.drawable.speech_bubble_orange);
}else{
hold.layoutParams.gravity = Gravity.END;
hold.sender.setTextColor(Color.BLUE);
hold.message.setBackgroundResource(R.drawable.speech_bubble_green);
}
}
public void confusing(){
myDB.removeEventListener(valueEventListener);
}
}

这是我的聊天活动:

package com.example.codechat;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
public class ChatActivity extends AppCompatActivity {
private String username;
private ListView list;
private EditText text;
private ImageButton james_bond;
private DatabaseReference ethan;
private CustomAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
showDisplay();
ethan = FirebaseDatabase.getInstance().getReference();
list = findViewById(R.id.listView);
text = findViewById(R.id.editTextT);
james_bond = findViewById(R.id.imageButton);
james_bond.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
pushER();
}
});
text.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) {
pushER();
return true;
}
});
}
private void pushER(){
String texT = text.getText().toString();
if(!texT.equals("")){
InstantMessage hobbs = new InstantMessage(username, texT);
ethan.child("Chats").push().setValue(hobbs);
text.setText("");
}
}
private void showDisplay(){
SharedPreferences prefs = getSharedPreferences(RegisterActivity.CHAT_PREF, MODE_PRIVATE);
username = prefs.getString(RegisterActivity.DISPLAY_NAME, null);
if(username ==  null){
username = "guest";
}
}
@Override
protected void onStart() {
super.onStart();
adapter = new CustomAdapter(this, ethan, username);
list.setAdapter(adapter);
}
@Override
protected void onStop() {
super.onStop();
adapter.confusing();
}
}

这是我的InstantMessage类:

package com.example.codechat;
public class InstantMessage{
private String user;
private String message;
public InstantMessage(String l, String k){
user = l;
message = k;
}
public InstantMessage(){
}
public String getMessage() {
return message;
}
public String getUser() {
return user;
}
}

这是我的数据库:

"Chats" : {
"-MG3WxkPWaK-SFh7Q5M_" : "ynnh"
}

我找不到与此错误有关的任何信息。我用了燃烧弹Crashlytics,得到了堆栈的痕迹。语法与其他语法大不相同。当我在editText中键入内容时,它就会崩溃。你能帮我吗?编辑:我有一个新错误:

Fatal Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
at com.example.codechat.CustomAdapter.getView(CustomAdapter.java:88)
at android.widget.AbsListView.obtainView(AbsListView.java:3073)
at android.widget.ListView.measureHeightOfChildren(ListView.java:1305)
at android.widget.ListView.onMeasure(ListView.java:1212)
at android.view.View.measure(View.java:20236)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:716)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:462)
at android.view.View.measure(View.java:20236)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6333)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at androidx.appcompat.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:146)
at android.view.View.measure(View.java:20236)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6333)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:747)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:629)
at android.view.View.measure(View.java:20236)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6333)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at android.view.View.measure(View.java:20236)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6333)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:747)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:629)
at android.view.View.measure(View.java:20236)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6333)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at com.android.internal.policy.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:3140)
at android.view.View.measure(View.java:20236)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2704)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1656)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1948)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1544)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7607)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
at android.view.Choreographer.doCallbacks(Choreographer.java:686)
at android.view.Choreographer.doFrame(Choreographer.java:622)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7402)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

您得到以下错误:

致命异常:com.google.firebase.database.DatabaseException:无法将java.lang.String类型的对象转换为com.example.codechat.InstanceMessage 类型

因为以下代码行:

return snapshot.getValue(InstantMessage.class);

这是因为myDB引用指向的是Chats节点,该节点实际上包含一个String,而不是一个InstantMessage对象。为了使它发挥作用,数据库结构应该如下所示:

Firebase-root
|
--- Chats
|
--- -MG3WxkPWaK-SFh7Q5M_
|
--- user: "Alex"
|
--- message: "Hi, Jandroid!"

因此,正如您所看到的,您不能具有动态属性,您应该具有InstantMessage类中的确切属性,这样您就可以将子级映射到InstantMessage类的对象中。

如果你不想使用POJO类,那么你可以简单地从你的实际结构中获取数据,如下所示:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference chatsRef = rootRef.child("Chats");
ValueEventListener valueEventListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String user = ds.getKey();
String message = ds.getValue(String.class);
Log.d("TAG", user + " / " + message);
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Log.d("TAG", databaseError.getMessage()); //Don't ignore potential errors!
}
};
chatsRef.addListenerForSingleValueEvent(valueEventListener);

你的logcat中的结果将是:

-MG3WxkPWaK-SFh7Q5M_ / ynnh

相关内容

最新更新