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

huangapple go评论74阅读模式
英文:

Firebase database data type conversion error

问题

以下是翻译好的内容:

在进行一个项目时遇到了这个错误:

    致命异常: com.google.firebase.database.DatabaseException: 无法将 java.lang.String 类型的对象转换为 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 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

这是我的自定义适配器 CustomAdapter:

    // 代码省略

这是我的 ChatActivity:

    // 代码省略

这是我的 InstantMessage 类:

    // 代码省略

这是我的数据库:

    // 代码省略

我找不到与此错误相关的任何信息。
我使用了 Firebase Crashlytics 并获取了堆栈跟踪。
语法与其他部分相比非常不同。
我一键输入一些内容时,应用就会崩溃。
你能帮助我吗?
编辑:
我得到了一个新的错误:

    致命异常: java.lang.NullPointerException: 尝试在空对象引用上调用虚拟方法 'boolean java.lang.String.equals(java.lang.Object)'
           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 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

请注意,由于您要求只返回翻译后的部分,因此我只提供了您所提供的内容的翻译,没有其他的内容。

英文:

I was doing a project and got this error:

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)

This my custom adapter:

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);
    }

}

This is my ChatActivity:

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();
    }

}

This is my InstantMessage class:

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;
   }
}

this is my database:

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

I could not find anything related to this error.
I used firebase Crashlytics and got the stack trace.
The syntax is quite different from the others.
The moment I type something in the editText it crashes.
Can you help me?
Edit:
I got a new error:

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)

答案1

得分: 0

你遇到了以下错误:

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

这是因为以下代码行:

return snapshot.getValue(InstantMessage.class);

而这是因为你的myDB引用指向实际包含字符串而不是InstantMessage对象的Chats节点。要使其工作,数据库结构应如下所示:

Firebase根目录
  |
  --- 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()); //不要忽略潜在错误!
	}
};
chatsRef.addListenerForSingleValueEvent(valueEventListener);

你在logcat中的结果将会是:

-MG3WxkPWaK-SFh7Q5M_ / ynnh
英文:

You are getting the following error:

> Fatal Exception: com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.String to type com.example.codechat.InstantMessage

Because of the following line of code:

return snapshot.getValue(InstantMessage.class);

And this is because your myDB reference points to the Chats node that actually contains a String and not an InstantMessage object. To make it work, the database structure should look like this:

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

So as you can see you can't have dynamic properties, you should have the exact properties that you have in your InstantMessage class, so you can map a child right into an object of your InstantMessage class.

If you don't want to use a POJO class, then you can simply get the data from your actual structure like this:

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);

And the result in your logcat will be:

-MG3WxkPWaK-SFh7Q5M_ / ynnh

huangapple
  • 本文由 发表于 2020年8月31日 21:20:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/63671630.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定