===================
我考虑了一会儿,并在问题末尾提出了一个可能的解决方案,您认为这可行吗?
===================
我正在使用Firebase实时数据库来支持我的iOS应用中的聊天。我在数据库中有一个名为“对话”的节点,其结构如下:
-conversations
-user_id_1 // This is you
-recipient_id_1 // id of the user who's chatting with you
-message_id_1
-message: <some_message>
-date: <some_date>
-message_id_2
-message: <some_message>
-date: <some_date>
-recipient_id_2
-message_id_1
-message: <some_message>
-date: <some_date>
-message_id_2
-message: <some_message>
-date: <some_date>
每当有新消息发送给用户时,他都会收到通知。
我曾考虑过使用推送通知,即我使用Cloud Function Trigger来观察路径:
functions.database.ref('conversations/{uid}/{recipientId}/{messageId}').onCreate((snapshot) => {
// Send push notification to user with "uid"
})
但是,这有一个问题,如果用户阻止了应用程序的推送通知该怎么办?用户在不使用应用程序时不会收到任何消息(这是他希望通过关闭推送通知来实现的),但是即使在应用程序中,他也不会收到任何消息。因此,我在想,也许我应该在应用中使用Firebase SDK来观察数据库,如下所示:
Database
.database().reference()
.child("conversations").child(<my_user_id>)
.observe(.childAdded) { (snapshot) in
// do stuff with snapshot
}
但是,这只会观察到新近开始的对话,即,如果用户已经与“ person1”进行了对话,而“ person1”向用户发送了新消息,则不会触发该观察者。然后,我在想:
首先,请保留上述观察者,以便在开始新的对话时得到通知
其次,创建其他多个监听我的现有对话的观察者:
Database
.database().reference()
.child("conversations").child(<my_user_id>).child(<existing_recipient_id>)
.observe(.childAdded) { (snapshot) in
// do stuff with snapshot
}
但是这样,我怎么知道我所有的“ existing_recipient_id”?我当然不应该在启动时获取它们:
Database
.database().reference()
.child("conversations").child(<my_user_id>)
.observeSingleEvent(of: .value) { (snapshot) in
// Extract all "existing_recipient_id"
}
因为这会获取我所有的会话及其消息,这些消息可能是数GB。
我有以下两个问题:
如果我与1000个人进行了1000次对话,那么我应该有1000个应用内观察者吗?如果这不会造成任何问题,例如性能问题,那么我该如何设置这些观察者,从而避免出现上述问题?
我肯定在使用推送通知,以防在新消息发送给用户时用户不在应用程序中。但是,我不知道该用户是否在应用程序中,如果他已经在应用程序中,则推送通知似乎是多余的,这会增加成本。有办法避免这种情况吗?
临时解决方案
编写一个云函数,该函数将获取所有“ existing_recipient_id”,这只是一个字符串数组。
在该应用程序中,我添加了一个监听器,用于监视设备的连接状态,无论何时该设备从脱机状态恢复为联机状态,还是在应用程序首次启动时,我都调用该云函数来获取所有现有对话的ID。
为每个对话添加观察者
添加观察者以收听新对话
但是我仍然不知道当用户在应用内时如何处理推送通知,我想即使多余,我也会这么做