Firestore带orderBy、limit的onSnapshot监听器能否直接调用off()解绑
结论
你在无查询参数的集合引用上调用off()的操作无法解绑当前监听器。
具体原因
Firestore的实时监听器是绑定在具体的查询实例上的:
- 你绑定监听器的对象是附加了
orderBy("timestamp")、limit(50)参数的查询实例,和你调用off()时使用的裸集合引用不是同一个实例,自然无法匹配到需要解绑的监听器。 - 即便你重新构造一个参数完全一致的新查询实例调用
off()也无法生效,因为每次调用查询方法返回的都是全新的实例,off()仅对当前实例上绑定的监听器生效。
正确解绑方式
方案1(官方推荐):存储onSnapshot返回的解绑函数
调用onSnapshot时会直接返回一个用于解绑当前监听器的函数,你只需要提前存储这个函数,需要解绑时直接调用即可:
// 存储解绑函数 const unsubscribeChat = firebase.firestore() .collection("chatrooms") .doc(`${chatId}`) .collection(`${chatId}`) .orderBy("timestamp") .limit(50).onSnapshot((snapshot) => { // 处理快照逻辑 }) // 需要解绑时直接调用 unsubscribeChat()
这种方式可以精准解绑单个监听器,即便同一个查询实例绑定了多个监听器也不会互相影响。
方案2:存储查询实例调用off()
如果你需要使用off()方法解绑,需要提前存储绑定时的查询实例,解绑时用同一个实例调用off():
// 提前存储查询实例 const chatQuery = firebase.firestore() .collection("chatrooms") .doc(`${chatId}`) .collection(`${chatId}`) .orderBy("timestamp") .limit(50) // 绑定监听器 chatQuery.onSnapshot(snapshot => { /* 逻辑 */ }) // 解绑当前查询实例上的所有监听器 chatQuery.off()
注意这种方式会解绑该查询实例上绑定的所有监听器,无法单独解绑某一个。
内容的提问来源于stack exchange,提问作者Kubaguette The Testobun
相关产品推荐
相关产品推荐

