JS_is_awesome18
JS_is_awesome18

Reputation: 1757

How to delete images from Firestore with Vue.js component

I am attempting to repurpose a Vue.js image uploader component that I found earlier (https://codesandbox.io/s/219m6n7z3j). This component enables uploading of images to Firebase storage, as well as the saving of the downloadURL to firestore in order to allow the image to continually render on the screen even after refreshing. I have been trying to add a deleteImg() method to the component, but am getting the error:

FirebaseError: Function CollectionReference.doc() requires its first argument to be of type non-empty string, but it was: undefined

Any recommendations on how to set up the deleteImg() method so that it removes the 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>

Upvotes: 0

Views: 429

Answers (1)

ittus
ittus

Reputation: 22403

I guess there is no id available in doc.data(), you need to add id manually

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 = ""
},

Upvotes: 1

Related Questions