我通过以下方式设置了Firestore:
频道[集合] ----> channelID->消息[集合]-> messageID
如何将snapshotListener添加到子集合“消息”中?
Firestore.firestore().collection("Channels").document().collection("Messages").addSnapshotListener { (querySnapshot, error) in
guard let snapshot = querySnapshot else {
print("Error listening for channel updates: \(error?.localizedDescription ?? "No error")")
return
}
snapshot.documentChanges.forEach { change in
print(change)
}
}
这对我不起作用
答案 0 :(得分:2)
您不可能只有一个侦听器从未知数量的子集合中接收更新。集合中没有用于侦听器的“通配符”运算符。您必须选择一个特定的集合或查询,并在其上附加一个侦听器。
答案 1 :(得分:1)
正如道格在正确答案中指出的那样,您无法让单个侦听器接收到来自未知子集(数量不明或未指定)的更新。
但是,如果可以确定那些子集合名称,那么答案就非常简单了。
想法是读取Channels的子节点,它们将是channel_0,channel_1等,并使用这些文档ID来建立对您有兴趣收听的节点的引用。
因此,给出此结构(与问题中的结构匹配):
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"
这是将侦听器添加到每个频道的代码,并响应该频道中的事件,并在控制台中通知消息ID,msg文本和事件发生所在的频道。
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
对于某些可选选项,代码还需要进行其他错误检查,但它应该提供解决方案。
答案 2 :(得分:0)
为此,请使用collection group query来收听所有具有相同名称的收藏集
db.collectionGroup("Messages"). docRef.addSnapshotListener(new EventListener<DocumentSnapshot>() {
@Override
public void onEvent(@Nullable DocumentSnapshot snapshot,
@Nullable FirestoreException e) {
if (snapshot != null && snapshot.exists()) {
System.out.println("Current data: " + snapshot.getData());
} else {
System.out.print("Current data: null");
}
}
});
答案 3 :(得分:-1)
我认为是因为
Firestore.firestore().collection("Channels").document().collection("Messages")
您未定义正确的CollectionReference,因为您未标识“渠道”集合的文档。
您应该这样做:
Firestore.firestore().collection("Channels").document(channelID).collection("Messages")