When making a POJO in Firebase, can you use ServerValue.TIMESTAMP?

Solution 1:

Update 12/27/2016

Switched out @JsonIgnore for @Exclude as many have mentioned.


I finally came up with a flexible solution for working with Dates and ServerValue.TIMESTAMP. This is working off of examples from Ivan V, Ossama, and puf.

I couldn't figure out a way to deal with the conversion between long and HashMap<String, String>, but if you nest the property in a more generic HashMap<String, Object> it can go into the database as either a single long value ("date", "1443765561874") or as the ServerValue.TIMESTAMP hash map ("date", {".sv", "servertime"}). Then when you pull it out, it will always be a HashMap with ("date", "some long number"). You can then create a helper method in your POJO class using the @JsonIgnore @Exclude annotation (meaning Firebase will ignore it and not treat it as a method for serializing to/from the database) to easily get the long value from the returned HashMap to use in your app.

Full example of a POJO class is below:

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

}

Solution 2:

I wanted to improve Lyla's answer a little bit. First, I would like to get rid of public methods public HashMap<String, Object> getDateLastChanged() public HashMap<String, Object> getDateCreated(). In order to do that you can mark dateCreated property with @JsonProperty annotation. Another possible way to do so is to change property detection like that: @JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE)
Second, I don't understand why we need to put ServerValue.TIMESTAMP into HashMap while we can just store them as property. So my final code is:

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

}