如何在Firebase Functions中通过FTP下载文件并解决函数提前终止问题
问题根因
Firebase 定时触发函数会在你返回的 Promise 状态变为 fulfilled/rejected 后立即回收运行资源。你当前代码中的 FTP 操作全部基于回调事件实现,外层 async 函数没有等待这些回调执行就已经走完流程,返回的 Promise 提前结束,导致后续业务逻辑被中断。
修正后完整代码
exports.fifteenMinutesData = functions .runWith(runtimeOpts) .pubsub .schedule('*/15 * * * *') .timeZone('Etc/UTC') .onRun(async (context) => { // 把全链路FTP操作封装为可等待的Promise const handleFtpTask = () => { return new Promise((resolve, reject) => { const Client = require('ftp'); const c = new Client(); // 捕获FTP连接层面的错误 c.on('error', (err) => { c.end(); reject(err); }); c.connect({ host: "...", user: "..." }); c.on('ready', () => { c.get('text.txt', (err, stream) => { if (err) { c.end(); return reject(err); } let content = ''; stream.on('data', (chunk) => { content += chunk.toString(); }); stream.on('end', async () => { try { let data = content; // 此处放入你原有需要执行的全部业务逻辑 // 所有异步操作都要加await等待执行完成 // ...你的业务逻辑代码... // 全部逻辑执行完成后resolve c.end(); resolve(); } catch (logicErr) { c.end(); reject(logicErr); } }); // 捕获流读取过程中的错误 stream.on('error', (streamErr) => { c.end(); reject(streamErr); }); }); }); }); }; try { // 等待整个FTP任务+业务逻辑全部执行完成 await handleFtpTask(); console.log('定时任务执行完成'); return null; } catch (err) { console.error("定时任务执行失败: ", err); return null; } });
核心修改点
- 将FTP连接、文件拉取、流式读取、业务处理全链路封装为标准Promise,所有异常场景(连接错误、文件拉取错误、流读取错误、业务逻辑错误)统一走reject,正常执行完成走resolve,保证执行状态完全可控
- 入口函数直接await封装后的Promise,确保所有业务逻辑执行完成前,函数返回的Promise不会结束,Firebase不会提前回收运行资源
- 所有场景执行完成后主动关闭FTP连接,避免资源泄漏
- 统一的错误捕获逻辑,不会出现未处理异常导致函数意外退出
内容的提问来源于stack exchange,提问作者TheProgrammer
相关产品推荐
相关产品推荐

