从Firestore获取数据时,我无法获取时间戳字段。
My Room文档的结构如下:
我正在从Firestore那里得到房间,如下所示。
助手类:
fun getRooms(userId: String): Task<QuerySnapshot> {
return FirebaseFirestore.getInstance()
.collection(KEY_USERS).document(userId)
.collection(KEY_ROOMS).get()
}
Interactor 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
模特课:
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)
来查看我是否可以获得任何价值,但无济于事。
经过几次尝试后,我测试了整个对象的打印情况,并且能够得到这个:
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
字段,这解释了空值。从我的代码中,我相信我正在正确处理解析。令人困惑的是,我还有一个Message
对象,其中包含dateCreated
时间戳字段,我能够正确地获取它。
P.S。:示例代码在Kotlin中,我可以发布Java代码版本,如果它可以帮助使事情更清楚。
更新:这是Firestore的消息文档的屏幕截图。
这是我的Message
模型类:
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
)不会做任何事情。
答案 0 :(得分:0)
似乎没有正确解析日期的格式。
使用firebase我正在做的是将日期转换为Unix时间戳值,将该值存储在firebase中。 你可以用getTime()方法做到这一点。
当我检索数据时,我将Unix时间戳值转换为Date类型。
Date date = new Date((long)timeStamp*1000);
前:
数据------&gt; Unix时间戳
05/14/2018 @ 3:26 pm(UTC)------&gt; 1526311610
答案 1 :(得分:0)
如果我已正确理解此问题,那么您需要设置快照选项,否则您可能无法等待完整结果。
我使用Node.js平台,因此您需要为SDK执行等效操作。
如果设置,则控制尚未设置的服务器时间戳的返回值 但已被设定为最终价值。
通过指定&#39;估计&#39;,挂起的服务器时间戳返回估计值 基于本地时钟。这个估计值与最终结果不同 一旦服务器结果变为值,就会导致这些值发生变化 可用。
通过指定&#39;之前的&#39;,将忽略待处理的时间戳 返回其先前的值。
如果省略或设置为&#39; none&#39;,默认情况下将返回null,直到 服务器值可用
以下是Node.js客户端SDK的链接。这可能会帮助您朝着正确的方向前进。 https://firebase.google.com/docs/reference/js/firebase.firestore.SnapshotOptions
答案 2 :(得分:0)
首先,您需要将POJO
项目上的名称与数据库中的名称保持一致,示例中的所有POJOs
都使用camelCase
注释编写并存储在数据库中它不是。
如果您希望将模型与camelCase
和数据库保持一致,则可以使用注释PropertyName
:
data class myFancyPojo(@PropertyName("name") val mName: String = "",
@ServerTimestamp
@PropertyName("timestamp")
val mTimestamp: Date? = null)
您错过了POJO构建器中参数的注释@ServerTimestamp
,这标志着它从服务器时间戳中膨胀。
用于标记要使用服务器时间戳填充的日期字段的注释。如果正在编写的POJO对于@ ServerTimestamp-annotated字段包含null,则它将替换为服务器生成的时间戳。
https://firebase.google.com/docs/reference/android/com/google/firebase/firestore/ServerTimestamp
最后,不要忘记,如果你用Java编写代码,你应该保留一个空构造函数,如果你在Kotlin上编写代码,你应该为类的任何参数赋予默认值。