2016-06-16 56 views
11

目前,Google版本的ServerValue.TIMESTAMP返回{".sv":"timestamp"},將Firebase數據保存到Firebase服務器後,將其作爲Firebase的指令使用服務器時間戳填充該字段。如何使用Firebase服務器時間戳生成創建的日期?

但是,當您在客戶端創建數據時,您還沒有實際的時間戳可供使用(即用作創建日期)。在初始保存和隨後的檢索之後,您只能訪問時間戳,我想 - 這有時爲時已晚,不夠優雅。


谷歌前:

更新:忽略這一部分,因爲它是不正確 - 我誤解的例子。 ServerValue.TIMESTAMP總是返回{".sv":"timestamp"}

至於我前谷歌火力地堡的理解似乎有一個服務器生成的時間戳可用,允許你獲得實際的時間戳:

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

ref 1ref 2


問題:

  1. 這樣的保存/檢索是獲得我的模型實例上服務器生成的創建日期的唯一方法嗎?
  2. 如果是,你可以提出一種實現這種模式的方法嗎?
  3. 我的理解是否正確ServerValue.TIMESTAMP隨着Google收購Firebase而改變? 更新:不,@FrankvanPuffelen回覆說,在收購過程中沒有任何變化。

注:

我不是在客戶端使用new Date(),因爲我一直在閱讀它不是安全的,但請分享您的想法,如果你認爲不同的考慮。

+0

* firebaser here *自從我們加入Google後,我們生成'ServerValue.TIMESTAMP'的方式沒有任何變化。以前工作的代碼將繼續工作。如果您的代碼無法正常工作,請將重現問題的最小代碼添加到您的問題中。 –

+0

@FrankvanPuffelen我誤解了舊的例子,謝謝。 'ServerValue.TIMESTAMP'總是返回'{「.sv」:「timestamp」}'。我不是指那些不起作用的代碼,只是關於如何正確使用服務器時間戳來處理*日期創建的理論問題* – Voy

回答

20

當您在寫入操作中使用ServerValue.TIMESTAMP常量時,表示Firebase數據庫服務器應在執行寫入操作時確定正確的時間戳。

比方說,我們運行這段代碼:

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

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

這將執行如下:

  1. 您可以將聽者
  2. 你寫與ServerValue.TIMESTAMP
  3. 的火力地堡客戶端即時值使用它將在服務器上寫入的時間戳近似值觸發值事件
  4. 那些重視
  5. 寫操作被髮送到火力地堡服務器
  6. 你的代碼打印
  7. 的火力地堡服務器確定實際的時間戳和值寫入數據庫(假設沒有安全規則失敗)
  8. 的火力地堡的服務器發送實際的時間戳返回給客戶端
  9. 的火力地堡客戶提出的實際值
  10. 你的代碼打印如果您使用的是01珍視

值事件代替ValueEventListener,然後在客戶端將調用在步驟3 onChildAddedonChildChanged在第8步

沒有在我們產生ServerValue.TIMESTAMP因爲火力地堡加入谷歌的方式改變。以前工作的代碼將繼續工作。這也意味着first answer you linked是處理它的有效方法。

0

我這樣做有點不同。

解決方案1:push()方法POJO

因爲我不想弄亂我的POJO奇怪的getter或屬性,我只是定義我的POJO內push()方法,它看起來像這樣:

/** 
* 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) 
     } 
} 

然後,我可以簡單地創建POJO的實例,並調用它push()其正確填充創建時間屬性。

這絕對會使POJO不那麼簡單,並涉及POJO不應該知道的邏輯。但是,如使用@Exclude註釋和/或強制轉換here中列出的某些響應也需要知道存儲機制。

解決方案2:助手或DatabaseReference延伸(科特林)

爲了克服這個可以當然也只是在一輔助創建pushTask(task: Task)方法或 - 如果使用科特林 - 擴展方法,以例如DatabaseReference這可能是這樣的:

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

看它現在我來想,其實我喜歡第二種方法更(如果我有科特林在我手上 - 我不喜歡傭工)。但這可能只是一個品味問題。 ;)

相關問題