2015-10-13 52 views
22

当你制作一个普通的旧Java对象,这个对象应该被序列化并反序列化为Firebase时,有没有办法使用ServerValue.TIMESTAMP值?在Firebase中制作POJO时,您可以使用ServerValue.TIMESTAMP吗?

例如,假设我想要一个对象,其中一个属性是最后一次编辑的对象,并且您希望使用ServerValue.TIMESTAMP值。

在POJO类,你可能有:

private String timeLastChanged; 

private Map<String, String> timeLastChanged; 

在与String第一个例子,我碰上设置timeLastChange = ServerValue.TIMESTAMP;的问题,因为ServerValue.TIMESTAMP是一个地图。

Map<String, String>的第二个例子中,我得到一个“未能反弹”的错误,因为它不能正确地反序列化存储在数据库中的长为Map<String, String>。有没有解决这个问题的方法?

+1

查看http://stackoverflow.com/questions/25500138/android-chat-c​​rashes-on-datasnapshot-getvalue-for-timestamp/25512747#25512747 –

回答

27

更新2016年12月27日

切换出@JsonIgnore为@Exclude如许多人提及。


我终于想出了一个用于处理日期和ServerValue.TIMESTAMP的灵活解决方案。这是从Ivan V,Ossamapuf的例子。

我无法想出一个办法来对付longHashMap<String, String>之间的转换,但如果你窝在一个更通用的HashMap<String, Object>财产可以进入数据库,可作为单一的长值(“日期”, “1443765561874”)或作为ServerValue.TIMESTAMP哈希映射(“date”,{“.sv”,“servertime”})。然后当你把它拉出来时,它总是一个带有(“date”,“some long number”)的HashMap。然后,您可以在POJO类中使用 @JsonIgnore @Exclude注解(意味着Firebase会忽略它,并且不会将其视为序列化到/从数据库序列化的方法)在辅助方法中轻松地从返回的值中获取长整型值HashMap在您的应用程序中使用。一个POJO类的

全部例子如下:

import com.google.firebase.database.Exclude; 
import com.firebase.client.ServerValue; 

import java.util.HashMap; 
import java.util.Map; 

public class ExampleObject { 
    private String name; 
    private String owner; 
    private HashMap<String, Object> dateCreated; 
    private HashMap<String, Object> dateLastChanged; 

    /** 
    * Required public constructor 
    */ 
    public ExampleObject() { 
    } 

    public ExampleObject(String name, String owner, HashMap<String,Object> dateCreated) { 
     this.name = name; 
     this.owner = owner; 
     this.dateCreated = dateCreated; 

     //Date last changed will always be set to ServerValue.TIMESTAMP 
     HashMap<String, Object> dateLastChangedObj = new HashMap<String, Object>(); 
     dateLastChangedObj.put("date", ServerValue.TIMESTAMP); 
     this.dateLastChanged = dateLastChangedObj; 
    } 

    public String getName() { 
     return name; 
    } 

    public String getOwner() { 
     return owner; 
    } 

    public HashMap<String, Object> getDateLastChanged() { 
     return dateLastChanged; 
    } 

    public HashMap<String, Object> getDateCreated() { 
     //If there is a dateCreated object already, then return that 
     if (dateCreated != null) { 
      return dateCreated; 
     } 
     //Otherwise make a new object set to ServerValue.TIMESTAMP 
     HashMap<String, Object> dateCreatedObj = new HashMap<String, Object>(); 
     dateCreatedObj.put("date", ServerValue.TIMESTAMP); 
     return dateCreatedObj; 
    } 

// Use the method described in https://stackoverflow.com/questions/25500138/android-chat-crashes-on-datasnapshot-getvalue-for-timestamp/25512747#25512747 
// to get the long values from the date object. 
    @Exclude 
    public long getDateLastChangedLong() { 

     return (long)dateLastChanged.get("date"); 
    } 

    @Exclude 
    public long getDateCreatedLong() { 
     return (long)dateCreated.get("date"); 
    } 

} 
+2

当我调用'getDateLastChangedLong()时, '我得到一个NullPointerException可能是因为投射到Long ..时间戳得到正确创建虽然...任何想法或解决方法?我基本上复制并粘贴你的代码之前,你要求我的代码:) –

+0

你应该使用“@Exclude”,而不是@JsonIgnore – tieorange

+0

如果我可以有一个C#版本,这将是非常棒的。谢谢 –

18

我想提高莱拉的回答一点点。首先,我想摆脱公共方法public HashMap<String, Object> getDateLastChanged() public HashMap<String, Object> getDateCreated()。为了做到这一点,您可以使用@JsonProperty注释标记dateCreated属性。另一种可能的方式是更改属性检测,如下所示:@JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE)
其次,我不明白为什么我们需要将ServerValue.TIMESTAMP放入HashMap,而我们可以将它们存储为属性。所以我的最终代码是:

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

public class ShoppingList { 
    private String listName; 
    private String owner; 
    @JsonProperty 
    private Object created; 

    public ShoppingList() { 
    } 

    public ShoppingList(String listName, String owner) { 
     this.listName = listName; 
     this.owner = owner; 
     this.created = ServerValue.TIMESTAMP; 
    } 

    public String getListName() { 
     return listName; 
    } 

    public String getOwner() { 
     return owner; 
    } 

    @JsonIgnore 
    public Long getCreatedTimestamp() { 
     if (created instanceof Long) { 
      return (Long) created; 
     } 
     else { 
      return null; 
     } 
    } 

    @Override 
    public String toString() { 
     return listName + " by " + owner; 
    } 

} 
+0

这种方法有助于保持时间戳与其他键一样。 – janakagamini

+0

真正的魔力。谢谢。这种行为是否在任何地方记录? – chetbox

+0

无论如何,我可以得到一个C#等效于unity3D#unity3d –

7

这些解决方案对我来说似乎有点困难,因为我不知道@JsonIgnore在做什么。我试图以一种简单的方式做到这一点,似乎工作。

private Object dateLastChanged; 

public Object getDateLastChanged() { 
    return dateLastChanged; 
} 

要得到的东西可读,我刚刚过去的返回值dateLastChanged铸造成Long对象为以下方法。

static String convertTime(Long unixtime) { 
    Date dateObject = new Date(unixtime); 
    SimpleDateFormat dateFormatter = new SimpleDateFormat("dd-MM-yy hh:mmaa"); 
    return dateFormatter.format(dateObject); 
} 

欢迎到我的解决方案^^

+0

当@snayde getter不工作的时候,你的getter方法帮助我(权限错误) –

+0

他们必须使用杰森忽略,因为该对象是地图,他们将其存储为一个简单的字段 – sivi

2

而不是使用@JsonIgnore的意见,你可以使用火力地堡本地@Exclude。例如,我在一个类似的项目中工作,我的模型就是这样。

package com.limte.app.borrador_1.mModel; 

import com.google.firebase.database.Exclude; 
import com.google.firebase.database.ServerValue; 

/** 
* Created by Familia on 20/12/2016. 
*/ 

public class ChatItem { 
    String chatName; 
    Long creationDate; 


    public ChatItem() { 
    } 

    public String getChatName() { 
     return chatName; 
    } 

    public void setChatName(String chatName) { 
     this.chatName = chatName; 
    } 

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

    @Exclude 
    public Long getCreationDateLong() { 
     return creationDate; 
    } 
    public void setCreationDate(Long creationDate) { 
     this.creationDate = creationDate; 
    } 

} 

而这段代码的工作原理!在Firebase中,结果为: Results

+0

你的实际工作! –

0

相同的解决方案,但我使用它。

@IgnoreExtraProperties 
public class FIRPost { 
    Object timestamp; 

    public FIRPost() { 
     // Default constructor required for calls to DataSnapshot.getValue(FIRPost.class) 
     this.timestamp = ServerValue.TIMESTAMP; 
    } 

    public Object getTimestamp() { 
     return timestamp; 
    } 

    @Exclude 
    public Long getTimestamp(boolean isLong) { 
     if (timestamp instanceof Long) return (Long) timestamp; 
     else return null; 
    } 
} 
0

为Server.TIMESTAMP最常见的用途是:

  1. 设置服务器值时,将数据发送到服务器
  2. 获取从火力此模型中,并轻松将它转换为长

这一招救了我把手2个不同领域的辛勤工作只值1

public class HandleTimestampFirebaseObject { 

    Object timestamp; 

    public HandleTimestampFirebaseObject() { 

    } 

    public Object getTimestamp(){ 
     if(timestamp instanceof Double){ 

     /* this will handle the case of AFTER fetch from backend,and 
      serialize to object into SharedPreferences for example ,when the 
      Object casting automatically into Double. 
      (Anyway,call (long)getTimestamp from your code who use this model*/ 
      return ((Double) timestamp).longValue(); 
     } 
     else{ 
      return timestamp; //this handle to firebase requirement in the server side(Object needed) 
     } 
    } 
相关问题