React应用中如何在Firestore的子集合中添加子集合?
解决Firestore中为已有预算添加expenses子集合的问题
你当前代码出现错误的核心原因是expense.budgetId没有正确获取到addBudget生成的自动预算ID,导致Firestore在路径中找不到对应ID的预算文档时,自动创建了一个空的"幽灵文档"(你看到的ID为1的新预算其实是未正确赋值的budgetId对应的空文档)。
步骤1:修改addBudget函数,返回自动生成的预算ID
调用addDoc会返回一个DocumentReference对象,其中包含Firestore自动生成的文档ID。修改函数如下,把ID返回给调用方,方便后续关联支出:
const addBudget = async (budget: Budget, userId: string): Promise<string> => { const budgetRef = await addDoc(collection(db, 'users', userId, 'budgets'), { name: budget.name, max: budget.max }); // 返回自动生成的预算ID return budgetRef.id; };
步骤2:确保expense.budgetId持有正确的预算ID
在创建支出前,先调用addBudget获取有效的预算ID,再将其赋值给expense.budgetId,之后再执行添加支出的操作:
// 示例调用流程 const userId = "当前用户的ID"; const newBudget: Budget = { name: "餐饮预算", max: 2000 }; // 先创建预算,拿到自动生成的ID const budgetId = await addBudget(newBudget, userId); // 创建支出对象并传入正确的budgetId const newExpense: Expense = { description: "午餐", expenseValue: 50, budgetId: budgetId // 这里必须是已存在的预算ID }; // 添加支出到对应预算的expenses子集合 await addExpense(newExpense, userId);
步骤3:优化addExpense函数(可选)
可以在addExpense中添加校验逻辑,避免传入无效ID或在不存在的预算下创建支出,同时简化集合路径的写法:
const addExpense = async (expense: Expense, userId: string) => { // 校验budgetId是否存在 if (!expense.budgetId) { throw new Error("budgetId不能为空"); } // 先检查目标预算文档是否存在,避免生成幽灵文档 const budgetDocRef = doc(db, 'users', userId, 'budgets', expense.budgetId); const budgetDocSnap = await getDoc(budgetDocRef); if (!budgetDocSnap.exists()) { throw new Error("对应的预算文档不存在"); } // 直接基于预算文档引用创建expenses子集合 await addDoc(collection(budgetDocRef, 'expenses'), { description: expense.description, expenseValue: expense.expenseValue }); };
内容的提问来源于stack exchange,提问作者blackrox
相关产品推荐
相关产品推荐

