2016-06-16 75 views
11

Obecnie wersja Google ServerValue.TIMESTAMP zwraca {".sv":"timestamp"}, która jest używana jako dyrektywa dla Firebase do wypełnienia tego pola znacznikiem czasu serwera po zapisaniu danych na serwerze Firebase.Jak użyć znacznika czasu serwera Firebase do wygenerowania daty utworzenia?

Jednak po utworzeniu danych po stronie klienta nie ma rzeczywistego znacznika czasu, z którym można jeszcze korzystać (tj. Użyj jako daty utworzenia). Będziesz miał dostęp do znacznika czasu po wstępnym zapisaniu i późniejszym odzyskaniu, które - jak sobie wyobrażam - jest czasami za późno i niezbyt elegancko.


Przed Google:

Aktualizacja: Zignoruj ​​ten punkt, ponieważ jest nieprawidłowy - ja źle przykłady. ServerValue.TIMESTAMP zawsze zwracano {".sv":"timestamp"}.

O ile mi zrozumieć, w pre-google Firebase wydawało się, że znacznik czasu serwera generowane dostępne który pozwalał nabyć rzeczywistą timestamp:

import com.firebase.client.ServerValue; 
ServerValue.TIMESTAMP // eg. 1466094046 

(ref 1, ref 2)


pytania:

  1. Czy takie zapisywanie/pobieranie jest jedynym sposobem uzyskania daty utworzenia wygenerowanej przez serwer w wystąpieniach mojego modelu?
  2. Jeśli tak, czy możesz zaproponować metodę wdrożenia takiego wzoru?
  3. Czy rozumiem poprawnie ServerValue.TIMESTAMP zmienił się wraz z przejęciem Firebase przez Google? Aktualizacja: Nie, @FrankvanPuffelen odpowiedział, że nic się nie zmieniło podczas akwizycji.

Uwaga:

nie jestem rozważa wykorzystanie new Date() po stronie klienta, jak czytałem to nie jest bezpieczne, choć proszę podzielić się swoimi przemyśleniami, jeśli myślisz inaczej.

+0

* firebaser tutaj * Nic się nie zmieniło w sposobie generowania 'ServerValue.TIMESTAMP' od czasu, kiedy dołączyliśmy do Google. Kod, który działał wcześniej, będzie nadal działał. Jeśli masz kod, który nie działa, dodaj minimalny kod, który powiela problem na twoje pytanie. –

+0

@FrankvanPuffelen I niezrozumiałe stare przykłady, dzięki. 'ServerValue.TIMESTAMP' zawsze zwracał' {".sv": "timestamp"} '. Nie odwołuję się do kodu, który nie działa, tylko teoretyczne pytanie, jak poprawnie użyć znacznika czasu serwera do pracy z * utworzoną datą * – Voy

Odpowiedz

20

Podczas korzystania ze stałej ServerValue.TIMESTAMP w operacji zapisu, mówisz, że serwer bazy danych Firebase powinien określić poprawny znacznik czasu podczas wykonywania operacji zapisu.

Powiedzmy, że ten kod:

ref.addValueEventListener(new ValueEventListener() { 
    public void onDataChange(DataSnapshot dataSnapshot) { 
     System.out.println(dataSnapshot.getValue()); 
    } 

    public void onCancelled(DatabaseError databaseError) { } 
}); 
ref.setValue(ServerValue.TIMESTAMP); 

Będzie to wykonać w następujący sposób:

  1. dołączeniu słuchacza
  2. piszesz wartość z ServerValue.TIMESTAMP
  3. klient Firebase natychmiastowa uruchamia zdarzenie wartości z przybliżeniem znacznika czasu zapisanego na serwerze
  4. wydruki kodów, które cenią
  5. operacja zapisu zostanie wysłany do Firebase serwerów
  6. z Firebase serwery określenia rzeczywistej znacznik czasu i wpisać wartość do bazy danych (przy założeniu, że żadne przepisy bezpieczeństwa nie)
  7. serwer Firebase wysłać rzeczywista datownik z powrotem do klienta
  8. Firebase klient zgłosi zdarzenie wartość rzeczywistej wartości
  9. wydruków kodów, które cenią

Jeśli używasz ChildEventListener zamiast ValueEventListener, wówczas klient zadzwoni onChildAdded w kroku 3 i onChildChanged w kroku 8.

nic się nie zmieniło w sposobie wygenerowania ServerValue.TIMESTAMP od Firebase dołączył do Google. Kod, który działał wcześniej, będzie nadal działał. Oznacza to również, że first answer you linked jest prawidłowym sposobem obsługi.

0

Robię to trochę inaczej.

Rozwiązanie 1: push() metoda POJO

Ponieważ nie chcę zaśmiecać moje POJOs z dziwnych pobierające lub właściwości, ja tylko wyznaczających push() metodę w moim POJOs który wygląda tak:

/** 
* Pushes a new instance to the DB. 
* 
* @param parentNode `DatabaseReference` to the parent node this object shall be attached to 
*/ 
fun push(parentNode: DatabaseReference) { 
    parentNode 
     .push() 
     .apply { 
      setValue([email protected]) 
      child(Pojo.CREATED_AT_KEY).setValue(ServerValue.TIMESTAMP) 
     } 
} 

Następnie mogę po prostu utworzyć instancję POJO i zadzwonić pod numer push(), który poprawnie wypełnia właściwość czasu utworzenia.

To zdecydowanie sprawia, że ​​POJO jest trochę mniej proste i wymaga logiki, o której POJO nie powinno wiedzieć. Jednak użycie adnotacji i/lub rzutów opisanych w niektórych odpowiedziach here wymaga również znajomości mechanizmu przechowywania.

Rozwiązanie 2: Pomocnik lub DatabaseReference przedłużenie (Kotlin)

Do tego można oczywiście pokonać też po prostu utworzyć metodę pushTask(task: Task) w pomocnika lub - w przypadku korzystania Kotlin - metodę rozszerzenia na przykładDatabaseReference która mogłaby wyglądać następująco:

fun DatabaseReference.push(pojo: Pojo) { 
    push() 
    .apply { 
     setValue(pojo) 
     child(Pojo.CREATED_AT_KEY).setValue(ServerValue.TIMESTAMP) 
    } 
} 

Patrząc na to teraz ja się o tym myśleć, że rzeczywiście tak jak w drugim podejściu więcej (jeśli mam Kotlin do mojej dyspozycji - Nie lubię pomocników). Ale to tylko kwestia gustu. ;)