【发布时间】:2023-03-06 09:30:01
【问题描述】:
我有一个使用 FirebaseDatabase 传输和存储消息的聊天应用。聊天必须在手机在线或离线模式下工作(大多数聊天都是这样),因此消息具有三个状态值:“未发送”、“未读”和“已读”。
1. 消息在本地以“未发送”状态存储。
2. 接下来我的应用实例尝试将其发送到 FirebaseDatabase 并在成功时将状态更改为“未读取”。
3. 最后,当合作伙伴收到消息时,他的应用程序实例在 FirebaseDatabase 上更新消息,状态为“已读”,而我的应用程序实例捕捉到此消息并更新本地消息数据。
当我尝试确定消息是否到达服务器以及何时更改其状态时,主要问题是第二步。
首先,我尝试发送一条消息:
private fun send (firebaseMessage: FirebaseMessage) {
val ref = FirebaseDatabase.getInstance().getReference("/user-messages/${firebaseMessage.fromUid}/${firebaseMessage.toUid}/${firebaseMessage.Uid}")
ref.setValue(firebaseMessage)
}
我有 childEventListener 如下:
private fun listen() {
val ref = FirebaseDatabase.getInstance().getReference("/user-messages/${firebaseMessage.fromUid}/${firebaseMessage.toUid}")
ref.addChildEventListener(object : ChildEventListener {
override fun onCancelled(p0: DatabaseError) {}
override fun onChildMoved(p0: DataSnapshot, p1: String?) {}
override fun onChildChanged(p0: DataSnapshot, p1: String?) {
updateMessage(p0.getValue(FirebaseMessage::class.java))
}
override fun onChildAdded(p0: DataSnapshot, p1: String?) {
updateStatusMessage(p0.getValue(FirebaseMessage::class.java))
}
override fun onChildRemoved(p0: DataSnapshot) {}
})
}
主要问题是 childEventListener 触发 onChildAdded 方法,当孩子(新消息)只是添加到 ref 之前,并且独立于它实际到达/与服务器同步,即使电话处于离线状态,因此消息传递到服务器不是完全有保证,所以我不能在 onChildAdded 方法中更改状态。
所以我需要:
1. 将消息状态设置为“未读”并将其发送到 FirebaseDatabase,然后捕获它到达服务器的事件,然后才将该消息的本地存储副本更新为“未读”状态,
2. 或者以某种方式在服务器端设置 FirebaseDatabase 以在到达时更改消息状态,然后此更改将被 onChildChanged 捕获,该更改将更新本地存储的此消息的“未读”状态副本。
【问题讨论】:
标签: android firebase firebase-realtime-database kotlin