问题
I am using Firebase child_added to watch for new entries being added to my database.
It seemed to work for a while but then I noticed some issues when leaving the connection idle. If I leave my app open for a prolonged period of time when Firebase returns duplicates. I think it maybe down to the connection being dropped and then established.
Here is my code.
getVoicemailList: function() {
var self = this;
var userId = firebase.auth().currentUser.uid;
firebase.database().ref('voicemails/' + userId).on('child_added', function(snapshot) {
var voicemail = snapshot.val();
self.addToCollection(voicemail.callerID, voicemail.timeReceived, voicemail.transcription, voicemail.audioURL);
});
},
addToCollection: function(callerID, timeReceived, transcription, audioURL) {
console.log(callerID)
var collectionList = $('.collapsible').length;
if(!collectionList) {
$('#main-content').append('<ul class="collapsible" data-collapsible="accordion"></ul>')
}
var output = '<li>';
output += '<div class="collapsible-header"><i class="material-icons">filter_drama</i>'+callerID+'</div>';
output += '<div class="collapsible-body">';
output += '<p><audio id="source" controls>';
output += '<source src="'+audioURL+'" type="audio/mpeg">';
output += '</audio></p>';
output += '<p>'+timeReceived+'</p>';
output += '<p>'+transcription+'</p>';
output += '</div>';
output += '</li>';
$('.collapsible').append(output);
$('.collapsible').collapsible();
},
回答1:
If I understand your issue correctly, then it's something I've come across a few times. I believe the trick is to .empty() the existing data from within the .on call.
As an example, on my site we have goals that users can add. When they add a new Goal the .on call adds a new Goal to the bottom of their list.
I was having an issue where deleting a Goal would then duplicate the UI data.
In order to address the issue, I moved $(#goals").empty(); to within the .on call.
firebase.database().ref('users/' + user).on('value', function(snapshot) {
$("#goals").empty(); // This removes all all previously added goals
snapshot.forEach(function(data) {
var id = data.key;
var desc = data.val().desc;
var url = data.val().url || "https://unsplash.it/400?image=" + getRandomNumber();
displayGoal(id,desc,url);
});
// If you need to append anything after all the data has been added you can do it here. e.g. $("#goals").append("</div>");
});
I suspected that doing this would force all relevant UI items to reload but they don't. If I add a Goal it just pops up on the bottom of the list, if I remove a Goal the UI just removes the goal without any reloading or duplication.
So in your case you would add $('.collapsible').empty(); after the .on call and before var voicemail = snapshot.val();.
Note: Previously I would call $("#goals").empty() prior to the .on call.
来源:https://stackoverflow.com/questions/37668683/firebase-child-added-event-listener-returning-duplicate-data