英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论