【问题标题】:Android chat crashes on DataSnapshot.getValue() for timestampAndroid 聊天在 DataSnapshot.getValue() 上崩溃以获取时间戳
【发布时间】:2014-10-19 10:38:32
【问题描述】:

我正在尝试修改 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"])

【问题讨论】:

  • this 有帮助吗?或thisthis
  • @Dhruti 在某种程度上确实如此......但不是一个令人难以置信的数量。我目前看不出命名约定会是个问题。我将使用消息结构更新我的帖子

标签: java android firebase


【解决方案1】:

Firebase.ServerValue.TIMESTAMP 设置为一个 Map(包含 {.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;
    }
}

【讨论】:

  • 是的,我似乎想通了,但是您对我能做些什么来解决这个问题有什么建议吗?
  • 太棒了!谢谢大家!
  • 有什么方法可以在不推送任何值的情况下获取 Firebase 服务器的日期和时间
  • @MuhammadYounas 您可以通过阅读“/.info/serverTimeOffset”获取设备时间与 Firebase 服务器时间之间的估计差异,参见firebase.google.com/docs/database/web/…
  • 谢谢会尝试,但我想知道如果设备时间改变意味着不准确,所以它会通过添加偏移量给我正确的日期/
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多