2015-10-13 2 views
22

Когда вы создаете Обычный объект Java, который предназначен для сериализации и десериализации в Firebase, существует ли способ использовать значение ServerValue.TIMESTAMP?При создании POJO в Firebase вы можете использовать ServerValue.TIMESTAMP?

Например, предположим, что у меня есть объект, в котором одно из свойств является последним, когда оно было отредактировано, и вы хотите использовать значение ServerValue.TIMESTAMP.

В классе POJO, вы можете иметь:

private String timeLastChanged; 

или

private Map<String, String> timeLastChanged; 

В первом примере с String, я бегу в вопросе установления timeLastChange = ServerValue.TIMESTAMP;, потому что ServerValue.TIMESTAMP является Карта ,

Во втором примере с Map<String, String> я получаю сообщение об ошибке «не удалось debounce», потому что он не может должным образом десериализовать длинный, хранящийся в базе данных, в Map<String, String>. Есть ли какая-нибудь работа для этого?

+1

См. Http://stackoverflow.com/questions/25500138/android-chat-crashes-on-datasnapshot-getvalue-for-timestamp/25512747#25512747 –

ответ

27

Update 12/27/2016

Switched из @JsonIgnore для @Exclude как многие уже упоминали.


Я, наконец, придумал гибкое решение для работы с датами и ServerValue.TIMESTAMP. Это отработка примеров от Ivan V, Ossama и puf.

Я не мог понять способ иметь дело с переходом между long и HashMap<String, String>, но если гнездо свойство в более общем HashMap<String, Object> он может пойти в базу данных либо как одно длинное значение («дата», «1443765561874») или как карта хеша ServerValue.TIMESTAMP («дата», {«.sv», «servertime»}). Затем, когда вы его вытаскиваете, всегда будет HashMap с («дата», «некоторое длинное число»). Затем вы можете создать вспомогательный метод в классе POJO с помощью аннотации @Exclude @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 ... timestamp создается правильно, хотя ... любые мысли или обходные пути для этого? Я в основном скопировал и вставил ваш код, прежде чем вы попросите мой код :) –

+0

Вы должны использовать «@Exclude» вместо @JsonIgnore уже – tieorange

+0

, если у меня может быть версия C#, это будет потрясающе. thanks –

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

} 
+0

Этот метод помогает сохранить метку времени на том же уровне, что и другие клавиши. – janakagamini

+0

Подлинная магия. Спасибо. Является ли это поведение документированным где угодно? – chetbox

+0

В любом случае, я мог бы получить эквивалент C# для использования в единстве3D # 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); 
} 

Добро пожаловать мнения о моем решении ^^

+0

Ваш метод getter помог мне, когда @snayde getter не работал для меня (ошибка разрешения) –

+0

Они должны использовать jason игнорировать, потому что объект является картой, и они хранят его как более простое поле – sivi

2

Вместо использования @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

+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. извлечь эту модель из firebase и брось легко Long

Этот трюк спас мне тяжелую работу ручки 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) 
     } 
    } 
Смежные вопросы