簡體   English   中英

無法從 Firestore 獲取時間戳文檔字段

[英]Unable to get Timestamp document field from Firestore

從 Firestore 獲取數據時,我無法獲取時間戳字段。

我的房間文檔的結構如下:

在此處輸入圖像描述

我正在從 Firestore 獲取房間,如下所示。

助手class:

    fun getRooms(userId: String): Task<QuerySnapshot> {
        return FirebaseFirestore.getInstance()
                .collection(KEY_USERS).document(userId)
                .collection(KEY_ROOMS).get()
    }

互動者 class:

private fun getRooms(): Task<List<Room>> {
    val source = TaskCompletionSource<List<Room>>()
    val listener = OnCompleteListener<QuerySnapshot> {
        if (it.isSuccessful) {
            val roomSnapshots = it.result
            if (!roomSnapshots.isEmpty) {
                val rooms = ArrayList<Room>()
                for (roomSnapshot in roomSnapshots) {
                    rooms.add(Room(roomSnapshot))
                }
                source.setResult(rooms)
            }
        } else {
            source.setException(it.exception!!)
        }
    }
    FirebaseFireStoreHelper.getRooms(mUserId).addOnCompleteListener(listener)
    return source.task
}

我的Room model class:

class Room(document: DocumentSnapshot) {

    companion object {
        private const val KEY_DATE_CREATED = "dateCreated"
        private const val KEY_TITLE = "title"
    }

    private lateinit var mId: String
    private lateinit var mDateCreated: Date
    private lateinit var mTitle: String

    init {
        if (document.exists()) {
            mId = document.id
            mDateCreated = document.getDate(KEY_DATE_CREATED)!!
            mTitle = document.getString(KEY_TITLE)!!
        }
    }

    fun getId(): String = mId

    fun getDateCreated(): Date? = mDateCreated

    fun getTitle(): String = mTitle

}

問題是document.getDate(KEY_DATE_CREATED)總是返回null 我試過使用get(KEY_DATE_CREATED)getString(KEY_DATE_CREATED)只是為了看看我是否可以獲得任何價值,但無濟於事。

再試幾次后,我測試了打印出整個 object 並能夠得到這個:

DocumentSnapshot{
    key=users/kCKkmgLmLGfvbPFK09qyZ5uoyw32/rooms/R35Bj56rda7pkkYWH1MQ,
    metadata=SnapshotMetadata{
        hasPendingWrites=false,
        isFromCache=false
    },
    doc=Document{
        key=users/kCKkmgLmLGfvbPFK09qyZ5uoyw32/rooms/R35Bj56rda7pkkYWH1MQ,
        data=zza{
            (title=>Sample Room)
        };,
    version=SnapshotVersion(seconds=1523285961, nanos=350799000),
    hasLocalMutations=false
    }
}

顯然,首先沒有檢索到dateCreated字段,這解釋了 null 值。 從我的代碼來看,我相信我正在正確處理解析。 令人困惑的是我還有一條Message object,它有一個dateCreated時間戳字段,我能夠正確地獲取它。

PS:示例代碼在Kotlin,我可以發一個Java的代碼版本,如果它能幫助更清楚的話。


更新:這是來自 Firestore 的消息文檔的屏幕截圖。

在此處輸入圖像描述

這是我的Message model class:

class Message(document: DocumentSnapshot) {

    companion object {
        private const val KEY_CONTENT = "content"
        private const val KEY_DATE_CREATED = "dateCreated"
    }

    private lateinit var mId: String
    private lateinit var mContent: String
    private lateinit var mDateCreated: Date

    // TODO: Figuring out why getDate doesn't seem to work for Rooms

    init {
        if (document.exists()) {
            mId = document.id
            mContent = document.getString(KEY_CONTENT)!!
            mDateCreated = document.getDate(KEY_DATE_CREATED)!!
        }
    }

    fun getId(): String = mId

    fun getContent(): String = mContent

    fun getDateCreated(): Date = mDateCreated

    fun getStringFormattedDateCreated() = FormatterUtil.getFormattedTimestamp(mDateCreated)

}

使Room的 Date 可為空 ( ? ) 不執行任何操作。

似乎無法正確解析日期格式。

使用firebase,我正在將日期轉換為Unix時間戳值,並將該值存儲在firebase中。 您可以使用getTime()方法來實現。

當我檢索數據時,同樣,我將Unix時間戳值轉換為類型Date。

Date date = new Date((long)timeStamp*1000);

例如:

數據------> Unix時間戳

2018年5月14日下午3:26(UTC)------> 1526311610

如果我已正確理解此問題,則需要設置快照選項,否則可能是您沒有等待完整的結果。

我使用Node.js平台,因此您需要為您的SDK做同樣的事情。

如果設置,控制尚未設置為其最終值的服務器時間戳的返回值。

通過指定“估計”,掛起的服務器時間戳返回基於本地時鍾的估計。 此估計值將不同於最終值,並且一旦服務器結果可用,這些值就會更改。

通過指定“ previous”,待處理的時間戳將被忽略,而是返回其先前的值。

如果省略或設置為“ none”,則默認情況下將返回null,直到服務器值可用為止

這是指向Node.js客戶端SDK的鏈接。 這可能會幫助您朝正確的方向發展。 https://firebase.google.com/docs/reference/js/firebase.firestore.SnapshotOptions

首先,您需要將POJO項的名稱與數據庫中的名稱保持相同,示例中的所有POJOs都使用camelCase批注編寫,而在數據庫中則不是。

如果要使用camelCase保留模型而沒有使用camelCase保留數據庫,則可以使用批注PropertyName

data class myFancyPojo(@PropertyName("name") val mName: String = "",
                   @ServerTimestamp
                   @PropertyName("timestamp")
                   val mTimestamp: Date? = null)

您錯過了POJO構建器中參數上的注解@ServerTimestamp ,這將其標記為已從服務器時間戳中誇大。

用於標記要使用服務器時間戳填充的“日期”字段的注釋。 如果要寫入的POJO包含@ServerTimestamp注釋的字段為null,它將被服務器生成的時間戳替換。

https://firebase.google.com/docs/reference/android/com/google/firebase/firestore/ServerTimestamp

最后,不要忘記,如果您使用Java編寫代碼,則應保留一個空的構造函數,如果您是在Kotlin上編寫,則應為該類的任何參數提供默認值。

從文檔中獲取時間戳時,您可以使用它。

Object ob=document.getDate("createdDate", DocumentSnapshot.ServerTimestampBehavior.ESTIMATE);

然后> ob.toString();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM