To explain what I want to do, I want the user:
Workflow:
- to be able to upload files to Firebase storage,
- The detail of that file is stored in Firestore using .set(),
- user see the name of the file on text input (loads from Firestore) and the user can download the file
No. (1) and (3) I have successfully done it, except no. (2). The doc itself, which contain the detail of the uploaded file, is not there in the Firestore. No errors show up that say it is failed to add the docs to Firestore, only just a warning like the attached image below.
To add, yesterday, I already deploy an update of the same workflow for my live web app, on one of the pages, (Let's say: Page A). It works as I wanted, from (1) to (3). Now I want to do the same workflow on other pages, (e.g. Page B, C, etc).
Today, on the localhost, on any part of my app including Page A, my app cannot add a doc of the uploaded file into Firestore. But when I do it on the live web app, it works and it still is.
Already gone through the internet and there are almost the same questions as me, but none of them works for me. Any advice?
HTML part
<v-row style="margin-left: 1%;">
<v-col cols="12" sm="6" md="12">
<h2>Program Summary</h2>
<h4>Upload the program summary of the package here.</h4>
</v-col>
</v-row>
<v-row style="margin-left: 1%;" v-if="fileUploaded">
<v-col cols="12" sm="6" md="4">
<v-text-field
v-model="editedItem.fileName"
outlined
readonly></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="3">
<v-btn
color="yellow"
dark
medium
style="margin: 0.5rem;"
@click.prevent="downloadFile()">
View
</v-btn>
</v-col>
</v-row>
<v-row style="margin-left: 1%;" v-else>
<v-col cols="12" sm="6" md="4">
<v-file-input
outlined
show-size
prepend-icon="null"
accept=".pdf"
v-model="ProgramSummary"
:disabled="processing">
<template v-slot:append-outer>
<v-progress-circular
v-if="processing"
indeterminate
color="red">
</v-progress-circular>
</template>
</v-file-input>
</v-col>
<v-col cols="12" sm="6" md="3">
<v-btn
color="primary"
dark
style="margin: 0.5rem;"
@click.prevent="uploadProgramSummary()">
Upload
</v-btn>
</v-col>
</v-row>
upload file and add detail of file into Firestore
// SAVE UPLOADED FILE TO FIRESTORE
onUpload() {
var uidRef = firebase.auth().currentUser.uid;
//var docName = `${this.ProgramSummary.name}`;
var docRef = firestore
.collection("SubworkPackage")
.doc(firebase.auth().currentUser.uid)
.collection("ProgramSummary")
.doc();
var data = {
fileName: this.ProgramSummary, // <--- this get the file name to firestore
uid: uidRef,
id: docRef,
};
firestore
.collection("SubworkPackage")
.doc(firebase.auth().currentUser.uid)
.collection("ProgramSummary")
.doc(firebase.auth().currentUser.uid)
.set(data);
},
// PROGRAM SUMMARY UPLOAD FILE
uploadProgramSummary() {
//LOADING ICON SET TO TRUE
this.processing = true;
//DOC REFERENCE OF USER ID
var uidRef = firebase.auth().currentUser.uid;
// DOC NAME IS SET TO HAVE A FIXED NAME
var programSummaryRef = "ProgramSummary.pdf";
// FILE PATH
var filePath = `WorkPackageContractor/${uidRef}/${programSummaryRef}`;
var docName = `${this.ProgramSummary.name}`;
// METADATA
const metadata = { contentType: this.ProgramSummary.type };
//FIREBASE STORAGE ACTION
FirebaseStorage
.ref()
.child(filePath)
.put(this.ProgramSummary, metadata)
.then(() => {
FirebaseStorage
.ref()
.child(filePath)
.put(this.ProgramSummary, metadata)
.snapshot
.ref
.getDownloadURL()
.then(() => { // url
//this.ProgramSummary = url;
this.ProgramSummary = docName;
this.onUpload();
this.processing = false;
alert("Program Summary Succesfully Uploaded!")
window.location.reload();
})
})
},
download file from Firebase Storage
downloadFile() {
var uidRef = firebase.auth().currentUser.uid;
var programSummaryRef = "ProgramSummary.pdf";
var filePath = `WorkPackageContractor/${uidRef}/${programSummaryRef}`;
const fileRef = FirebaseStorage.ref().child(filePath);
fileRef
.getDownloadURL()
.then((url) => {
console.log(url);
const xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.onload = function() {
const blob = xhr.response;
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = "Program Summary";
link.click();
URL.revokeObjectURL(link.href);
};
xhr.open('GET', url);
xhr.send();
}).catch((error) => {
// Handle any errors
switch (error.code) {
case 'storage/object-not-found':
// File doesn't exist
break;
case 'storage/unauthorized':
// User doesn't have permission to access the object
break;
case 'storage/canceled':
// User canceled the upload
break;
case 'storage/unknown':
// Unknown error occurred, inspect the server response
break;
default:
break;
}
});
},
Read uploaded file detail from Firestore, inside created(),
readFileInput() {
let _this = this;
firestore
.collection("SubworkPackage")
.doc(firebase.auth().currentUser.uid)
.collection("ProgramSummary")
.doc(firebase.auth().currentUser.uid)
.get()
.then(doc => {
if (doc.exists) {
_this.fileUploaded = true;
_this.editedItem.fileName = doc.data().fileName
} else {
_this.fileUploaded = false;
console.log("No Document Exists");
}
})
},
Notes:
- I want the detail of the uploaded file to be added in Firestore after the file is uploaded.
- I'm using Nuxt.js v2 and Firebase v8.10.0
- It works on my live hosting web app but not on the localhost (I want to deploy the latest today update to see if it really happens just on localhost, but nope, I dont want for it to broke my current live hosting web app too if anything went wrong).
- Already tried
experimentalForceLongPolling
,experimentalAutoDetectLongPolling
,useFetchStreams
. still not working.