2015-10-13 60 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) 
     } 
    } 
相關問題