javascript - 如何从 Firebase 存储中删除 Vue.js 组件图像?

标签 javascript firebase vue.js google-cloud-storage vuetify.js

我正在构建一个 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/

相关文章:

javascript - 在javascript中动态生成行?

javascript - History back() 方法关闭新打开的选项卡

javascript - Firebase 函数返回并 promise 不退出函数

vue.js - v-cloak 在加载页面时不会隐藏组件

vue.js - Vue组件访问数据对象

javascript - Vue中如何访问子组件数据

javascript - Webpack 配置 - 添加另一个入口文件

javascript - 确定新数据是否可用的最佳方法

javascript - 上传成功后生成下载地址

firebase - Flutter Firebase 时间戳