0

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>

1 Answer 1

1

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 = ""
},
Sign up to request clarification or add additional context in comments.

2 Comments

thanks so much! This works specifically for the doc in the database. The images are removed from the screen and from the Firestore database. However, the images still remain in storage. I attempted to add a .then() promise to the deleteImg() function that also removes the image from storage. I set up the promise based on this example (firebase.google.com/docs/storage/web/delete-files). However, I am not sure how to configure this promise to enable deleting of targeted images. Any tips on how to set this up? Thanks again!
@Frank van Puffelen, thank you for updating the layout of the question. Would you be able to take a look at the next issue as well? I am attempting to also enable removal of images from storage. Any tips on how to set this up? Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.