web-dev-qa-db-ja.com

FirebaseでPOJOを作成するときに、ServerValue.TIMESTAMPを使用できますか?

Plain Old Java Firebaseからシリアル化され、Firebaseに逆シリアル化されることを意図したオブジェクトを作成している場合、ServerValue.TIMESTAMP値を使用する方法はありますか?

たとえば、プロパティの1つが最後に編集されたときのオブジェクトがあり、ServerValue.TIMESTAMP値を使用したいとします。

POJOクラスでは、次のようになります。

private String timeLastChanged;

または

private Map<String, String> timeLastChanged;

Stringを使用した最初の例では、timeLastChange = ServerValue.TIMESTAMP;がマップであるため、ServerValue.TIMESTAMPの設定の問題に遭遇します。

Map<String, String>を使用した2番目の例では、データベースに保存されているlongをMap<String, String>に正しくデシリアライズできないため、「デバウンスに失敗しました」エラーが発生します。これに対する回避策はありますか?

25
Lyla

更新12/27/2016

@JsonIgnoreを @ Exclude に切り替え、多くの人が言及しました。


ようやく、DatesとServerValue.TIMESTAMPを操作するための柔軟なソリューションを思い付きました。これは Ivan VOssama 、および puf の例で機能しています。

longHashMap<String, String>の間の変換を処理する方法を理解できませんでしたが、より一般的なHashMap<String, Object>でプロパティをネストすると、どちらかとしてデータベースに入ることができます単一のlong値( "date"、 "1443765561874")またはServerValue.TIMESTAMPハッシュマップ( "date"、{".sv"、 "servertime"})として。次に、それを引き出すと、常に( "date"、 "some long number")を持つHas​​hMapになります。次に、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");
    }

}
29
Lyla

Lylaの答えを少し改善したかった。まず、パブリックメソッドpublic HashMap<String, Object> getDateLastChanged() public HashMap<String, Object> getDateCreated()を削除します。そのためには、dateCreatedプロパティに_@JsonProperty_アノテーションを付けることができます。これを行う別の可能な方法は、そのようなプロパティ検出を変更することです:@JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE)
2番目に、_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;
    }

}
_
18
sergey.n

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

私の解決策に関する意見へようこそ^^

8
Daniel Chan

@JsonIgnoreを使用する代わりに、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

同じソリューションですが、これを使用します。

@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
wonsuc

Server.TIMESTAMPの最も一般的な用途は次のとおりです。

  1. データがサーバーに送信されたときにサーバー値を設定する
  2. このモデルをfirebaseからフェッチし、簡単にLongにキャストします

このトリックにより、1つの値に対して2つの異なるフィールドを処理するという面倒な作業を省くことができました

    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)
        }
    }
0
yarin