Deleting images from Firestore using a Vue.js componentReady to learn how to remove images

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>

Answer №1

It appears that the doc.data() does not contain an 'id'. You will need to manually add the id to the data.

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

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Creating a JavaScript function that responds to multiple click events

Can someone please help me out? I have the link to the output of my work below using JavaScript and HTML: My goal is for only one circle to be active when clicked, while the others are disabled. Currently, when I click on a circle and then another one, bo ...

Is the button failing to direct you to the intended destination?

I'm facing an issue with a button tied to a JavaScript function using onClick(); My interface allows me to ban players on a game server, but when I select anyone here: https://i.stack.imgur.com/kcE1t.png, it always selects wartog for some reason. In ...

Having trouble creating a unit test for exporting to CSV in Angular

Attempting to create a unit test case for the export-to-csv library within an Angular project. Encountering an error where generateCsv is not being called. Despite seeing the code executed in the coverage report, the function is not triggered. Below is the ...

Cross-Origin Resource Sharing problem encountered with the webservice thumbnail.ws

I am attempting to create an HTML page that generates a snapshot of a URL using the free webservice provided by thumbnail.ws. Below is my code snippet: var myurl = "http://api.thumbnail.ws/api/API_KEY/thumbnail/get?url=http://maps.google.com/?q=36.82 ...

AngularJS - activating $watch/$observe event handlers

I am looking for a way to trigger all $watch/$observe listeners, even if the watched/observed value has not changed. This would allow me to implement a "testing only" feature that refreshes the current page/view without requiring user interaction. I have a ...

Using Jquery and Ajax to add information to a database

One of the challenges I'm facing involves a page with three forms, each containing separate variables that need to be inserted into a MySQL database for viewing. My current script is working fine, even though I am aware that `mySql_` is deprecated but ...

What is the best way to continuously loop the animation in my SVG scene?

After designing a SVG landscape with an animation triggered by clicking the sun, I encountered an issue where the animation only works once. Subsequent clicks do not result in any animation. Below is my current JavaScript code: const sun = document.getEle ...

Incorporate MUX Player (Video) into Angular versions 14 or 15

Mux offers a video API service with its own player: MUX Player I am interested in integrating this npm package specifically into a component in Angular 14/15. The JavaScript should only be loaded when this particular component is rendered. Integration Th ...

Ways to exchange information among Vue components?

My role does not involve JavaScript development; instead, I focus on connecting the APIs I've created to front-end code written in Vue.js by a third party. Currently, I am struggling to determine the hierarchy between parent and child elements when ac ...

Executing JavaScript code within a class object using ASP-VB

I'm looking to create a function that will show a Javascript-based notification. I already have the code for the notification, but I'm trying to encapsulate it in a class library as a function. However, I am unsure about what to return from the f ...

The select event in Vuetify's v-select component does not fire when clicking on an option with a custom

Currently, I am utilizing the beta version of Vuetify (v3.0.0-beta.6) due to the necessity of using Vue 3 which is not compatible with Vuetify 2.x. My objective is to create an i18n selector featuring country flag icons. For managing i18n functionalities ...

Manipulating HTML content with Javascript Array

Is there a way to retain Javascript context from an array? Any suggestions for improving this code? SAMPLE: <html> <script type="text/javascript"> var rand = Math.floor(Math.random() * 6) + 1; var i = Math.floor(Math.random() * 6) + 1; var ...

``After initialization, the service is unable to retrieve the object as

I have a special service that stores specific objects to be shared among different controllers. Here is an example of the code I am using: $rootScope.$on('controller.event', function(event, arg){ self.backendConnectorService.getBac ...

The authentication protocol, Next Auth, consistently provides a 200 status response for the signIn function

I ran into a challenge while building my custom login page using Next Auth. The issue arises when I try to handle incorrect login data. If the login credentials are correct, I am able to successfully send JWT and redirect to /dashboard. However, when the l ...

Occasionally, the map may take a moment to fully load

Update: Resolving the issue involved directly calling these two methods on the map object: leafletData.getMap().then(function(map) { map.invalidateSize(); map._onResize(); }); Encountering a minor yet bothersome problem with the Leaflet directive ...

Techniques for passing state values in Vuex post requests

I am working on a project where I need to collect data using get and set methods for my form. The goal is to post the states to an API. However, I am wondering how I can organize or group the states in order to pass them to an action. Any suggestions? st ...

Utilize AngularJS to retrieve and interact with the JSON data stored in a local file once it has

Please do not mark this as a duplicate since I have not found a solution yet. Any help would be appreciated. I have a file called category.json located next to my index.html file, containing the following JSON data: [{"name":"veg"},{"name","non-veg"}] W ...

Failure to receive a server response during the AJAX communication

I am facing an issue with my code that is making 3 requests to a server. The code successfully sends the request, but fails when receiving the response. I need help in skipping the first response and only getting the third one. phone.open("POST", '/& ...

Encountered an error while running the `npx-create-react-app my-app` command in

When attempting to run 'npx create-react-app my-app', the following error message is displayed: 'npx' is not recognized as the name of a cmdlet, function, script file, or operable program. Double check the spelling and path included to ...

Ensuring the legitimacy of Rails form submissions

I am encountering an issue with validating a form before submitting it, as the form is being submitted without triggering the jQuery part. <%= form_for(:session,class:"form-signin form-horizontal",:id=> "form",:role=> "form") do |f| %> & ...