启动Firebase Cloud Storage上传400ms后暂停触发未知错误
Firebase Cloud Storage 上传暂停操作延迟触发时的未知错误解决方案
问题背景
使用Firebase Cloud Storage的uploadBytesResumable进行文件上传时,出现以下异常表现:
- 调用上传后400ms内执行
uploadTask.pause():上传可正常暂停,无错误抛出 - 调用上传后400-500ms执行
uploadTask.pause():控制台抛出FirebaseError: Firebase Storage: An unknown error occurred, please check the error payload for server response. (storage/unknown),但实际上传已成功暂停
上传功能本身正常,仅该时间窗口内的暂停操作触发错误。
原代码片段:
async function uploadFile() { // file comes from a file input html element const uploadTask = uploadBytesResumable(ref(cloudStorage, `videos/${file.name}`), file); uploadTask.on("state_changed", (snapshot) => { const uploadProgress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100; // Update progress state setProgress(Math.floor(uploadProgress)); switch (snapshot.state) { case "paused": console.log("Upload paused"); break; case "running": console.log("Upload resumed"); break; } }, (e) => { console.log("an error occurred...", e.serverResponse, e); }, () => { console.log("upload completed!"); }); // 400ms内暂停:正常无错误 setTimeout(() => { uploadTask.pause(); }, 400); // 500ms后暂停:抛出未知错误 setTimeout(() => { uploadTask.pause(); }, 500); }
错误栈信息:
an error occurred... <empty string> FirebaseError: Firebase Storage: An unknown error occurred, please check the error payload for server response. (storage/unknown) FirebaseError errors.ts:85 StorageError error.ts:40 unknown error.ts:126 backoffDone request.ts:163 triggerCallback backoff.ts:67 responseHandler backoff.ts:91 node_modules bundle.js:45348 promise callback*doTheRequest request.ts:113 node_modules bundle.js:45038 setTimeout handler*callWithDelay backoff.ts:72 start backoff.ts:136 start_ request.ts:184 node_modules bundle.js:45309 NetworkRequest request.ts:76 makeRequest request.ts:273 _makeRequest service.ts:309 node_modules bundle.js:47029 node_modules bundle.js:46971 promise callback*_resolveToken task.ts:211 _continueUpload task.ts:296 node_modules bundle.js:46956 setTimeout handler*_start task.ts:195 completeTransitions_ task.ts:477 node_modules bundle.js:46992 promise callback*./node_modules/ bundle.js:46988 node_modules bundle.js:46971 promise callback*_resolveToken task.ts:211 _createResumable task.ts:233 _start task.ts:186 node_modules bundle.js:46919 UploadTask task.ts:156 uploadBytesResumable$1 reference.ts:291 uploadBytesResumable api.ts:167 initiateTransaction TimeStampTest.js:12 React 23 js index.js:7 factory react refresh:6 Webpack3 TimeStampTest.js:40
可能原因
该时间窗口对应上传任务的初始化过渡阶段:此时SDK刚完成resumable token的获取,开始发起实际的文件分片上传请求,pause()操作与网络请求的回调逻辑产生状态同步冲突,导致SDK误抛出未知错误,但实际上传任务已正确暂停。
解决方案
方案1:过滤暂停操作导致的误报错误
在错误回调中,结合当前上传任务的状态判断是否为暂停触发的假错误,直接忽略:
(e) => { // 当任务已处于暂停状态,且错误为storage/unknown时,判定为误报 if (uploadTask.snapshot.state === 'paused' && e.code === 'storage/unknown') { console.log("忽略暂停操作触发的误报错误"); return; } console.log("真实上传错误:", e.serverResponse, e); }
方案2:确保在稳定的运行状态下执行暂停
通过监听任务状态,等待任务进入running状态并稳定后,再允许执行暂停操作,避免在初始化阶段调用:
async function uploadFile() { const uploadTask = uploadBytesResumable(ref(cloudStorage, `videos/${file.name}`), file); let isTaskStableRunning = false; uploadTask.on("state_changed", (snapshot) => { const uploadProgress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100; setProgress(Math.floor(uploadProgress)); switch (snapshot.state) { case "paused": console.log("Upload paused"); break; case "running": // 延迟标记任务进入稳定运行状态,跳过初始化阶段的瞬间 setTimeout(() => { isTaskStableRunning = true; }, 100); console.log("Upload resumed"); break; } }, (e) => { console.log("真实上传错误:", e.serverResponse, e); }, () => { console.log("upload completed!"); }); // 仅当任务处于稳定运行状态时执行暂停 setTimeout(() => { if (isTaskStableRunning) { uploadTask.pause(); } else { // 若仍在初始化阶段,延迟后再尝试暂停 setTimeout(() => uploadTask.pause(), 100); } }, 500); }
方案3:升级Firebase SDK到最新版本
该问题可能是Firebase Storage SDK的已知bug,后续版本已修复。执行以下命令升级依赖:
npm install firebase@latest
内容的提问来源于stack exchange,提问作者MasterpieceKODZ
相关产品推荐
相关产品推荐

