2015-10-13 14 views
22

Firebaseにシリアル化されてシリアル化されることになっているPlain Old Javaオブジェクトを作成するときに、ServerValue.TIMESTAMPの値を使用する方法はありますか?FirebaseでPOJOを作成するときに、ServerValue.TIMESTAMPを使用できますか?

たとえば、最後に編集したプロパティの1つで、ServerValue.TIMESTAMPという値を使用したいオブジェクトがあるとします。 POJOクラスで

、あなたが持つかもしれない:Stringとの最初の例で

private String timeLastChanged; 

または

private Map<String, String> timeLastChanged; 

ServerValue.TIMESTAMPが地図であるので、私は、timeLastChange = ServerValue.TIMESTAMP;の設定の問題が発生しました。

Map<String, String>の2番目の例では、データベースに格納されたlongを正しくデシリアライズしてMap<String, String>にすることができないため、「デバッグに失敗しました」というエラーが表示されます。これのための回避策はありますか?

+1

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

答えて

27

を更新2016年12月27日

多くの人が言及したよう@Excludeため@JsonIgnoreを交換。


私は最終的にDatesとServerValue.TIMESTAMPで作業するための柔軟なソリューションを考え出しました。これは、Ivan VOssama、およびpufの例を解決しています。

私はlongHashMap<String, String>間の変換に対処する方法を見つけ出すことができませんでしたが、より一般的なHashMap<String, Object>でネストプロパティを場合には、単一のlong値(「日付」としてデータベースに行くことができ、 "1443765561874")またはServerValue.TIMESTAMPハッシュマップ( "date"、{".sv"、 "servertime"})として使用できます。それを引き出すと、常に( "日付"、 "ある程度長い")HashMapになります。 @JsonIgnore @Excludeアノテーションを使用してPOJOクラスのヘルパーメソッドを作成することができます(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() 'おそらくLongへのキャストのためにNullPointerExceptionが発生します。タイムスタンプは正しく作成されますが...これについての考えや回避策はありますか? –

+0

@JsonIgnoreの代わりに "@Exclude"を使用してください。すでに – tieorange

+0

があれば、これでC#バージョンの素晴らしいものにすることができます。 thanks –

18

私はライラの答えを少し改善したかったです。まず、公開方法を取り除きたいですpublic HashMap<String, Object> getDateLastChanged() public HashMap<String, Object> getDateCreated()。そのためにdateCreatedプロパティに@JsonProperty注釈を付けることができます。もう1つの可能な方法は、そのようなプロパティの検出を変更することです。@JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE)
第2に、ServerValue.TIMESTAMPHashMapに入れなければならない理由はわかりませんが、プロパティとして保存することができます。だから私の最終的なコードは次のとおりです。

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。

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

代わり@JsonIgnoreを使用しての^^

+0

@snaydeゲッターが私のために働いていなかったときに、 (許可エラー) –

+0

オブジェクトはマップなので、jason ignoreを使用しなければなりません。より単純なフィールドとして保存します。 – sivi

2

私の解決策について意見へようこそ、あなたはFirebaseネイティブ@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. は、データがfirebaseからこのモデルをフェッチし、ロングに簡単にそれをキャストサーバー
  2. に送信されたときにサーバーの値を設定します

このトリックは私にハンドルのハードワークのみ1値

01のための2つの異なるフィールドを保存