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

如何在获取Firebase用户信息后再执行JavaScript函数?

解决方案:调整代码结构确保用户认证后再初始化jsGrid并加载数据

核心问题分析

  1. 页面DOM加载完成后立即初始化jsGrid,此时用户认证流程可能还未完成,导致getData无法获取用户相关权限或数据。
  2. _db被包裹在自执行函数内部,属于局部变量,全局环境无法直接访问;若将onAuthStateChanged放入该函数块,又会因作用域或执行顺序问题导致_db未被正确识别。

具体调整步骤


1. 重构index.js:以认证状态为核心驱动,修复作用域问题

调整Firebase初始化、认证监听和数据逻辑的顺序,将_db改为全局可访问的变量,确保只有用户登录后才初始化数据控制器:

// 先初始化Firebase核心实例
const firebaseConfig = {
  // 填写你的Firebase配置信息
};
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
const db = getFirestore(app);
const db_name = "tesint";
const collectionRef = collection(db, db_name);

// 全局声明_db,后续在认证完成后赋值
let _db;

async function getData(filter) {
  // 先校验用户登录状态
  const user = auth.currentUser;
  if (!user) throw new Error("用户未登录,无法获取数据");
  
  // 你的数据查询逻辑,可结合filter和用户信息(如user.uid)过滤数据
  const querySnapshot = await getDocs(collectionRef);
  return querySnapshot.docs.map(doc => ({ ...doc.data(), uid: doc.id }));
}

// 监听用户认证状态变化,这是核心触发点
onAuthStateChanged(auth, (user) => {
  if (user) {
    console.log('用户已登录');
    // 用户登录后才初始化数据控制器
    _db = {
      loadData: function(filter) {
        return getData(filter);
      }
    };
    // 触发jsGrid初始化
    initJsGrid();
  } else {
    console.log('用户未登录');
    // 未登录时隐藏表格或提示登录
    if ($("#jsGrid").length) {
      $("#jsGrid").hide();
    }
  }
});

// 登录/登出按钮逻辑
const provider = new GoogleAuthProvider();
const signInBtn = document.getElementById("signInBtn");
const signOutBtn = document.getElementById("signOutBtn");

signInBtn.onclick = () => {
  signInWithPopup(auth, provider)
    .then((result) => {
      console.log('登录成功:', result.user);
    })
    .catch((error) => {
      console.error('登录失败:', error);
      alert(`登录错误:${error.message}`);
    });
};

signOutBtn.onclick = () => {
  signOut(auth).then(() => {
    console.log('用户已登出');
    $("#jsGrid").hide();
  });
};

// 暴露全局函数,供认证回调触发jsGrid初始化
window.initJsGrid = function() {
  $("#jsGrid").jsGrid({
    width: "100%",
    height: "90%",
    heading: true,
    insertRowLocation: "top",
    loadMessage: "请稍候...",
    noDataContent: "暂无数据,请尝试刷新",
    filtering: true,
    editing: true,
    inserting: true,
    sorting: false,
    paging: true,
    autoload: true,
    confirmDeleting: true,
    pageSize: 15,
    pageButtonCount: 5,
    pageLoading: true,
    deleteConfirm: "确定要删除这行吗?",
    controller: _db,
    fields: [              
      { name: "name", type: "text", width: 150 },
      { name: "uid", type: "number", width: 200 },                    
      { type: "control", align: "center"}
    ]
  });
  $("#jsGrid").show();
};

2. 修改index.html:移除提前初始化逻辑,等待认证触发

删除原来DOM加载时立即初始化jsGrid的代码,改为等待用户登录后通过全局函数触发:

<!DOCTYPE html>
<html>
<head>
  <!-- 先引入依赖库 -->
  <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid.min.css" />
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid-theme.min.css" />
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid.min.js"></script>
  
  <!-- 引入Firebase SDK -->
  <script src="https://www.gstatic.com/firebasejs/9.23.0/firebase-app-compat.js"></script>
  <script src="https://www.gstatic.com/firebasejs/9.23.0/firebase-auth-compat.js"></script>
  <script src="https://www.gstatic.com/firebasejs/9.23.0/firebase-firestore-compat.js"></script>
  
  <script src="./index.js"></script>
</head>
<body class="myclass">
  <!-- 登录/登出按钮 -->
  <button id="signInBtn">登录</button>
  <button id="signOutBtn">登出</button>
  
  <!-- jsGrid容器,默认隐藏 -->
  <div id="jsGrid" style="display:none;"></div>
</body>
</html>

关键调整说明

  • 认证优先:通过onAuthStateChanged监听用户状态,确保只有登录后才初始化数据控制器和表格,避免未认证时调用数据接口。
  • 作用域修复:将_db改为全局变量,在认证回调中赋值,彻底解决局部作用域无法访问的问题。
  • 延迟初始化:jsGrid不再随DOM加载自动初始化,而是等待用户登录后触发,从根源避免了数据加载与认证不同步的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 09:25:07