Firebase onAuthStateChange的unsubscribe失效问题求助
问题
我尝试调用unsubscribe()来停止onAuthStateChanged监听,但没生效。代码如下:
var unsubscribe = firebase.auth().onAuthStateChanged((user) => { unsubscribe() readCourses(user.uid) // 函数1:读取数据 addElement(user) // 函数2:写入数据更新信息 })
我希望函数1(对应代码里的lecturaCursos)只执行一次,所以想停止监听用户状态,但点击函数2的按钮时,函数1会再次执行,导致数据库信息重复。以下是完整相关代码:
var espacioforCards=document.getElementById('espacioCards')// Div var nombreCurso; var descripcionCurso; var obtenerNombreCurso=document.getElementById('obtener nombre curso')//button function lecturaCursos(uid){ console.log('leyendo...datos') var cursos = dbRef.ref("Usuarios").child(uid).child("cursos") cursos.on('value', (snapshot) => { if (snapshot.exists()){ //spinner document.getElementById("spinner").style.visibility = "visible"; snapshot.forEach((childSnapshot) => { crearTarjeta(childSnapshot.val().nombre,childSnapshot.val().descripcion) }) document.getElementById("spinner").style.visibility = "hidden"; }else{ console.log('No hay datos') document.getElementById("spinner").style.visibility = "hidden"; } }); } function crearCurso(userRef,nombreCurso,descripcionCurso){ userRef.child('cursos').update({[nombreCurso]:{'nombre': nombreCurso, 'descripcion': descripcionCurso}}) } function crearTarjeta(nombreCurso,descripcionCurso){ let card = document.createElement("div") card.setAttribute("class","card") card.setAttribute('style', 'width: 15rem; margin:5px') card.setAttribute("id", nombreCurso); card.innerHTML+='<img src="img/nuevosm.jpg"class="card-img-top" alt="..."></img>' let cardbody = document.createElement("div") cardbody.innerHTML+= '<h5 class="card-title">'+nombreCurso+'</h5>' cardbody.innerHTML+= '<p class="card-text">'+descripcionCurso+'</p>' cardbody.innerHTML+='<a href="#" class="btn btn-primary">al curso</a>' card.appendChild(cardbody) espacioforCards.appendChild(card) } function addElement (user) { console.log('adding elements...........') obtenerNombreCurso.addEventListener("click", function(){ nombreCurso=document.getElementById('nombre del curso').value descripcionCurso=document.getElementById('descripcion del curso').value if(Boolean(nombreCurso) && Boolean(descripcionCurso)){ crearTarjeta(nombreCurso,descripcionCurso) let userRef=dbRef.ref('Usuarios').child(user.uid) crearCurso(userRef,nombreCurso,descripcionCurso) //location.reload(true) }else{ console.log('you must fill in') } }) }
解决方案
1. 替换持续监听器为单次读取
你当前的lecturaCursos用了cursos.on('value', ...),这会持续监听数据库cursos节点的变化——每次调用crearCurso写入新数据时,回调都会触发,导致重复创建卡片。
要实现仅读取一次数据,把on换成once:
function lecturaCursos(uid){ console.log('leyendo...datos') var cursos = dbRef.ref("Usuarios").child(uid).child("cursos") // 用once替代on,仅执行一次数据读取 cursos.once('value', (snapshot) => { if (snapshot.exists()){ document.getElementById("spinner").style.visibility = "visible"; snapshot.forEach((childSnapshot) => { crearTarjeta(childSnapshot.val().nombre,childSnapshot.val().descripcion) }) document.getElementById("spinner").style.visibility = "hidden"; }else{ console.log('No hay datos') document.getElementById("spinner").style.visibility = "hidden"; } }); }
2. 修正unsubscribe调用时机
你现在在onAuthStateChanged回调里直接调用unsubscribe(),此时unsubscribe可能未完全初始化。正确做法是在确认用户存在并执行完逻辑后调用:
var unsubscribe = firebase.auth().onAuthStateChanged((user) => { if (!user) return; // 用户未登录时直接返回 readCourses(user.uid) addElement(user) // 执行完必要逻辑后取消监听 unsubscribe() })
3. 避免重复绑定点击事件
每次onAuthStateChanged触发时,addElement都会给按钮绑定一次点击事件,多次触发会导致点击一次执行多次逻辑。添加标志位确保仅绑定一次:
// 新增标志位,防止重复绑定事件 let isEventBound = false function addElement (user) { console.log('adding elements...........') if (isEventBound) return; // 已绑定则直接返回 obtenerNombreCurso.addEventListener("click", function(){ nombreCurso=document.getElementById('nombre del curso').value descripcionCurso=document.getElementById('descripcion del curso').value if(Boolean(nombreCurso) && Boolean(descripcionCurso)){ crearTarjeta(nombreCurso,descripcionCurso) let userRef=dbRef.ref('Usuarios').child(user.uid) crearCurso(userRef,nombreCurso,descripcionCurso) }else{ console.log('you must fill in') } }) isEventBound = true; // 标记为已绑定 }
内容的提问来源于stack exchange,提问作者organizacion courses
相关产品推荐
相关产品推荐

