繁体   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