I recently came across a Vue.js image uploader component that I am trying to repurpose (https://codesandbox.io/s/219m6n7z3j). This component allows users to upload images to Firebase storage and save the downloadURL to firestore for continuous rendering of the image on the screen even after refreshing. I have been working on adding a deleteImg() method to the component, but encountered the following error:
FirebaseError: Function CollectionReference.doc() requires its first argument to be of type non-empty string, but it was: undefined
Do you have any suggestions on how I can implement the deleteImg()
method to successfully remove an image from both storage and the database?
<template>
<div id="app">
<v-toolbar color="indigo" dark fixed app>
<v-toolbar-title>Vue Firebase Image Upload</v-toolbar-title>
</v-toolbar>
<v-app id="inspire">
<v-content>
<v-container fluid>
<v-layout align-center justify-center>
<v-flex xs12 sm8 md4>
<img :src="imageUrl" height="150" v-if="imageUrl" />
<v-text-field label="Select Image" @click="pickFile" v-model="imageName"></v-text-field>
<input type="file" style="display: none" ref="image" accept="image/*" @change="onFilePicked"/>
<v-btn color="primary" @click="upload">UPLOAD</v-btn>
</v-flex>
</v-layout>
<br />
<v-layout align-center justify-center>
<v-flex xs12 sm8 md4>
<div v-for="img in imgUrls" :key="img.id">
<br />
<img :src="img.downloadUrl" height="150" />
<v-btn @click="deleteImg(img.id)">x</v-btn>
</div>
</v-flex>
</v-layout>
</v-container>
</v-content>
</v-app>
</div>
</template>
<script>
import firebase from 'firebase'
import { db } from "./main";
export default {
name: "App",
data() {
return {
photo: null,
photo_url: null,
dialog: false,
imageName: "",
imageUrl: "",
imageFile: "",
imgUrls: []
};
},
created() {
this.getImages();
},
methods: {
getImages: function() {
db.collection("images")
.get()
.then(snap => {
const array = [];
snap.forEach(doc => {
array.push(doc.data());
});
this.imgUrls = array;
});
this.imageName = "";
this.imageFile = "";
this.imageUrl = "";
},
pickFile() {
this.$refs.image.click();
},
onFilePicked(e) {
const files = e.target.files;
if (files[0] !== undefined) {
this.imageName = files[0].name;
if (this.imageName.lastIndexOf(".") <= 0) {
return;
}
const fr = new FileReader();
fr.readAsDataURL(files[0]);
fr.addEventListener("load", () => {
this.imageUrl = fr.result;
this.imageFile = files[0]; // this is an image file that can be sent to server...
});
} else {
this.imageName = "";
this.imageFile = "";
this.imageUrl = "";
}
},
upload: function() {
var storageRef = firebase.storage().ref();
var mountainsRef = storageRef.child(`images/${this.imageName}`);
mountainsRef.put(this.imageFile).then(snapshot => {
snapshot.ref.getDownloadURL().then(downloadURL => {
this.imageUrl = downloadURL;
const bucketName = "xxx-xxxx-xxxxx.xxxxxxx.xxx";
const filePath = this.imageName;
db.collection("images").add({
downloadURL,
downloadUrl:
`https://firebasestorage.googleapis.com/v0/b/${bucketName}/o/images` +
"%2F" +
`${encodeURIComponent(filePath)}?alt=media`,
timestamp: Date.now()
});
this.getImages();
});
});
},
deleteImg(img) {
db.collection("images").doc(img).delete()
.then(() => {
console.log('Document successfully deleted')
})
.then(() => {
this.getImages()
})
}
},
components: {}
};
</script>
<style>
#app {
font-family: "Avenir", Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>