I am currently having trouble uploading an image/file to firestore. I have been stuck on this for hours now. I am using the latest version as well as the latest version of nextJS and reactJS. I am tried copying the docs but using both uploadString and uploadBytesResumable yield no success. I also tried various online tutorials. My rules are set in firestore such that anyone can read or write.
I can upload when there is no image selected in the filePickerRef
/imgFile
; however, when I include a file input along with my text input, only the text is uploaded. I am using a form with a button and an input to submit the text, when this is submitted, I check if there is a file uploaded (imgFile is a state that gets set when the file input tag is changed -- filePickerRef.current.files[0]
should also have the file but neither work...), if there is, I attempt to upload the file to the document I just added the message and timestamp to (Note: this file is uploaded to a file input outside of the form and when the input changes, it calls setImgFile(event.target.files[0])
. the input also has the prop ref='filePickerRef'
which was generated by the useRef()
hook).
The error I get is:
FirebaseError: Firebase Storage: An unknown error occurred, please check the error payload for server response. (storage/unknown)
with the response:
{
"error": {
"code": 404,
"message": "Not Found."
}
}
When I run the web tools debugger, I can see that both imgFile and filePickerRef.current.files[0]
have the File object of the file I selected to be uploaded, but the upload still fails.
Here is my code below:
const uploadMessage = (event) => {
event.preventDefault()
// no text input
if (!inputRef.current.value) return
addDoc(collection(db, 'msgs'), {
message: inputRef.current.value,
timestamp: serverTimestamp()
}).then(docRef => {
if (imgFile) {
//const file = filePickerRef.current.files[0]
const file = imgFile
// upload image
const storafeRef = ref(storage, `msgs/${docRef.id}`)
const uploadTask = uploadBytesResumable(storafeRef, file)
// note: imageToPost is state set by a file reader using readAsDataURL() when the file input changes
//uploadString(storafeRef, imageToPost, 'data_url').then(() => console.log('submitted image!'))
uploadTask.on("state_changed",
snapshot => {
const progress = Math.round((snapshot.bytesTransferred / snapshot.totalBytes) * 100)
setProgresspercent(progress)
},
error => {
alert(error)
},
() => {
getDownloadURL(uploadTask.snapshot.ref).then(url => {
setDoc(doc(db, 'msgs', docRef.id), { url }, { merge: true })
})
})
console.log('image uploaded.')
} else {
console.log('no image.')
}
console.log('Added doc: ', docRef.id)
}).then(() => {
inputRef.current.value = ''
setImageToPost(null)
setImgFile(null)
filePickerRef.current.value = ''
console.log('removed image.')
}).catch(error => {
console.error("Error adding document: ", error);
})
}
These are my firestore rules:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write;
}
}
}