You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firebase认证登录时出现Uncaught TypeError错误求助

搞定「Uncaught TypeError: Cannot read property 'addEventListener' of null」这个报错

兄弟,这个报错我太熟了!本质就是你的JS代码在找一个根本不存在的DOM元素,然后想给它加事件监听,自然就报错了。结合你贴的代码,我帮你梳理两个最可能的原因,以及对应的解决办法:

原因一:DOM还没加载完,JS就提前跑了

虽然你把app.js放在了</body>前面,按说DOM应该已经渲染好了,但有时候浏览器的渲染节奏可能跟不上脚本执行速度,或者有缓存干扰。稳妥点的做法是把所有JS逻辑包裹在DOMContentLoaded事件里,确保页面所有元素都加载完成后再执行代码:

document.addEventListener('DOMContentLoaded', function() {
  // 把你原来的立即执行函数整个放进这里面
  (function() {
    // Initialize Firebase
    var config = {
      apiKey: "AIzaSyC3FyniOt7C2zKVISszaogAH4TknjnM3-s",
      authDomain: "fir-auth-546d6.firebaseapp.com",
      databaseURL: "https://fir-auth-546d6.firebaseio.com",
      projectId: "fir-auth-546d6",
      storageBucket: "fir-auth-546d6.appspot.com",
      messagingSenderId: "996823342440"
    };
    firebase.initializeApp(config);

    //Get elements
    const txtEmail = document.getElementById('txtEmail');
    const txtPassword = document.getElementById('txtPassword');
    const btnLogin = document.getElementById('btnLogin');
    const btnSignup = document.getElementById('btnSignup');
    const btnLogout = document.getElementById('btnLogout');

    //Add login event
    btnLogin.addEventListener('click', e => {
      const email = txtEmail.value;
      const pass = txtPassword.value;
      const auth = firebase.auth();
      const promise = auth.signInWithEmailAndPassword(email,pass);
      promise.catch(e => console.log(e.message));
    });

    btnSignup.addEventListener('click', e => {
      const email = txtEmail.value;
      const pass = txtPassword.value;
      const auth = firebase.auth();
      const promise = auth.createUserWithEmailAndPassword(email,pass).then(newUser => {
        firebase.database().ref('/userProfile').child(newUser.uid).set({email: email });
      });
      promise.catch(e => console.log(e.message));
    });

    btnLogout.addEventListener('click', e => {
      firebase.auth().signOut();
    });

    firebase.auth().onAuthStateChanged(firebaseUser => {
      if (firebaseUser) {
        // 先改DOM再跳转,不然跳转后代码就不执行了
        btnLogout.classList.remove('hide');
        window.location="sample.html";
      } else {
        console.log('not logged in');
        btnLogout.classList.add('hide');
      }
    });
  }());
});

原因二:跳转后的sample.html也引入了app.js

这个概率更大!你登录成功后跳转到sample.html,如果这个页面里也加了<script src="app.js"></script>,但sample.html里根本没有btnLogin、btnSignup这些按钮,代码执行时找不到这些元素,直接就报错了。

解决办法有两个:

  • 只在你的登录主页面引入app.js,sample.html里别加这行脚本
  • 或者给每个元素添加事件监听前先判断元素是否存在,避免报错:
// 处理登录按钮
const btnLogin = document.getElementById('btnLogin');
if (btnLogin) {
  btnLogin.addEventListener('click', e => {
    // 原有的登录逻辑
    const email = txtEmail.value;
    const pass = txtPassword.value;
    const auth = firebase.auth();
    const promise = auth.signInWithEmailAndPassword(email,pass);
    promise.catch(e => console.log(e.message));
  });
}

// 处理注册按钮
const btnSignup = document.getElementById('btnSignup');
if (btnSignup) {
  btnSignup.addEventListener('click', e => {
    const email = txtEmail.value;
    const pass = txtPassword.value;
    const auth = firebase.auth();
    const promise = auth.createUserWithEmailAndPassword(email,pass).then(newUser => {
      firebase.database().ref('/userProfile').child(newUser.uid).set({email: email });
    });
    promise.catch(e => console.log(e.message));
  });
}

// 处理登出按钮
const btnLogout = document.getElementById('btnLogout');
if (btnLogout) {
  btnLogout.addEventListener('click', e => {
    firebase.auth().signOut();
  });
}

另外提个小细节:你原来的onAuthStateChanged里,先执行了window.location="sample.html"再去改btnLogout的样式,这行改样式的代码其实根本不会生效,因为页面已经跳转走了,记得把顺序调换一下哦!

内容的提问来源于stack exchange,提问作者kiran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:37:10