在DataSnapshot.getValue()时间戳Android的聊天崩溃时间、DataSnapshot、getValue、Android

2023-09-04 03:08:10 作者:无名份的浪漫

我试图修改火力地堡的Andr​​oid聊天的例子包括火力地堡时间戳值。我可以送就好了使用 ServerValue.TIMESTAMP时间戳; 但是当火力地堡试图以显示消息,该应用程序崩溃。编辑:下面满错误输出

要发送消息我用

 私人无效的sendMessage(){
    EditText上的inputText =(EditText上)findViewById(R.id.messageInput);
    字符串输入= inputText.getText()的toString()。
    地图时间戳= ServerValue.TIMESTAMP;

    如果(!input.equals()){
        //创建我们的模式,一个聊天对象
        聊天=新的聊天(姓名,输入,时间戳,用户ID);
        //创建的那个聊天的位置一个新的,自动生成的孩子,救救我们聊天数据存在
        chatRef.push()的setValue(聊天)。
        inputText.setText();
    }
}
 

伪造的结构是这样的:

   - >信使
  |  - >房间
      |  - >信息
        |  - > MESSAGEID
          |  - >从名
          |  - >文字:消息
          |  - >时间戳:XXXXXXXXXXXXX
          |  - >用户ID:ID
 
时间数据处理丨周期和周期运算

和Chat.java

 公共类聊天{

    私人字符串;
    私人字符串文本;
    私人诠释用户ID;
    私人地图<字符串,字符串>时间戳=新的HashMap<字符串,字符串>();

    //必需的默认构造函数的火力地堡对象映射
    @燮pressWarnings(未使用)
    私人聊天(){}

    聊天(从,字符串文字,地图时间戳,INT用户ID字符串){
        this.from =距离;
        this.text =文本;
        this.timestamp =时间戳;
        this.userID =用户ID;
    }

    公共字符串GETFROM(){
        从回报;
    }

    公共字符串的getText(){
        返回文本;
    }

    公共地图getTimestamp(){
        返回时间戳;
    }

    公众诠释getuserID(){
        返回用户ID;
    }
}
 

如果我从火力地堡邮件删除时间戳字段,应用程序不会崩溃。

完整的错误消息如下:

  08-26 15:08:08.223 18097-18097 / com.firebase.androidchat E / AndroidRuntime:致命异常:主要
    工艺:com.firebase.androidchat,PID:18097
    com.firebase.client.FirebaseException:未能反弹打字
            在com.firebase.client.DataSnapshot.getValue(DataSnapshot.java:185)
            在com.firebase.androidchat.FirebaseListAdapter $ 1.onChildAdded(FirebaseListAdapter.java:63)
            在com.firebase.client.core.ChildListenerContainer $ 1.运行(ChildListenerContainer.java:52)
            在android.os.Handler.handleCallback(Handler.java:733)
            在android.os.Handler.dispatchMessage(Handler.java:95)
            在android.os.Looper.loop(Looper.java:136)
            在android.app.ActivityThread.main(ActivityThread.java:5001)
            在java.lang.reflect.Method.invokeNative(本机方法)
            在java.lang.reflect.Method.invoke(Method.java:515)
            在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:785)
            在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
            在dalvik.system.NativeStart.main(本机方法)
     致:com.shaded.fasterxml.jackson.databind.JsonMappingException:无法反序列化java.util.LinkedHashMap中的实例出来VALUE_NUMBER_INT令牌
            在[来源:java.io.StringReader@41f8c588;行:1列:2](通过参考链:com.firebase.androidchat.Chat [时间戳])
            在com.shaded.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:575)
            在com.shaded.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:569)
            在com.shaded.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:310)
            在com.shaded.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:26)
            在com.shaded.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:464)
            在com.shaded.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:107)
            在com.shaded.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:295)
            在com.shaded.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121)
            在com.shaded.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2888)
            在com.shaded.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2034)
            在com.firebase.client.DataSnapshot.getValue(DataSnapshot.java:181)
在com.firebase.androidchat.FirebaseListAdapter $ 1.onChildAdded(FirebaseListAdapter.java:63)
在com.firebase.client.core.ChildListenerContainer $ 1.运行(ChildListenerContainer.java:52)
在android.os.Handler.handleCallback(Handler.java:733)
在android.os.Handler.dispatchMessage(Handler.java:95)
在android.os.Looper.loop(Looper.java:136)
在android.app.ActivityThread.main(ActivityThread.java:5001)
在java.lang.reflect.Method.invokeNative(本机方法)
在java.lang.reflect.Method.invoke(Method.java:515)
在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:785)
在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
在dalvik.system.NativeStart.main(本机方法)
 

它看起来像可以通过另一个问题,它混淆了我更加引起...

 产生的原因:com.shaded.fasterxml.jackson.databind.JsonMappingException:无法反序列化java.util.LinkedHashMap中的实例出来VALUE_NUMBER_INT令牌
        在[来源:java.io.StringReader@41f8c588;行:1列:2](通过参考链:com.firebase.androidchat.Chat [时间戳])
 

解决方案

Firebase.ServerValue.TIMESTAMP 设置为一个Map(含 {。 SV:时间戳} ),它告诉火力地堡来填充该字段与服务器的时间。当数据被读回,它是实际的Unix时间戳这是一个。当火力地堡(使用杰克逊)试图反序列化返回的值,它失败,因为它不是一个地图

您可以使用杰克逊注释来控制您的类转换成JSON。

例如,这样的事情应该工作:

 进口com.fasterxml.jackson.annotation.JsonIgnore;
进口com.firebase.client.ServerValue;

公共类的事{
    私人字符串ID;
    私人龙creationDate;

    公共事(){

    }

    公共物(字符串ID){
        this.id = ID;
    }

    公共字符串的getId(){
        返回ID;
    }

    公众的java.util.Map<字符串,字符串> getCreationDate(){
        返回ServerValue.TIMESTAMP;
    }

    @JsonIgnore
    众长getCreationDateLong(){
       返回creationDate;
    }

    公共无效SETID(字符串ID){
        this.id = ID;
    }

    公共无效setCreationDate(长creationDate){
        this.creationDate = creationDate;
    }
}
 

I'm trying to modify Firebase's Android chat example to include Firebase timestamp values. I can send the timestamp just fine using ServerValue.TIMESTAMP; but when Firebase tried to display the message, the app crashes. EDIT: full error output below

To send a message I use

private void sendMessage() {
    EditText inputText = (EditText)findViewById(R.id.messageInput);
    String input = inputText.getText().toString();
    Map timestamp = ServerValue.TIMESTAMP;

    if (!input.equals("")) {
        // Create our 'model', a Chat object
        Chat chat = new Chat(name, input, timestamp, userID);
        // Create a new, auto-generated child of that chat location, and save our chat data there
        chatRef.push().setValue(chat);
        inputText.setText("");
    }
}

The forge's structure is something like this:

->Messenger
  |--> room
      |--> messages
        |--> messageID
          |--> from: "Name"
          |--> text: "Message"
          |--> timestamp: xxxxxxxxxxxxx
          |--> userID: "id"

And Chat.java

public class Chat {

    private String from;
    private String text;
    private int userID;
    private Map<String, String> timestamp = new HashMap<String, String>();

    // Required default constructor for Firebase object mapping
    @SuppressWarnings("unused")
    private Chat() { }

    Chat(String from, String text, Map timestamp, int userID) {
        this.from = from;
        this.text = text;
        this.timestamp = timestamp;
        this.userID = userID;
    }

    public String getFrom() {
        return from;
    }

    public String getText() {
        return text;
    }

    public Map getTimestamp() {
        return timestamp;
    }

    public int getuserID() {
        return userID;
    }
}

If I delete the timestamp field from the messages on Firebase, the app doesn't crash.

The full Error message is below:

08-26 15:08:08.223  18097-18097/com.firebase.androidchat E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.firebase.androidchat, PID: 18097
    com.firebase.client.FirebaseException: Failed to bounce to type
            at com.firebase.client.DataSnapshot.getValue(DataSnapshot.java:185)
            at com.firebase.androidchat.FirebaseListAdapter$1.onChildAdded(FirebaseListAdapter.java:63)
            at com.firebase.client.core.ChildListenerContainer$1.run(ChildListenerContainer.java:52)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5001)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: com.shaded.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.util.LinkedHashMap out of VALUE_NUMBER_INT token
            at [Source: java.io.StringReader@41f8c588; line: 1, column: 2] (through reference chain: com.firebase.androidchat.Chat["timestamp"])
            at com.shaded.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:575)
            at com.shaded.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:569)
            at com.shaded.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:310)
            at com.shaded.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:26)
            at com.shaded.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:464)
            at com.shaded.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:107)
            at com.shaded.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:295)
            at com.shaded.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121)
            at com.shaded.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2888)
            at com.shaded.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2034)
            at com.firebase.client.DataSnapshot.getValue(DataSnapshot.java:181)
            at com.firebase.androidchat.FirebaseListAdapter$1.onChildAdded(FirebaseListAdapter.java:63)
            at com.firebase.client.core.ChildListenerContainer$1.run(ChildListenerContainer.java:52)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5001)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
            at dalvik.system.NativeStart.main(Native Method)

It looks like it may be caused by another issue which confuses me even more...

Caused by: com.shaded.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.util.LinkedHashMap out of VALUE_NUMBER_INT token
        at [Source: java.io.StringReader@41f8c588; line: 1, column: 2] (through reference chain: com.firebase.androidchat.Chat["timestamp"])

解决方案

Firebase.ServerValue.TIMESTAMP is set as a Map (containing {.sv: "timestamp"}) which tells Firebase to populate that field with the server's time. When that data is read back, it is the actual unix time stamp which is a Long. When Firebase (using Jackson) tries to deserialize that returned value, it fails since it is not a Map.

You could use Jackson annotations to control how your class is converted to JSON.

For example, something like this should work:

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.firebase.client.ServerValue;

public class Thing {
    private String id;
    private Long creationDate;

    public Thing() {

    }

    public Thing(String id) {
        this.id = id;
    }

    public String getId() {
        return id;
    }

    public java.util.Map<String, String> getCreationDate() {
        return ServerValue.TIMESTAMP;
    }

    @JsonIgnore
    public Long getCreationDateLong() {
       return creationDate;
    }

    public void setId(String id) {
        this.id = id;
    }

    public void setCreationDate(Long creationDate) {
        this.creationDate = creationDate;
    }
}