自定义Firebase Storage插件下Uppy Dashboard无进度/完成状态显示问题
核心问题与修复方案
1. 插件ID与组件引用不匹配
你的插件类中定义的ID是FirebaseCloudStorage,但<Dashboard>组件的plugins属性里写的是FirebaseCloudStoragePlugin,Uppy无法正确关联插件与UI组件,导致UI无法监听插件触发的上传事件。
修复:
将Dashboard的plugins参数改为插件实际ID:
<Dashboard uppy={uppy} plugins={['Webcam', 'FirebaseCloudStorage']} />
2. Object.assign语法错误
在上传成功回调中,你用Object.assign(file, 'downloadUrl', downloadUrl)试图给file对象添加属性,但Object.assign的正确语法是Object.assign(target, sourceObject),当前写法不会生效。
修复:
直接通过setFileState统一更新文件状态,包含下载链接和成功状态:
async () => { const downloadUrl = await getDownloadURL(uploadTask.snapshot.ref); // 用setFileState更新文件状态,符合Uppy状态管理规范 this.uppy.setFileState(id, { status: 'success', downloadUrl, uploadResponse: { url: downloadUrl } // 可选:符合Uppy上传结果格式 }); console.log('Upload success', { file: this.uppy.getFile(id), downloadUrl }); this.uppy.emit('upload-success', this.uppy.getFile(id), { url: downloadUrl }); resolve(); }
3. upload-success事件参数不符合Uppy规范
Uppy的upload-success标准参数为(file, response),你之前传递的(file, uploadTask.snapshot, downloadUrl)参数结构错误,导致UI组件无法解析上传成功状态。
修复:
按照规范传递参数,第二个参数为包含上传结果的对象,如上面代码中的{ url: downloadUrl }。
4. 可选:确保上传状态流转正确
虽然你已经触发了upload-started事件,可额外手动设置文件初始上传状态,确保UI能及时响应:
const file = this.uppy.getFile(id); // 手动设置文件为上传中状态 this.uppy.setFileState(id, { status: 'uploading' }); this.uppy.emit('upload-started', file);
5. 可选:React组件与Uppy实例生命周期同步
如果你的组件存在多次渲染的情况,建议使用@uppy/react提供的useUppy钩子在组件内部创建实例,避免全局实例导致的状态同步问题:
import { useUppy } from '@uppy/react'; const Uploader = () => { const uppy = useUppy(() => { const instance = new Uppy(); instance.use(FirebaseCloudStoragePlugin as any); instance.setOptions({ restrictions: { allowedFileTypes: ['video/*'] } }); return instance; }, []); // ... 其余组件逻辑 }
总结
优先修复前三个问题(插件ID匹配、Object.assign语法、upload-success参数规范),这是导致UI不更新的最直接原因。修复后进度条、状态栏应该能正常响应上传状态变化。
内容的提问来源于stack exchange,提问作者Benedict Chen

