Vydia / react-native-background-upload

Upload files in your React Native app even while it's backgrounded. Supports Android and iOS, including camera roll assets.
MIT License
735 stars 336 forks source link

Video file uploads but corrupted in S3 - Multipart upload #331

Closed aleksandar-zoric-workvivo closed 1 year ago

aleksandar-zoric-workvivo commented 1 year ago

The file uploads (3.2mb in size, mp4 extension), I get no error. But when I preview the record in S3, the size listed is 136.0 B.

When I download the file from S3, it's corrupted.

...
try {
        const file = isIOS ? filePath : filePath.replace("file://", "");
        const fileInfo = await RNBackgroundUpload.getFileInfo(file);

        const headers = {
            "Content-Type": "multipart/form-data",
            "Content-length": fileInfo.size.toString()
        };

        // file key is an object, stringify it. 
        const formData = authObject?.formData._parts.reduce(
            (obj, [key, value]) => {
                obj[key] = key === "file" ? JSON.stringify(value) : value;
                return obj;
            },
            {}
        );

        const options = {
            url: authObject?.api,
            path: file,
            parameters: formData,
            headers: headers,
            method: "POST",
            field: key,
            type: "multipart",
            maxRetries: 2,
            notification: {
                enabled: true,
                autoClear: true,
                onProgressTitle: "Uploading",
                onProgressMessage: "Uploading your video",
                onCompleteTitle: "Completed",
                onCompleteMessage: "Video uploaded successfully"
            }
        };

        const resolveUpload = function (uploadId) {
            return new Promise((resolve, reject) => {
                let l1 = RNBackgroundUpload.addListener(
                    "error",
                    uploadId,
                    data => {
                        reject(data);
                        cleanup();
                    }
                );
                let l2 = RNBackgroundUpload.addListener(
                    "cancelled",
                    uploadId,
                    data => {
                        reject(data);
                        cleanup();
                    }
                );
                let l3 = RNBackgroundUpload.addListener(
                    "completed",
                    uploadId,
                    data => {
                        console.log("Upload complete");
                        resolve(data);
                        cleanup();
                    }
                );
                RNBackgroundUpload.addListener("progress", uploadId, data => {
                    onProgress(data.progress, fileInfo.size);
                });
                let cleanup = () => {
                    l1.remove();
                    l2.remove();
                    l3.remove();
                };
            });
        };

        let res;
        let responseData = null;

        try {
            const uploadId = await RNBackgroundUpload.startUpload(options);
            res = await resolveUpload(uploadId);
        } catch (err) {
            throw {
                status: -1,
                _error: err,
                data: {
                    code: null,
                    detail: null,
                    message: "Network error"
                }
            };
        }

        responseData = res.responseBody;

        if (res.responseCode >= 400) {
            const errorRes = {
                data: responseData,
                status: res.responseCode,
                _response: res
            };
            return errorRes;
        } else {
            const dataRes = {
                data: responseData,
                status: res.responseCode,
                _response: res
            };
            return dataRes;
        }
    } catch (error) {
        console.log("Generic Error: ", error);
    }
aleksandar-zoric-workvivo commented 1 year ago

Resolved: Issue was my field property in the options object. The key property contained special characters, it was long etc. when I changed it to just "file" - it worked. Not sure on the logic behind it but that was the only change.