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

Next.js14+TS+Firebase:工单系统筛选已提交工单学生的问题

问题排查与优化方案

核心问题分析

你的hasTicket始终无法正确判断,核心原因是数据结构与判断逻辑不匹配:

  • 根据业务描述,学生提交工单后,student/{studentId}/tickets/{ticketName}文档的结构应为{ content: true }(content是布尔值而非对象)
  • 但你当前代码错误地判断typeof ticketData.content === "object",这会直接导致整个逻辑与表达式返回false,无法正确识别content的布尔值

另外,若你目标是统计提交指定工单的学生,当前遍历所有工单文档的逻辑存在冗余,无需遍历学生的所有工单。

修复后的代码实现

方案1:针对单个指定工单的统计(精准匹配)

如果要统计提交了某一特定工单(比如targetTicketName = "作业提交工单")的学生,直接查询对应工单文档即可:

// 目标工单名称
const targetTicketName = "你的目标工单名称";

// 获取学生集合数据
const studentsSnapshot = await getDocs(collection(db, "student"));
const studentsDetailsArray = [];

for (const studentDoc of studentsSnapshot.docs) {
  const studentId = studentDoc.id;
  const raisedTickets = { studentId, hasSubmittedTargetTicket: false };

  // 直接查询该学生是否提交了目标工单
  const ticketDocRef = doc(db, "student", studentId, "tickets", targetTicketName);
  const ticketDoc = await getDoc(ticketDocRef);

  // 判断文档存在且content为true
  if (ticketDoc.exists() && ticketDoc.data().content === true) {
    raisedTickets.hasSubmittedTargetTicket = true;
  }

  studentsDetailsArray.push(raisedTickets);
}

// 更新状态
setStudents(studentsDetailsArray);

方案2:修复原逻辑(兼容遍历所有工单场景)

如果需要统计学生提交的所有工单数量,或检查是否提交过任意工单,只需修正hasTicket的判断逻辑:

const ticketsRef = collection(db, "student", studentId, "tickets");
const ticketsSnapshot = await getDocs(ticketsRef);

let hasSubmittedAnyTicket = false;
let submittedTicketCount = 0;

ticketsSnapshot.forEach((ticketDoc) => {
  const ticketData = ticketDoc.data();
  // 直接判断content是否为true(匹配实际数据结构)
  const hasTicket = ticketData.content === true;

  if (hasTicket) {
    hasSubmittedAnyTicket = true;
    submittedTicketCount++;
  }
});

const raisedTickets = {
  studentId,
  hasSubmittedAnyTicket,
  submittedTicketCount
};

studentsDetailsArray.push(raisedTickets);

额外优化建议

  1. 类型安全:为Firebase数据定义TypeScript接口,避免类型判断错误:
interface StudentTicketDoc {
  content: boolean;
}

// 使用时断言类型
const ticketData = ticketDoc.data() as StudentTicketDoc;
  1. 性能优化:如果学生数量较多,用Promise.all并行查询工单文档,提升加载速度:
const studentPromises = studentsSnapshot.docs.map(async (studentDoc) => {
  const studentId = studentDoc.id;
  const ticketDocRef = doc(db, "student", studentId, "tickets", targetTicketName);
  const ticketDoc = await getDoc(ticketDocRef);
  return {
    studentId,
    hasSubmittedTargetTicket: ticketDoc.exists() && ticketDoc.data().content === true
  };
});

const studentsDetailsArray = await Promise.all(studentPromises);

内容的提问来源于stack exchange,提问作者ice-weasel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 11:47:12