Problem Detaching Listener From Firestore Nested / Sub-collection
Solution 1:
You have to store in data
the function returned by the onSnapshot()
method and call this function in order to detach the listener.
In your existing code you are indeed declaring an unsubscribe
object in data
but you are not correctly assigning to it the function returned by the onSnapshot()
method (you should do that in the addListeners()
method) and you are not calling it correctly (you do this.unsubscribe
instead of this.unsubscribe()
).
I've not reproduced your full case, since it implies a Vuex store and some extra components but you will find below a similar code that demonstrates how it works (my settings are a bit different than yours -I use require("../firebaseConfig.js");
and fb.db.collection(channel)
- but you'll easily get the philosophy!):
<template>
<div>
<input v-model="currentChannel" placeholder="Enter Current Channel">
<p>CurrentChannel is: {{ currentChannel }}</p>
<div class="messagesList">
<li v-for="m in messages">{{ m.name }}</li>
</div>
</div>
</template>
<script>
const fb = require("../firebaseConfig.js");
export default {
data() {
return {
messages: [],
currentChannel: null,
listener: null //We store the "listener function" in the object returned by the data function
};
},
watch: {
currentChannel: function(newValue, oldValue) {
this.messages = [];
if (this.listener) {
this.listener(); //Here we call the "listener function" -> it detaches the current listener
this.addListeners(newValue);
} else {
this.addListeners(newValue);
}
}
},
methods: {
addListeners(channel) {
this.listener = fb.db.collection(channel).onSnapshot(snapshot => {
snapshot.docChanges().forEach(change => {
if (change.type == "added") {
let doc = change.doc;
this.messages.push({
id: doc.id,
name: doc.data().name
});
}
});
});
}
}
};
</script>
<style>
.messagesList {
margin-top: 28px;
}
</style>
So, if we try to apply this approach to your code, the modified code would be as follows:
<script>
import firestore from 'firebase/firestore'
import { mapGetters } from 'vuex'
import SingleMessage from './SingleMessage'
import MessageForm from './MessageForm'
export default {
name: 'messages',
components: {
SingleMessage,
MessageForm,
},
data() {
return {
channelsRef: firebase.firestore().collection('channels'),
messages: [],
channel: '',
unsubscribe: null
}
},
computed: {
...mapGetters(['currentChannel']),
},
watch: {
currentChannel: function(newValue, oldValue) {
this.messages = [];
if (this.unsubscribe) {
this.unsubscribe();
this.addListeners(newValue);
} else {
this.addListeners(newValue);
}
}
},
methods: {
addListeners(newValue) {
this.unsubscribe = this.channelsRef
.doc(newValue.id)
.collection('messages')
.onSnapshot(snapshot => {
snapshot.docChanges().forEach(change => {
if (change.type == 'added') {
let doc = change.doc
this.messages.push({
id: doc.id,
content: doc.data().content,
timestamp: doc.data().timestamp,
user: doc.data().user,
});
}
});
});
console.log('[addListeners] channel:', newValue.id)
}
}
}
</script>
Post a Comment for "Problem Detaching Listener From Firestore Nested / Sub-collection"