我正在为 React(使用 Redux)编写一个自定义 Firebase 存储插件,但我在使用库 Uppy 时遇到问题(特别是
@uppy/react
)。即使文件明显正在上传(根据控制台日志和显示的结果文件),用户界面也永远不会自行更新。实际上它似乎根本就没有动过。
知道会发生什么吗?
插件要点:https://gist.github.com/benedictchen/3a2fd82ccaf537e6bb1521dc46e4a70d
const uppy = new Uppy();
uppy.use(FirebaseCloudStoragePlugin as any)
// uppy.use(DragDrop, { allowed})
uppy.setOptions({
// autoProceed: false,
// allowMultipleUploads: true,
// debug: false,
restrictions: {
// maxNumberOfFiles: 20,
// minNumberOfFiles: 1,
allowedFileTypes: ['video/*'],
},
});
const Uploader = () => {
const handleDrop: DragEventHandler < HTMLDivElement > = (e) => {
e.preventDefault();
e.stopPropagation();
console.warn(e);
};
return (
<Box
sx={{
position: 'relative',
backgroundColor: 'red',
minHeight: 300,
borderRadius: 2
}}
onDrop={handleDrop}
>
<Dashboard uppy={uppy} plugins={['Webcam', 'FirebaseCloudStoragePlugin']} />
<ProgressBar uppy={uppy} />
<StatusBar uppy={uppy} />
</Box>
);
}```
Plugin
======
```typescript
import {
BasePlugin
} from '@uppy/core'
import {
Uppy,
UppyOptions
} from '@uppy/core';
import {
getAuth
} from 'firebase/auth';
import {
UploadTaskSnapshot,
getDownloadURL,
getStorage,
uploadBytesResumable,
ref,
} from 'firebase/storage';
import {
v4 as uuid
} from 'uuid';
const storage = getStorage();
export default class FirebaseCloudStoragePlugin extends BasePlugin {
constructor(uppy: Uppy, opts: UppyOptions) {
super(uppy, opts);
this.type = 'uploader';
this.id = 'FirebaseCloudStorage';
this.uploadFile = this.uploadFile.bind(this);
}
uploadFile(fileIds: string[]): Promise < any > {
return Promise.all(
fileIds.map((id) => {
return new Promise < void > ((resolve, reject) => {
const file = this.uppy.getFile(id);
const refId = uuid();
const userId = getAuth().currentUser?.uid;
const folder = userId ? `${userId}/` : '';
const storageRef = ref(storage, `${folder}${refId}-[::]-${file.name}`);
this.uppy.emit('upload-started', file);
const uploadTask = uploadBytesResumable(storageRef, file.data);
uploadTask.on(
'state_changed',
(snapshot: UploadTaskSnapshot) => {
const bytesUploaded = snapshot.bytesTransferred;
const bytesTotal = snapshot.totalBytes;
console.log(`progress happening: ${bytesUploaded}/${bytesTotal}`);
this.uppy.emit('upload-progress', file.id, {
uploader: this,
bytesUploaded,
bytesTotal,
});
},
(error: Error) => {
this.uppy.emit('upload-error', file, error);
reject(error);
},
async () => {
const downloadUrl = await getDownloadURL(uploadTask.snapshot.ref);
const file = this.uppy.getFile(id);
Object.assign(file, 'downloadUrl', downloadUrl);
this.uppy.setFileState(file.id, {
status: 'success'
});
console.log('Time to emit success', {
file,
downloadUrl
});
this.uppy.emit(
'upload-success',
file,
uploadTask.snapshot,
downloadUrl,
);
resolve();
}
);
});
})
);
}
install() {
this.uppy.addUploader(this.uploadFile);
}
uninstall() {
this.uppy.removeUploader(this.uploadFile);
}
}
我一直在阅读所有内容并四处探索。我似乎无法弄清楚这个奇怪的图书馆。 上传工作正常,但 UI 永远不会更新其状态。
我在分析了
Tus
上传者并弄清楚发生了什么之后就弄清楚了。
似乎有不同的事件需要按一定的顺序发出。我编写的代码缺少包含所有要上传的文件的
upload-start
事件。这导致 UI 处于奇怪的状态并且进度条永远不会显示。
uploadFile(fileIds: string[]): Promise<any>{
this.uppy.emit('upload-start', this.uppy.getFiles()); // <-- THIS