简体   繁体   English

如何使用 Vue.js 删除嵌套的 Firebase 数据

[英]How to delete nested Firebase data with Vue.js

I am attempting to build a Vue.js component that enables deleting of nested Firebase data.我正在尝试构建一个 Vue.js 组件,该组件可以删除嵌套的 Firebase 数据。 My component currently looks like the following:我的组件目前如下所示:

<v-flex v-for="user in users" :key="user.id" xs12 md12>
  <v-layout row wrap>
    <v-flex v-for="newUser in user.gallery" :key="newUser.id" xs12 sm6 md3>
      <v-img :src="newUser.image" />
      <v-btn @click="deleteImg(newUser.id)">x</v-btn>
    </v-flex>
  </v-layout>
</v-flex>

This component uses a v-for directive to first loop through all Firebase items returned to the users array.该组件使用 v-for 指令首先循环遍历所有返回到users数组的 Firebase 项目。 The second v-for directive loops through all of the images inside a nested Firebase array called gallery .第二个 v-for 指令循环遍历名为gallery的嵌套 Firebase 数组中的所有图像。 The delete button is intended to target the id of each image (newUser.id) inside the nested gallery array.删除按钮旨在定位嵌套gallery数组中每个图像 (newUser.id) 的 id。 Here is the deleteImg() method:这是deleteImg()方法:

    deleteImg (img) {
      db.collection('users').doc(img).delete()
    }

When I click the deleteImg() button, I get the following handler error:当我单击deleteImg()按钮时,我收到以下处理程序错误:

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

How can I adjust the deleteImg() handler to properly target images based on id in the nested array?如何调整deleteImg()处理程序以根据嵌套数组中的 id 正确定位图像? Thanks!谢谢!

******REVISION****** ******修订******

Here is the full code for a better example of what I am trying to accomplish.这是我想要完成的更好示例的完整代码。 Basically, this component is set up to push new input into an array called events (which already exists as a document field in Firebase), and then then return those array items in user.events to the screen.基本上,该组件设置为将新输入推送到一个名为events的数组中(它已经作为 Firebase 中的文档字段存在),然后将user.events中的这些数组项返回到屏幕。 As you can see in the screenshot below, those inputted items are stored in the events array.正如您在下面的屏幕截图中所见,这些输入的项目存储在事件数组中。 Those array items render on the screen just fine.这些数组项在屏幕上渲染得很好。 I am attempting to delete those array items, but am not sure how to properly target them.我正在尝试删除这些数组项,但不确定如何正确定位它们。 How can I configure the deleteInput() method to target those array items?如何配置deleteInput()方法以定位这些数组项?

<template>
  <div class="input">
    <input v-model="newInput" />
    <button @click.prevent="addInput()">submit</button>
    <br><br>
    <div v-for="user in users" :key="user.id">
      <div v-for="newUser in user.events" :key="newUser.id">
        <h3>{{ newUser.name }}</h3>
        <button @click="deleteInput(newUser.id)">x</button>
      </div>
    </div>
  </div>
</template>

<script>
import firebase from 'firebase'
import { db } from '@/main'
export default {
  name: 'HelloWorld',
  data: () => ({
    newInput: null,
    users: []
  }),
  mounted () {
    this.getData()
  },
  methods: {
    async getData () {
      let snapshot = await db.collection('users').get()
      const users = []
      snapshot.forEach(doc => {
        let appData = doc.data()
        appData.id = doc.id
        users.push(appData)
      })
      this.users = users
    },
    async addInput () {
      let finalInput = this.newInput
      let querySnapshot = await db.collection('users').where('user_id', '==', firebase.auth().currentUser.uid).get()
        querySnapshot.forEach(function(doc) {
          doc.ref.update({'events': firebase.firestore.FieldValue.arrayUnion({
            'name': finalInput
          })
        })
      })
      this.newInput = ''
      this.getData()
    },
    deleteInput (item) {
      db.collection('users').doc(item).delete()
    }
  }
}
</script>

在此处输入图像描述

There are two pieces of code in your question (somehow two linked but different questions): an initial one and one after the REVISION.您的问题中有两段代码(不知何故是两个链接但不同的问题):最初的一段和 REVISION 之后的一段。

Let's first give the answer for the initial question: with your Vue.js component code you need to have a users array that looks like:让我们首先给出第一个问题的答案:使用 Vue.js 组件代码,您需要一个users数组,如下所示:

  users: [
    {
      id: 1,
      gallery: [
        { id: 11, image: "http://...image1.jpg" },
        { id: 12, image: "http://...image2.jpg" },
        { id: 13, image: "http://...image3.jpg" }
      ]
    },
    {
      id: 2,
      gallery: [
        { id: 21, image: "http://...image1.jpg" },
        { id: 22, image: "http://...image2.jpg" },
        { id: 23, image: "http://...image3.jpg" }
      ]
    }
  ]

It means you have to "construct" your Firestore documents in such a way they return an array with this format.这意味着您必须“构造”您的 Firestore 文档,使其返回具有这种格式的数组。


For the second problem (after the REVISION sub-title):对于第二个问题(在 REVISION 子标题之后):

You should use the optional second argument of v-for to get the index of the current item and call the deleteInput() with this index value plus the user.id , as follows:您应该使用v-for的可选第二个参数来获取当前项目的索引,并使用此index值加上user.id调用deleteInput() ,如下所示:

<div v-for="user in users" :key="user.id">
  <div v-for="(newUser, index) in user.events" :key="newUser.id">
    <h3>{{ newUser.name }}</h3>
    <button @click="deleteInput(user.id, index)">x</button>
  </div>
</div>

Then in deleteInput() you need to然后在deleteInput()你需要

either任何一个

overwrite the events array for the user (with id == user.id) with a new events array, in which you have deleted the element at position index ,用一个新的events数组覆盖userevents数组(id == user.id),您在其中删除了 position index处的元素,

or或者

use the arrayRemove() method with the entire object (events, email, name, etc...).对整个 object(事件、email、名称等)使用arrayRemove()方法。

I would opt for the first approach.我会选择第一种方法。

Note that depending on your exact use case you may have to do that in a transaction, to be sure the events array was not modified between the initial read and the modifciation.请注意,根据您的确切用例,您可能必须在事务中执行此操作,以确保在初始读取和修改之间未修改events数组。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM