简体   繁体   English

无法从 Firestore 获取时间戳文档字段

[英]Unable to get Timestamp document field from Firestore

When getting data from Firestore, I am unable to get a timestamp field.从 Firestore 获取数据时,我无法获取时间戳字段。

My Room document is structured like this:我的房间文档的结构如下:

在此处输入图像描述

and I'm getting the rooms from Firestore like below.我正在从 Firestore 获取房间,如下所示。

Helper class:助手class:

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

Interactor class:互动者 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
}

My Room model class:我的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

}

The issue is that document.getDate(KEY_DATE_CREATED) is always returning null .问题是document.getDate(KEY_DATE_CREATED)总是返回null I've tried using get(KEY_DATE_CREATED) and getString(KEY_DATE_CREATED) just to see if I could get any value, but to no avail.我试过使用get(KEY_DATE_CREATED)getString(KEY_DATE_CREATED)只是为了看看我是否可以获得任何价值,但无济于事。

After a few more tries, I tested printing out the whole object and was able to get this:再试几次后,我测试了打印出整个 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
    }
}

So apparently, the dateCreated field is not being retrieved in the first place, which explains the null value.显然,首先没有检索到dateCreated字段,这解释了 null 值。 From the code I have, I believe I'm handling the parsing properly.从我的代码来看,我相信我正在正确处理解析。 What's confusing is I also have a Message object that has a dateCreated timestamp field and I'm able to get it properly.令人困惑的是我还有一条Message object,它有一个dateCreated时间戳字段,我能够正确地获取它。

PS: The sample codes are in Kotlin, I could post a Java code version if it could help make things more clear. PS:示例代码在Kotlin,我可以发一个Java的代码版本,如果它能帮助更清楚的话。


Update: Here's a screenshot of the Message document from Firestore.更新:这是来自 Firestore 的消息文档的屏幕截图。

在此处输入图像描述

And here's the my Message model class:这是我的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)

}

Making the Date nullable ( ? ) for Room does nothing.使Room的 Date 可为空 ( ? ) 不执行任何操作。

Seems that is not parsing correctly the format of the date. 似乎无法正确解析日期格式。

With firebase what I am doing is convert the date in to an Unix timestamp value, store that value in firebase. 使用firebase,我正在将日期转换为Unix时间戳值,并将该值存储在firebase中。 You can do that with the method getTime(). 您可以使用getTime()方法来实现。

And when I retrieve the data, the same, I convert the Unix timestamp value to a type Date. 当我检索数据时,同样,我将Unix时间戳值转换为类型Date。

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

Ex: 例如:

Data ------> Unix timestamp 数据------> Unix时间戳

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

If I have understood this problem correctly then you'll need to set the snapshot options, or it could be you're not waiting for the full result. 如果我已正确理解此问题,则需要设置快照选项,否则可能是您没有等待完整的结果。

I use the Node.js platform so you'll need to do the equivalent for your SDK. 我使用Node.js平台,因此您需要为您的SDK做同样的事情。

If set, controls the return value for server timestamps that have not yet been set to their final value. 如果设置,控制尚未设置为其最终值的服务器时间戳的返回值。

By specifying 'estimate', pending server timestamps return an estimate based on the local clock. 通过指定“估计”,挂起的服务器时间戳返回基于本地时钟的估计。 This estimate will differ from the final value and cause these values to change once the server result becomes available. 此估计值将不同于最终值,并且一旦服务器结果可用,这些值就会更改。

By specifying 'previous', pending timestamps will be ignored and return their previous value instead. 通过指定“ previous”,待处理的时间戳将被忽略,而是返回其先前的值。

If omitted or set to 'none', null will be returned by default until the server value becomes available 如果省略或设置为“ none”,则默认情况下将返回null,直到服务器值可用为止

Here is the link to the Node.js Client SDK. 这是指向Node.js客户端SDK的链接。 This may help you in the right direction. 这可能会帮助您朝正确的方向发展。 https://firebase.google.com/docs/reference/js/firebase.firestore.SnapshotOptions https://firebase.google.com/docs/reference/js/firebase.firestore.SnapshotOptions

First, you need to keep the names on your POJO item with the same ones of your Database, all your POJOs in the examples are wrote with camelCase annotation and in your database it is not. 首先,您需要将POJO项的名称与数据库中的名称保持相同,示例中的所有POJOs都使用camelCase批注编写,而在数据库中则不是。

If you want to keep your model with camelCase and your database without, you can use the annotation PropertyName : 如果要使用camelCase保留模型而没有使用camelCase保留数据库,则可以使用批注PropertyName

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

You missed the annotation @ServerTimestamp on your parameter in the POJO builder, which marks it it be inflated from a server timestamp. 您错过了POJO构建器中参数上的注解@ServerTimestamp ,这将其标记为已从服务器时间戳中夸大。

Annotation used to mark a Date field to be populated with a server timestamp. 用于标记要使用服务器时间戳填充的“日期”字段的注释。 If a POJO being written contains null for a @ServerTimestamp-annotated field, it will be replaced with a server-generated timestamp. 如果要写入的POJO包含@ServerTimestamp注释的字段为null,它将被服务器生成的时间戳替换。

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

Finally, don't forget that if you are writing your code in Java you should keep an empty constructor, and if you are writing it on Kotlin you should give a default value to any parameter of the class. 最后,不要忘记,如果您使用Java编写代码,则应保留一个空的构造函数,如果您是在Kotlin上编写,则应为该类的任何参数提供默认值。

When getting timeStamp from document you can use this.从文档中获取时间戳时,您可以使用它。

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

And Then> ob.toString();然后> ob.toString();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 从 Firestore 中的一个文档中获取一个字段 - Get one field from one document in Firestore 如何通过文档 ID 从 firestore 网站获取特定字段数据 - How get specific Field data by document id from firestore website 在嵌套的 map 中查询带有时间戳字段的 firestore 文档 - Query a firestore document with a timestamp field inside a nested map 我无法从云 firestore 访问文档字段并在 flutter 中的 statefulwidget class 中显示它 - I am unable to access document field from cloud firestore and show it in a statefulwidget class in flutter Firestore:通过 ID 从 CollectionGroup 获取文档 - Firestore: get document by ID from CollectionGroup 如何从云功能中的 firestore 获取文档 - How to get a document from firestore in cloud functions 如何使用 typescript 或 javascript 从 firestore 中的文档获取字段值并放入 console.log()? - How can I get a field value from a document in firestore with typescript or javascript and put in a console.log()? 如何从 Firebase 的集合中的 Firestore 文档中获取单个字段? - How to fetch a single Field from a Firestore document in a collection from Firebase? 如何从 Firestore 获取对文档数组的引用 - How to Get Reference to Document Array from Firestore 从 2 collection firestore 获取所有文档 - get all document from 2 collection firestore
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM