在Firebase中制作POJO时,可以使用ServerValue.TIMESTAMP吗?

时间:2015-10-13 07:00:24

标签: android firebase firebase-realtime-database

当你制作一个普通的旧Java对象,意味着从Firebase序列化和反序列化时,有没有办法使用ServerValue.TIMESTAMP值?

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

在POJO课程中,您可能有:

private String timeLastChanged;

private Map<String, String> timeLastChanged;

在使用String的第一个示例中,我遇到了设置timeLastChange = ServerValue.TIMESTAMP;的问题,因为ServerValue.TIMESTAMP是一个地图。

Map<String, String>的第二个示例中,我得到了一个&#34;未能去抖动#34;错误,因为它无法将存储在数据库中的long正确反序列化为Map<String, String>。有没有解决这个问题?

6 个答案:

答案 0 :(得分:28)

2016年12月27日更新

为许多人提到的@Exclude切换了@JsonIgnore。

我终于想出了一个灵活的解决方案来处理Dates和ServerValue.TIMESTAMP。这是基于Ivan VOssamapuf的示例。

我无法找到处理longHashMap<String, String>之间转换的方法,但如果您将该属性嵌套在更通用的HashMap<String, Object>中,则可以进入数据库可以是单个长值(&#34;日期&#34;,&#34; 1443765561874&#34;),也可以是ServerValue.TIMESTAMP哈希映射(&#34;日期&#34;,{&# 34; .sv&#34;,&#34; servertime&#34;})。然后当你把它拉出来时,它总是一个HashMap(&#34; date&#34;,&#34;一些长数&#34;)。然后,您可以使用 @JsonIgnore @Exclude注释(意味着Firebase将忽略它而不将其视为用于序列化到数据库/从数据库中删除的方法)在POJO类中创建辅助方法,以轻松获取返回的HashMap中的long值将在您的应用中使用。

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

}

答案 1 :(得分:18)

我想稍微提高Lyla的答案。首先,我想摆脱公共方法public HashMap<String, Object> getDateLastChanged() public HashMap<String, Object> getDateCreated()。为此,您可以使用dateCreated注释标记@JsonProperty属性。另一种可能的方法是更改​​属性检测:@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;
    }

}

答案 2 :(得分: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);
}

欢迎就我的解决方案发表意见^^

答案 3 :(得分:5)

您可以使用Firebase原生>>> it = (i for i in range(4)) >>> sum(1 for _ in it) 4 ,而不是使用@JsonIgnore。 例如,我在一个类似的项目中工作,我的模型是这样的。

@Exclude

这段代码有效!在Firebase中,结果如下: Results

答案 4 :(得分: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;
    }
}

答案 5 :(得分:0)

Server.TIMESTAMP的最常见用途是:

  1. 在数据进入服务器时设置服务器值
  2. 从firebase获取此模型,并将其轻松转换为Long
  3. 这个技巧为我节省了处理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)
            }
        }