0

I'm working on implementing the Background Fetch API in my Vue project to enable file uploads to an S3 bucket. The goal is to allow the upload process to continue even if the user closes the screen, which is particularly useful for a mobile web application. This functionality ensures that file uploads are completed successfully in the background, providing a seamless user experience without interruption.

This is my sample code: In service-worker.js:

self.addEventListener("install", (event) => { event.waitUntil(console.log("Service worker installing")); }); self.addEventListener("activate", (event) => { console.log("Service Worker activating."); }); self.addEventListener("fetch", (event) => { console.log("This is fetch"); }); self.addEventListener("backgroundfetchsuccess", async (event) => { const bgFetch = event.registration; const records = await bgFetch.matchAll(); for (const record of records) { const response = await record.responseReady; if (!response.ok) { throw new Error(`Error response status: ${response.status}`); } console.log(`File uploaded successfully: ${response.status}`); } console.log("Background fetch success:", event); }); self.addEventListener("backgroundfetchfail", async (event) => { console.log("Background fetch fail:", event); }); self.addEventListener("backgroundfetchabort", async (event) => { console.log("Background fetch abort:", event); }); 

And this is my upload function:

const uploadFile = async () => { if (!selectedFile.value) { message.value = "No file selected"; return; } message.value = "Generating presigned URL..."; let presignedUrl; try { const s3Client = new S3Client({ region: s3Config.region, credentials: { accessKeyId: s3Config.accessKeyId, secretAccessKey: s3Config.secretAccessKey, }, }); const command = new PutObjectCommand({ Bucket: s3Config.bucketName, Key: selectedFile.value.name, ContentType: selectedFile.value.type, }); presignedUrl = await getSignedUrl(s3Client, command, { expiresIn: 3600 }); } catch (error) { message.value = `Error generating presigned URL: ${error.message}`; return; } message.value = "Uploading..."; if ("BackgroundFetchManager" in self) { try { const swReg = await navigator.serviceWorker.ready; console.log("Service Worker ready:", swReg); const bgFetch = await swReg.backgroundFetch.fetch( "upload-file-abc", [ new Request(presignedUrl, { method: "PUT", body: selectedFile.value, headers: { "Content-Type": selectedFile.value.type }, }), ], { title: "File Upload", downloadTotal: selectedFile.value.size, } ); bgFetch.addEventListener("progress", (event) => { if (!event.uploadTotal || !event.uploaded) return; const percent = Math.round((event.uploaded / event.uploadTotal) * 100); console.log(`Upload progress: ${percent}%`); }); } catch (error) { message.value = `Error uploading file: ${error.message}`; } } else { message.value = "Background Fetch API not supported"; } }; 

When I try to upload the file it triggers: Background fetch fail event Am I missing something..?

1 Answer 1

0

I successfully implemented a POST API to upload files, and it works well for files up to 10MB. However, I'm facing an issue when trying to upload larger files (above 10MB).

I attempted to use the PUT method to upload files, but unfortunately, it didn't work. I suspect that the API doesn't handle PUT requests.

If anyone has experience with this issue or knows a solution, please share your ideas. I'd appreciate any help in resolving this problem.

 const request = new Request(url, { method: "POST", body: formData, }); const reg = await navigator.serviceWorker.ready; console.log("Reg", reg); startTime.value = Date.now(); console.log("Start time", startTime.value); const bgFetchReg = await reg.backgroundFetch.fetch("my-upload", [request], { uploadTotal: formData.size, downloadTotal: 0, title: "Uploading file", icons: [{ src: "./movie.png", sizes: "192x192", type: "image/png" }], }); bgFetchReg.addEventListener("progress", () => { console.log("Upload progressing "); const uploaded = bgFetchReg.uploaded; const uploadedMB = uploaded / (1024 * 1024); console.log(`Uploaded size: ${uploadedMB.toFixed(2)} MB`); const uploadTotal = bgFetchReg.uploadTotal; const uploadTotalMB = uploadTotal / (1024 * 1024); console.log(`Total size to upload: ${uploadTotalMB.toFixed(2)} MB`); const progress = (uploaded / uploadTotal) * 100; console.log(`Upload progress: ${progress.toFixed(2)}%`); });

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.