获取 "Failed to bounce to type"
Getting "Failed to bounce to type"
我在使用 firebase
构建 android 聊天应用程序时遇到错误。当我发送消息时没问题,但发送消息后我收到错误消息。错误如下所示。
04-17 15:21:54.242 12961-12961/learning.firebase.app.learningfirebase E/AndroidRuntime: FATAL EXCEPTION: main
com.firebase.client.FirebaseException: Failed to bounce to type
at com.firebase.client.DataSnapshot.getValue(DataSnapshot.java:183)
at learning.firebase.app.learningfirebase.FirebaseListAdapter.onChildAdded(FirebaseListAdapter.java:63)
at com.firebase.client.core.ChildEventRegistration.fireEvent(ChildEventRegistration.java:48)
at com.firebase.client.core.view.DataEvent.fire(DataEvent.java:45)
at com.firebase.client.core.view.EventRaiser.run(EventRaiser.java:38)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:176)
at android.app.ActivityThread.main(ActivityThread.java:5365)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
at dalvik.system.NativeStart.main(Native Method)
Caused by: com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class learning.firebase.app.learningfirebase.Chat]: can not instantiate from JSON object (need to add/enable type information?)
at [Source: java.io.StringReader@42285cd8; line: 1, column: 2]
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:984)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:276)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2888)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2034)
at com.firebase.client.DataSnapshot.getValue(DataSnapshot.java:181)
... 13 more
我的MainActivity.java
public class MainActivity extends ListActivity {
private static final String FIREBASE_URL = "https://bohrachat.firebaseio.com/";
private String mUsername;
private Firebase mFirebaseRef;
private ValueEventListener mConnectedListener;
private ChatListAdapter mChatListAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupUsername();
setTitle("Chatting as " + mUsername);
// Setup our Firebase mFirebaseRef
mFirebaseRef = new Firebase(FIREBASE_URL).child("chat");
// Setup our input methods. Enter key on the keyboard or pushing the send button
EditText inputText = (EditText) findViewById(R.id.messageInput);
inputText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) {
if (actionId == EditorInfo.IME_NULL && keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
sendMessage();
}
return true;
}
});
findViewById(R.id.sendButton).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
sendMessage();
}
});
}
@Override
public void onStart() {
super.onStart();
// Setup our view and list adapter. Ensure it scrolls to the bottom as data changes
final ListView listView = getListView();
// Tell our list adapter that we only want 50 messages at a time
mChatListAdapter = new ChatListAdapter(mFirebaseRef.limit(50), this, R.layout.chat_message, mUsername);
listView.setAdapter(mChatListAdapter);
mChatListAdapter.registerDataSetObserver(new DataSetObserver() {
@Override
public void onChanged() {
super.onChanged();
listView.setSelection(mChatListAdapter.getCount() - 1);
}
});
// Finally, a little indication of connection status
mConnectedListener = mFirebaseRef.getRoot().child(".info/connected").addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
boolean connected = (Boolean) dataSnapshot.getValue();
if (connected) {
Toast.makeText(MainActivity.this, "Connected to Firebase", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "Disconnected from Firebase", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onCancelled(FirebaseError firebaseError) {
// No-op
}
});
}
@Override
public void onStop() {
super.onStop();
mFirebaseRef.getRoot().child(".info/connected").removeEventListener(mConnectedListener);
mChatListAdapter.cleanup();
}
private void setupUsername() {
SharedPreferences prefs = getApplication().getSharedPreferences("ChatPrefs", 0);
mUsername = prefs.getString("username", null);
if (mUsername == null) {
Random r = new Random();
// Assign a random user name if we don't have one saved.
mUsername = "JavaUser" + r.nextInt(100000);
prefs.edit().putString("username", mUsername).commit();
}
}
private void sendMessage() {
EditText inputText = (EditText) findViewById(R.id.messageInput);
String input = inputText.getText().toString();
if (!input.equals("")) {
// Create our 'model', a Chat object
Chat chat = new Chat(input, mUsername,"Today : ");
// Create a new, auto-generated child of that chat location, and save our chat data there
mFirebaseRef.push().setValue(chat);
inputText.setText("");
Bundle b=new Bundle();
b.putString("mUsername",mUsername);
b.putString("mMessage",input);
Intent intent = new Intent();
intent.putExtras(b);
intent.setAction("learning.firebase.app.learningfirebase.CUSTUM_INTENT");
sendBroadcast(intent);
}
}
}
Chat.java
public class Chat {
private String message;
private String author;
private String datetime;
// Required default constructor for Firebase object mapping
@SuppressWarnings("unused")
Chat(String message, String author,String datetime) {
this.message = message;
this.author = author;
this.datetime=datetime;
}
public String getMessage() {
return message;
}
public String getAuthor() {
return author;
}
public String getDatetime() {
return datetime;
}
}
ChatListAdapter.java
public class ChatListAdapter extends FirebaseListAdapter<Chat> {
// The mUsername for this client. We use this to indicate which messages originated from this user
private String mUsername;
public ChatListAdapter(Query ref, Activity activity, int layout, String mUsername) {
super(ref, Chat.class, layout, activity);
this.mUsername = mUsername;
}
/**
* Bind an instance of the <code>Chat</code> class to our view. This method is called by <code>FirebaseListAdapter</code>
* when there is a data change, and we are given an instance of a View that corresponds to the layout that we passed
* to the constructor, as well as a single <code>Chat</code> instance that represents the current data to bind.
*
* @param view A view instance corresponding to the layout we passed to the constructor.
* @param chat An instance representing the current state of a chat message
*/
@Override
protected void populateView(View view, Chat chat) {
// Map a Chat object to an entry in our listview
String author = chat.getAuthor();
TextView authorText = (TextView) view.findViewById(R.id.author);
authorText.setText(author + ": ");
// If the message was sent by this user, color it differently
if (author != null && author.equals(mUsername)) {
authorText.setTextColor(Color.RED);
} else {
authorText.setTextColor(Color.BLUE);
}
((TextView) view.findViewById(R.id.message)).setText(chat.getMessage());
((TextView) view.findViewById(R.id.datetime)).setText(chat.getDatetime());
}
}
我的Firebase
截图
请帮我解决这个问题。我关注 firebase github 聊天项目。在我只添加一个值后,表示日期时间,我得到这个错误。
tl;dr:使 Chat
class 静态并向其添加 parameterless/default 构造函数。
在单个文件中运行的最少代码 (Main.java
):
public class Main {
public static class Chat {
private String message;
private String author;
private String datetime;
// Required default constructor for Firebase object mapping
public Chat() {}
public Chat(String message, String author, String datetime) {
this.message = message;
this.author = author;
this.datetime = datetime;
}
public String getMessage() { return message; }
public String getAuthor() { return author; }
public String getDatetime() { return datetime; }
}
public static void main(String[] args) throws Exception {
Firebase ref = new Firebase("https://Whosebug.firebaseio.com/36675151/-KFaDuobfEA1FLslYZMM");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
public void onDataChange(DataSnapshot dataSnapshot) {
System.out.println(dataSnapshot.getValue(Chat.class));
}
public void onCancelled(FirebaseError error) {
}
});
Thread.sleep(10000);
}
}
JSON数据:
"-KFaDuobfEA1FLslYZMM": {
"author": "user73181",
"datetime": "today heyy",
"message": "xjcjcj"
}
与您的代码不同的地方:
- 我删除了所有与错误消息无关的内容。例如,这是一个 Java 程序,而不是 Android 程序。这个简单的改变消除了数以千计的潜在问题。但是既然你的问题依然存在,说明问题与Android无关。这种隔离问题的方法使查找原因变得容易得多。它通常被称为 minimal, complete/compilable verifiable example.
- 我将所有内容都包含在一个文件中。这不仅使 copy/paste 更容易,还意味着文件之间的交互不能成为原因。在这种情况下,这确实意味着我必须 使
Chat
class 静态 ,这可能是您出现问题的原因之一。
- 我不得不 添加一个 parameterless/default 构造函数 ,这就是 Kato 在 [您之前的问题] 中指出的内容。 (Failed to bounce to type, Chat example error when adding another value,) 以及我告诉您要添加的内容。这可能是您问题的第二个原因。
- 我将 JSON 添加为文本,而不是图像。这意味着您现在可以 copy/paste my JSON 查看您的问题是否源于此(顺便说一句,不是)。您可以通过单击 Firebase 仪表板中的“导出”按钮轻松获取 JSON。这样做让我不必再打字了。
我在使用 firebase
构建 android 聊天应用程序时遇到错误。当我发送消息时没问题,但发送消息后我收到错误消息。错误如下所示。
04-17 15:21:54.242 12961-12961/learning.firebase.app.learningfirebase E/AndroidRuntime: FATAL EXCEPTION: main
com.firebase.client.FirebaseException: Failed to bounce to type
at com.firebase.client.DataSnapshot.getValue(DataSnapshot.java:183)
at learning.firebase.app.learningfirebase.FirebaseListAdapter.onChildAdded(FirebaseListAdapter.java:63)
at com.firebase.client.core.ChildEventRegistration.fireEvent(ChildEventRegistration.java:48)
at com.firebase.client.core.view.DataEvent.fire(DataEvent.java:45)
at com.firebase.client.core.view.EventRaiser.run(EventRaiser.java:38)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:176)
at android.app.ActivityThread.main(ActivityThread.java:5365)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
at dalvik.system.NativeStart.main(Native Method)
Caused by: com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class learning.firebase.app.learningfirebase.Chat]: can not instantiate from JSON object (need to add/enable type information?)
at [Source: java.io.StringReader@42285cd8; line: 1, column: 2]
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:984)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:276)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2888)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2034)
at com.firebase.client.DataSnapshot.getValue(DataSnapshot.java:181)
... 13 more
我的MainActivity.java
public class MainActivity extends ListActivity {
private static final String FIREBASE_URL = "https://bohrachat.firebaseio.com/";
private String mUsername;
private Firebase mFirebaseRef;
private ValueEventListener mConnectedListener;
private ChatListAdapter mChatListAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupUsername();
setTitle("Chatting as " + mUsername);
// Setup our Firebase mFirebaseRef
mFirebaseRef = new Firebase(FIREBASE_URL).child("chat");
// Setup our input methods. Enter key on the keyboard or pushing the send button
EditText inputText = (EditText) findViewById(R.id.messageInput);
inputText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) {
if (actionId == EditorInfo.IME_NULL && keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
sendMessage();
}
return true;
}
});
findViewById(R.id.sendButton).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
sendMessage();
}
});
}
@Override
public void onStart() {
super.onStart();
// Setup our view and list adapter. Ensure it scrolls to the bottom as data changes
final ListView listView = getListView();
// Tell our list adapter that we only want 50 messages at a time
mChatListAdapter = new ChatListAdapter(mFirebaseRef.limit(50), this, R.layout.chat_message, mUsername);
listView.setAdapter(mChatListAdapter);
mChatListAdapter.registerDataSetObserver(new DataSetObserver() {
@Override
public void onChanged() {
super.onChanged();
listView.setSelection(mChatListAdapter.getCount() - 1);
}
});
// Finally, a little indication of connection status
mConnectedListener = mFirebaseRef.getRoot().child(".info/connected").addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
boolean connected = (Boolean) dataSnapshot.getValue();
if (connected) {
Toast.makeText(MainActivity.this, "Connected to Firebase", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "Disconnected from Firebase", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onCancelled(FirebaseError firebaseError) {
// No-op
}
});
}
@Override
public void onStop() {
super.onStop();
mFirebaseRef.getRoot().child(".info/connected").removeEventListener(mConnectedListener);
mChatListAdapter.cleanup();
}
private void setupUsername() {
SharedPreferences prefs = getApplication().getSharedPreferences("ChatPrefs", 0);
mUsername = prefs.getString("username", null);
if (mUsername == null) {
Random r = new Random();
// Assign a random user name if we don't have one saved.
mUsername = "JavaUser" + r.nextInt(100000);
prefs.edit().putString("username", mUsername).commit();
}
}
private void sendMessage() {
EditText inputText = (EditText) findViewById(R.id.messageInput);
String input = inputText.getText().toString();
if (!input.equals("")) {
// Create our 'model', a Chat object
Chat chat = new Chat(input, mUsername,"Today : ");
// Create a new, auto-generated child of that chat location, and save our chat data there
mFirebaseRef.push().setValue(chat);
inputText.setText("");
Bundle b=new Bundle();
b.putString("mUsername",mUsername);
b.putString("mMessage",input);
Intent intent = new Intent();
intent.putExtras(b);
intent.setAction("learning.firebase.app.learningfirebase.CUSTUM_INTENT");
sendBroadcast(intent);
}
}
}
Chat.java
public class Chat {
private String message;
private String author;
private String datetime;
// Required default constructor for Firebase object mapping
@SuppressWarnings("unused")
Chat(String message, String author,String datetime) {
this.message = message;
this.author = author;
this.datetime=datetime;
}
public String getMessage() {
return message;
}
public String getAuthor() {
return author;
}
public String getDatetime() {
return datetime;
}
}
ChatListAdapter.java
public class ChatListAdapter extends FirebaseListAdapter<Chat> {
// The mUsername for this client. We use this to indicate which messages originated from this user
private String mUsername;
public ChatListAdapter(Query ref, Activity activity, int layout, String mUsername) {
super(ref, Chat.class, layout, activity);
this.mUsername = mUsername;
}
/**
* Bind an instance of the <code>Chat</code> class to our view. This method is called by <code>FirebaseListAdapter</code>
* when there is a data change, and we are given an instance of a View that corresponds to the layout that we passed
* to the constructor, as well as a single <code>Chat</code> instance that represents the current data to bind.
*
* @param view A view instance corresponding to the layout we passed to the constructor.
* @param chat An instance representing the current state of a chat message
*/
@Override
protected void populateView(View view, Chat chat) {
// Map a Chat object to an entry in our listview
String author = chat.getAuthor();
TextView authorText = (TextView) view.findViewById(R.id.author);
authorText.setText(author + ": ");
// If the message was sent by this user, color it differently
if (author != null && author.equals(mUsername)) {
authorText.setTextColor(Color.RED);
} else {
authorText.setTextColor(Color.BLUE);
}
((TextView) view.findViewById(R.id.message)).setText(chat.getMessage());
((TextView) view.findViewById(R.id.datetime)).setText(chat.getDatetime());
}
}
我的Firebase
截图
请帮我解决这个问题。我关注 firebase github 聊天项目。在我只添加一个值后,表示日期时间,我得到这个错误。
tl;dr:使 Chat
class 静态并向其添加 parameterless/default 构造函数。
在单个文件中运行的最少代码 (Main.java
):
public class Main {
public static class Chat {
private String message;
private String author;
private String datetime;
// Required default constructor for Firebase object mapping
public Chat() {}
public Chat(String message, String author, String datetime) {
this.message = message;
this.author = author;
this.datetime = datetime;
}
public String getMessage() { return message; }
public String getAuthor() { return author; }
public String getDatetime() { return datetime; }
}
public static void main(String[] args) throws Exception {
Firebase ref = new Firebase("https://Whosebug.firebaseio.com/36675151/-KFaDuobfEA1FLslYZMM");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
public void onDataChange(DataSnapshot dataSnapshot) {
System.out.println(dataSnapshot.getValue(Chat.class));
}
public void onCancelled(FirebaseError error) {
}
});
Thread.sleep(10000);
}
}
JSON数据:
"-KFaDuobfEA1FLslYZMM": {
"author": "user73181",
"datetime": "today heyy",
"message": "xjcjcj"
}
与您的代码不同的地方:
- 我删除了所有与错误消息无关的内容。例如,这是一个 Java 程序,而不是 Android 程序。这个简单的改变消除了数以千计的潜在问题。但是既然你的问题依然存在,说明问题与Android无关。这种隔离问题的方法使查找原因变得容易得多。它通常被称为 minimal, complete/compilable verifiable example.
- 我将所有内容都包含在一个文件中。这不仅使 copy/paste 更容易,还意味着文件之间的交互不能成为原因。在这种情况下,这确实意味着我必须 使
Chat
class 静态 ,这可能是您出现问题的原因之一。 - 我不得不 添加一个 parameterless/default 构造函数 ,这就是 Kato 在 [您之前的问题] 中指出的内容。 (Failed to bounce to type, Chat example error when adding another value,) 以及我告诉您要添加的内容。这可能是您问题的第二个原因。
- 我将 JSON 添加为文本,而不是图像。这意味着您现在可以 copy/paste my JSON 查看您的问题是否源于此(顺便说一句,不是)。您可以通过单击 Firebase 仪表板中的“导出”按钮轻松获取 JSON。这样做让我不必再打字了。