Android聊天在DataSnapshot.getValue()上崩溃,以获取时间戳

时间:2014-08-26 07:18:44

标签: java android firebase

我正在尝试修改Firebase的Android聊天示例以包含Firebase时间戳值。我可以使用ServerValue.TIMESTAMP;发送时间戳,但是当Firebase尝试显示消息时,应用程序崩溃了。编辑:

以下的完整错误输出

发送我使用的消息

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

伪造的结构是这样的:

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

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

如果我从Firebase上的邮件中删除了时间戳字段,则该应用不会崩溃。

完整的错误消息如下:

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)

看起来它可能是由另一个令我困惑的问题引起的......

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"])

2 个答案:

答案 0 :(得分:13)

Firebase.ServerValue.TIMESTAMP设置为地图(包含{.sv: "timestamp"}),告知Firebase使用服务器的时间填充该字段。当回读该数据时,它是实际的unix时间戳,它是Long。当Firebase(使用Jackson)尝试反序列化返回的值时,它会失败,因为它不是Map

您可以使用Jackson annotations来控制类转换为JSON的方式。

例如,这样的事情应该有效:

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

答案 1 :(得分:12)

我知道这个帖子已经过时了,但对于任何尝试实现类似时间戳的人来说,现在可以使用Firebase原生@JsonIgnore而不是使用Jackson注释中的@Exclude