Cloud Firestore嵌套集合批量写入无报错但未生效求助
问题分析与解决方案
你的代码无报错但未写入Firestore,核心原因是Cloud Functions未等待异步操作完成就提前终止,同时缺少错误处理导致问题被隐藏。以下是具体修复点和完整代码:
核心问题点
异步任务未被等待
functions.cloudEvent处理函数没有返回Promise,也未等待https.get和后续Firestore批量写入操作完成。Cloud Functions会在同步代码执行完毕后立即终止进程,导致后续异步写入被中断。无错误捕获机制
代码未对HTTP请求、数据解析、Firestore操作添加错误处理,即使出现网络异常、权限问题或数据格式错误,也无法在控制台看到报错信息。日期格式潜在风险
需确认Wordle API的日期格式是否严格匹配UTC日期(当前代码逻辑是正确的,但需验证请求URL是否能返回有效数据)。
修复后的完整代码
const functions = require('@google-cloud/functions-framework'); const https = require('https'); const { promisify } = require('util'); const admin = require("firebase-admin"); admin.initializeApp(); // 将https.get转为Promise形式,适配async/await const httpsGet = promisify(https.get); functions.cloudEvent('getWordleSolution', async () => { const incrementAndPad = (num) => { const str = String(num + 1); return str.padStart(2, "0"); } const now = new Date(); const year = now.getUTCFullYear(); const month = incrementAndPad(now.getUTCMonth()); const date = now.getUTCDate(); const url = `https://www.nytimes.com/svc/wordle/v2/${year}-${month}-${date}.json`; try { // 等待HTTP请求完成 const res = await httpsGet(url); let puzzleData = ""; // 等待数据流接收完成 await new Promise((resolve, reject) => { res.on("data", (chunk) => puzzleData += chunk); res.on('end', resolve); res.on('error', reject); }); const puzzle = JSON.parse(puzzleData); await writeToFirestore(puzzle); console.log('批量写入完成'); } catch (error) { console.error('执行出错:', error); throw error; // 抛出错误让Cloud Functions记录日志 } }); const writeToFirestore = async ({ id, solution, print_date }) => { const db = admin.firestore(); const batch = db.batch(); const leaderboardsRef = db.collection('leaderboards'); const leaderboardDocsSnapshot = await leaderboardsRef.get(); // 处理空集合场景 if (leaderboardDocsSnapshot.empty) { console.log('未找到任何leaderboard文档'); return; } leaderboardDocsSnapshot.forEach((snapshot) => { const contestsRef = snapshot.ref.collection('contests'); // Firestore会自动创建不存在的contests集合 batch.set(contestsRef.doc(id), { solution, print_date }); }); await batch.commit(); console.log(`成功写入${leaderboardDocsSnapshot.size}个contest文档`); };
关键修复说明
- Promise封装异步操作:将
https.get和数据流接收转为Promise,配合async/await确保Cloud Functions等待所有异步任务完成后再终止。 - 完整错误处理:通过
try/catch捕获全流程错误,确保异常能被日志记录,方便排查问题。 - 空集合处理:当
leaderboards集合为空时,提前返回并打印日志,避免无效操作。 - 自动创建集合:无需手动创建
contests集合,Firestore会在写入第一个文档时自动生成该集合,满足需求。
额外检查项
- 权限验证:确保Cloud Functions服务账号拥有
datastore.user或更高权限,具备Firestore写入权限。 - API可用性:本地测试请求URL是否能返回有效JSON数据,确认Wordle API可正常访问。
- 日志排查:在Cloud Functions控制台查看执行日志,确认是否有隐藏的错误信息。
内容的提问来源于stack exchange,提问作者Zach McNulty
相关产品推荐
相关产品推荐

