我正在构建一个 Vue.js 组件,该组件支持在 Firebase 上上传和删除图像。到目前为止,我的组件可以将图像上传到数据库和存储。该图像只能从数据库中删除,但仍保留在存储中。为了解决这个问题,我尝试设置 deleteImg()
函数,并使用 .then()
promise 将存储中的图像作为删除目标。文档中的示例(“https://firebase.google.com/docs/storage/web/delete-files”)设置为针对硬编码图像。如何设置删除功能以删除删除按钮所针对的特定图像?这是我的删除功能:
deleteImg(img) {
db.collection("images").doc(img).delete()
.then(() => {
var storageRef = firebase.storage().ref();
var desertRef = storageRef.child('images/Desert.jpg');
desertRef.delete().then(function() {
console.log('Document successfully deleted')
}).catch(function(error) {
console.log(error)
});
})
.then(() => {
this.getImages()
})
}
这是整个组件:
<template>
<div id="app">
<v-app-bar color="indigo" dark fixed app>
<v-toolbar-title>Vue Firebase Image Upload</v-toolbar-title>
</v-app-bar>
<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 => {
const data = doc.data()
array.push({
id: doc.id,
...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`,
originalName: this.imageName,
timestamp: Date.now()
});
this.getImages();
});
});
},
deleteImg(img) {
db.collection("images").doc(img).delete()
.then(() => {
var storageRef = firebase.storage().ref();
var desertRef = storageRef.child('images/Desert.jpg');
desertRef.delete().then(function() {
console.log('Document successfully deleted')
}).catch(function(error) {
console.log(error)
});
})
.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>
更新了删除功能
async deleteImg(img) {
let imgDBRef = await db.collection("images").doc(img).get()
let imgFileName = imgDBRef.exists ? imgDBRef.data().originalName : null;
let storageRef = firebase.storage().ref();
let desertRef = storageRef.child('images/' + imgFileName);
desertRef.delete()
db.collection("images").doc(img).delete()
this.getImages()
}
最佳答案
我认为您应该尝试将图像文件名保存到数据库中,以便能够将其映射到存储项。
从此处添加imageName
:
storageRef.child(`images/${this.imageName}`);
到db.collection("images").add(..)
函数参数对象:
db.collection("images").add({
downloadURL,
originalName: this.imageName,
});
然后在您的deleteImg
函数中从db.collection("images").doc(img)
文档数据获取originalName
像这样的东西:
const imgDBRef = db.collection("images").doc(img).get();
const imgFileName = imgDBRef.exists ? imgDBRef.data().originalName : null;
//... here should be your checks for image name nullable state etc.
const storageRef = firebase.storage().ref();
const desertRef = storageRef.child('images/' + imgFileName);
最好将文件名存储为哈希值,而不是真实名称。
关于javascript - 如何从 Firebase 存储中删除 Vue.js 组件图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57395614/