Как указал Дуг в своем правильном ответе, нельзя, чтобы один слушатель получал обновления от неизвестного (количество или не указано) подколлекции.
Однако, если вы можете определить имена этих подколлекций, то ответ довольно прост.
Идея состоит в том, чтобы прочитать дочерние узлы каналов, которые будут являться channel_0, channel_1 и т. Д., И использовать эти идентификаторы документа для создания ссылок на узлы, которые вы хотите слушать.
Итак, учитывая эту структуру (которая соответствует структуре в вопросе):
Channels
channel_0
Messages
message_0
msg: "chan 0 msg 0"
message_1
msg: "chan 0 msg 1"
message_2
msg: "chan 0 msg 2"
channel_1
Messages
message_0
msg: "chan 1 msg 0"
message_1
msg: "chan 1 msg 1"
Вот код, который добавляет прослушиватели к каждому каналу и отвечает на события в этих каналах, сообщая в консоли идентификатор сообщения, текст сообщения и канал, в котором произошло событие.
func addChannelCollectionObserver() {
let channelsRef = self.db.collection("Channels")
channelsRef.getDocuments(completion: { snapshot, error in
guard let documents = snapshot?.documents else {
print("Collection was empty")
return
}
for doc in documents {
let docID = doc.documentID
let eachChannelRef = channelsRef.document(docID)
let messagesRef = eachChannelRef.collection("Messages")
messagesRef.addSnapshotListener { querySnapshot, error in
querySnapshot?.documentChanges.forEach { diff in
if diff.type == .added {
let doc = diff.document
let msgId = doc.documentID
let channelId = messagesRef.parent!.documentID
let msg = doc.get("msg") as? String ?? "no message"
print(" added msgId: \(msgId) with msg: \(msg) in channel: \(channelId)")
}
if diff.type == .modified {
let doc = diff.document
let msgId = doc.documentID
let msg = doc.get("msg") as? String ?? "no message"
print(" modified msgId: \(msgId) with msg: \(msg)")
}
if diff.type == .removed {
let doc = diff.document
let msgId = doc.documentID
let msg = doc.get("msg") as? String ?? "no message"
print(" removed msgId: \(msgId) with msg: \(msg)")
}
}
}
}
})
}
При первом запуске выходные данные будут показывать, как и ожидалось, каждый дочерний узел. С этого момента он будет выводить любые добавления, модификации или удаления.
added msgId: message_0 with msg: chan 0 msg 0 in channel: channel_0
added msgId: message_1 with msg: chan 0 msg 1 in channel: channel_0
added msgId: message_2 with msg: chan 0 msg 2 in channel: channel_0
added msgId: message_0 with msg: chan 1 msg 0 in channel: channel_1
added msgId: message_1 with msg: chan 1 msg 1 in channel: channel_1
код нуждается в дополнительной проверке ошибок для некоторых дополнительных функций, но он должен обеспечить решение.