iOS端点击按钮时如何调整Firebase SnapshotListener的查询限制数
实现方案
1. 新增类属性
首先在你的聊天页类中声明两个存储属性,分别记录当前查询上限和监听器实例:
// 记录当前查询的消息数量上限 private var currentMessageLimit: Int = 20 // 存储当前激活的Snapshot监听器,用于后续注销 private var messageListener: ListenerRegistration?
2. 改造原有监听方法
修改readAllMessages方法,每次调用前先注销旧监听器,使用动态的currentMessageLimit作为查询上限:
func readAllMessages() { // 注销旧监听器,避免重复触发回调 messageListener?.remove() let docRef = ref.collection("discussions").document(id) let messageQuery = docRef.collection("messages") .order(by: "dateCreated", descending: true) .limit(to: currentMessageLimit) // 保存新监听器的实例 messageListener = messageQuery.addSnapshotListener { [weak self] (snap, err) in guard let self = self, let documents = snap?.documents.reversed() else { print(err?.localizedDescription ?? "未知错误") return } self.messages = documents.compactMap { querySnapshot in return try? querySnapshot.data(as: Message_M.self) } } }
3. 实现加载更多逻辑
给按钮绑定点击事件,每次点击更新上限后重新调用监听方法即可:
// 按钮点击触发方法 @objc func loadMoreButtonTapped() { currentMessageLimit += 20 readAllMessages() }
4. 额外优化项
- 页面销毁时主动注销监听器,避免内存泄漏:
deinit { messageListener?.remove() }
- 可以在快照回调中判断返回的文档数量是否小于
currentMessageLimit,如果是则说明已经加载完全部消息,可禁用加载更多按钮避免无效请求。
原理解释
Firestore的查询参数在创建后无法动态修改,因此调整limit的本质是使用新的limit参数创建全新查询,注销旧监听器后绑定新监听器即可。Firestore自带本地缓存,已经拉取过的文档不会重复请求网络,整体性能开销极低。
内容的提问来源于stack exchange,提问作者Flincorp
相关产品推荐
相关产品推荐

