【问题标题】:How do I push new data in an array stored in Firestore如何将新数据推送到存储在 Firestore 中的数组中
【发布时间】:2019-12-02 10:40:26
【问题描述】:

我的数据存储在 Firestore 中,如下所示:

其数据检索如下:

created () {
    db.collection('cards').where('user', '==', this.user)
      .get()
      .then(querySnapshot => {
        querySnapshot.forEach(doc => {
          const data = {
            'id': doc.id,
            'group_name': doc.data().group_name,
            'group': doc.data().group,
            'size': doc.data().group.length
          }
          this.cards.push(data)
        })
      })
  }

最后以如下方式渲染:

 <div v-for="(card, groupIndex) in cards" v-bind:key="card.id" class="card-group">....</div>

所有工作都按要求进行。问题是我如何将一个带有数据的新插槽添加到 firestore 中的group-array。在搜索了互联网之后,似乎无法将新数据推送到存储在 firestore 中的数组中。这是真的还是有可能?

如果不可能,我是否需要将我的数据存储为一个对象,我如何 v-for 使其内容真实?

完整代码如下:

<template>
  <div id="dashboard">
    <div style="margin-bottom: 50px">
      <div v-for="(card, groupIndex) in cards" v-bind:key="card.id" class="card-group">
      <div :id="card.group_name" class="card-group-header" @click="toggleChild" >{{card.group_name}}
        <div class="group-count-label"> {{card.size}} </div>
        <div class="right">
          <div :id="card.group_name + 'B'" class="dropdown-arrow"></div>
          <div style="margin-right:10px;font-size:15px">&#8942;</div>
          </div>
      </div>
        <div class="card-group-items hidden-group" :id="card.group_name + 'A'">
          <div v-for="(value, index) in card.group" v-bind:key="index" class="collection-item">
            <div :id="card.group_name + index" class="card-group-item-header" @click="toggleItem" >
              <div class="card-group-item-header-text">
                <div class="card-group-item-header-text-front">{{value.front}}</div>
                <div class="card-group-item-header-text-back">{{value.back}}</div>
              </div>
              <div class="right">
                <div :id="card.group_name + index + 'B'" class="dropdown-arrow-b"></div>
                <div style="margin:7px 10px 0px 0px;font-size:15px">&#8942;</div>
              </div>
            </div>
            <!-- ITEM -->
              <div :id="card.group_name + index + 'A'" class="card-group-item">
                <div>
                  <div class="textbox-tip">Front</div>
                  <input type="text" class="card-group-item-input" :value="value.front" spellcheck="false">
                </div>
                <div>
                  <div class="textbox-tip">Back</div>
                  <input type="text" class="card-group-item-input" :value="value.back" spellcheck="false">
                </div>
                <!-- CARD EXAMPLES -->
                <div class="card-group-examples">
                  <div class="card-group-example-header"><div>Examples</div><div class="card-group-example-header-plus" @click="addExample(groupIndex,index)">&#43;</div></div>
                  <div v-for="(v, i) in value.examples" v-bind:key="i">
                    <div>
                      <div class="textbox-tip">Example {{i+1}}</div>
                      <input type="text" class="card-group-item-input" :value="v.example" spellcheck="false">
                    </div>
                    <div>
                      <div class="textbox-tip">Answer {{i+1}}</div>
                      <input type="text" class="card-group-item-input" :value="v.answer" spellcheck="false">
                    </div>
                  </div>
                </div>
                <div class="card-group-item-footer">
                  <button class="button" @click="saveUpdate(groupIndex,index,card.id)" >SAVE CHANGES</button>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <button class="button" @click="test" >SAVE new</button>
    <div class="footer">
      <p>Footer</p>
    </div>
  </div>
</template>

<script>
import db from './firebaseInit'
export default {
  name: 'dashboard',
  data () {
    return {
      cards: [],
      user: 'kikker'
    }
  },
  created () {
    db.collection('cards').where('user', '==', this.user)
      .get()
      .then(querySnapshot => {
        querySnapshot.forEach(doc => {
          const data = {
            'id': doc.id,
            'group_name': doc.data().group_name,
            'group': doc.data().group,
            'size': doc.data().group.length
          }
          this.cards.push(data)
        })
      })
  },
  methods: {
    toggleChild (i) {
      var x = document.getElementById(i.target.id + 'A')
      var y = document.getElementById(i.target.id + 'B')
      if (x.style.display === 'none' || x.style.display === '') {
        x.style.display = 'block'
        y.style.webkitTransform = 'rotate(45deg)'
        y.style.margin = '5px 5px 0px 0px'
      } else {
        x.style.display = 'none'
        y.style.webkitTransform = 'rotate(-45deg)'
        y.style.margin = '7px 5px 0px 0px'
      }
    },
    toggleItem (i) {
      var x = document.getElementById(i.target.id + 'A')
      var y = document.getElementById(i.target.id + 'B')

      if (x.style.display === 'none' || x.style.display === '') {
        x.style.display = 'block'
        y.style.webkitTransform = 'rotate(45deg)'
        y.style.margin = '13px 5px 0px 0px'
      } else {
        x.style.display = 'none'
        y.style.webkitTransform = 'rotate(-45deg)'
        y.style.margin = '15px 5px 0px 0px'
      }
    },
    addExample (x, y) {
      this.cards[x].group[y].examples.push({
      })
    },
    saveUpdate (x, y, z) {
      console.log(z)
      db.collection('cards').doc(z).update({
        'age': 13,
        'favorites.color': 'Red'
      })
        .then(function () {
          console.log('Document successfully updated!')
        })
        .catch(function (error) {
          alert('Error updating document: (The document probably doesn\'t exist.: )', error)
        })
    },
    test () {
      console.log('vd')

      db.collection('cards').doc('BdSxtZL8V4S576i2BTRs').update({
        group: firebase.firestore.FieldValue.arrayUnion({ back: 'bla', front: 'blabla' })
      })

    }
  }
}
</script>

firebaseInit.js

import firebase from 'firebase'
import 'firebase/firestore'
import firebaseConfig from './firebaseConfig'
const firebaseApp = firebase.initializeApp(firebaseConfig)
export default firebaseApp.firestore()

firebaseConfig.js

export default {
  apiKey: 'blabla',
  authDomain: 'blabla',
  databaseURL: 'blabla',
  projectId: 'blabla',
  storageBucket: 'blabla.appspot.com',
  messagingSenderId: 'blabla',
  appId: 'blabla',
  measurementId: 'G-blabla'
}

更新内容:

firebaseInit.js

import firebase from 'firebase'
import 'firebase/firestore'
import firebaseConfig from './firebaseConfig'
const firebaseApp = firebase.initializeApp(firebaseConfig)
export default firebaseApp.firestore()

const db = firebaseApp.firestore()
const fieldValue = firebaseApp.firestore.FieldValue

export { db, fieldValue }

dahsboard.vue

<template>
  <div id="dashboard">
    <div style="margin-bottom: 50px">
      <div v-for="(card, groupIndex) in cards" v-bind:key="card.id" class="card-group">
      <div :id="card.group_name" class="card-group-header" @click="toggleChild" >{{card.group_name}}
        <div class="group-count-label"> {{card.size}} </div>
        <div class="right">
          <div :id="card.group_name + 'B'" class="dropdown-arrow"></div>
          <div style="margin-right:10px;font-size:15px">&#8942;</div>
          </div>
      </div>
        <div class="card-group-items hidden-group" :id="card.group_name + 'A'">
          <div v-for="(value, index) in card.group" v-bind:key="index" class="collection-item">
            <div :id="card.group_name + index" class="card-group-item-header" @click="toggleItem" >
              <div class="card-group-item-header-text">
                <div class="card-group-item-header-text-front">{{value.front}}</div>
                <div class="card-group-item-header-text-back">{{value.back}}</div>
              </div>
              <div class="right">
                <div :id="card.group_name + index + 'B'" class="dropdown-arrow-b"></div>
                <div style="margin:7px 10px 0px 0px;font-size:15px">&#8942;</div>
              </div>
            </div>
              <div :id="card.group_name + index + 'A'" class="card-group-item">
                <div>
                  <div class="textbox-tip">Front</div>
                  <input type="text" class="card-group-item-input" :value="value.front" spellcheck="false">
                </div>
                <div>
                  <div class="textbox-tip">Back</div>
                  <input type="text" class="card-group-item-input" :value="value.back" spellcheck="false">
                </div>
                <div class="card-group-examples">
                  <div class="card-group-example-header"><div>Examples</div><div class="card-group-example-header-plus" @click="addExample(groupIndex,index)">&#43;</div></div>
                  <div v-for="(v, i) in value.examples" v-bind:key="i">
                    <div>
                      <div class="textbox-tip">Example {{i+1}}</div>
                      <input type="text" class="card-group-item-input" :value="v.example" spellcheck="false">
                    </div>
                    <div>
                      <div class="textbox-tip">Answer {{i+1}}</div>
                      <input type="text" class="card-group-item-input" :value="v.answer" spellcheck="false">
                    </div>
                  </div>
                </div>
                <div class="card-group-item-footer">
                  <button class="button" @click="saveUpdate(groupIndex,index,card.id)" >SAVE CHANGES</button>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <button class="button" @click="test" >SAVE new</button>
    <div class="footer">
      <p>Footer</p>
    </div>
  </div>
</template>

<script>
import { db, fieldValue } from './firebaseInit'
export default {
  name: 'dashboard',
  data () {
    return {
      cards: [],
      user: 'kikker'
    }
  },
  created () {
    db.collection('cards').where('user', '==', this.user)
      .get()
      .then(querySnapshot => {
        querySnapshot.forEach(doc => {
          const data = {
            'id': doc.id,
            'group_name': doc.data().group_name,
            'group': doc.data().group,
            'size': doc.data().group.length
          }
          this.cards.push(data)
        })
      })
  },
  methods: {
    toggleChild (i) {
      var x = document.getElementById(i.target.id + 'A')
      var y = document.getElementById(i.target.id + 'B')
      if (x.style.display === 'none' || x.style.display === '') {
        x.style.display = 'block'
        y.style.webkitTransform = 'rotate(45deg)'
        y.style.margin = '5px 5px 0px 0px'
      } else {
        x.style.display = 'none'
        y.style.webkitTransform = 'rotate(-45deg)'
        y.style.margin = '7px 5px 0px 0px'
      }
    },
    toggleItem (i) {
      var x = document.getElementById(i.target.id + 'A')
      var y = document.getElementById(i.target.id + 'B')

      if (x.style.display === 'none' || x.style.display === '') {
        x.style.display = 'block'
        y.style.webkitTransform = 'rotate(45deg)'
        y.style.margin = '13px 5px 0px 0px'
      } else {
        x.style.display = 'none'
        y.style.webkitTransform = 'rotate(-45deg)'
        y.style.margin = '15px 5px 0px 0px'
      }
    },
    addExample (x, y) {
      this.cards[x].group[y].examples.push({
      })
    },
    saveUpdate (x, y, z) {
      console.log(z)
      db.collection('cards').doc(z).update({
        'age': 13,
        'favorites.color': 'Red'
      })
        .then(function () {
          console.log('Document successfully updated!')
        })
        .catch(function (error) {
          alert('Error updating document: (The document probably doesn\'t exist.: )', error)
        })
    },
    test () {
      console.log('vd')

      db.collection('cards').doc('BdSxtZL8V4S576i2BTRs').update({
        group: fieldValue.arrayUnion({ back: 'bla', front: 'blabla' })
      })
    }
  }
}
</script>

【问题讨论】:

    标签: firebase vue.js google-cloud-platform google-cloud-firestore


    【解决方案1】:

    如果我正确理解了您的问题,您应该使用arrayUnion() 方法:“数组中尚不存在的每个指定元素都将添加到(数组的)末尾”。 在documentation 中查看更多详细信息。

    为此,您需要:

    1. 将您的 firebaseInit.js 文件更改为:

          import firebase from 'firebase'
          import 'firebase/firestore'
          import firebaseConfig from './firebaseConfig'
          firebase.initializeApp(firebaseConfig)
      
          const db = firebase.firestore();
          const fieldValue = firebase.firestore.FieldValue;
      
          export { db, fieldValue };
      
    2. 如下调整你的组件代码:

          <script>
          import { db, fieldValue } from './firebaseInit'
          export default {
          name: 'dashboard',
          data () {
              return {
              cards: [],
              user: 'kikker'
              }
          },
          created () {
              db.collection('cards').where('user', '==', this.user)
              .get()
              .then(querySnapshot => {
                  querySnapshot.forEach(doc => {
                  const data = {
                      'id': doc.id,
                      'group_name': doc.data().group_name,
                      'group': doc.data().group,
                      'size': doc.data().group.length
                  }
                  this.cards.push(data)
                  })
              })
          },
          methods: {
              //....
              test () {
              console.log('vd')
      
              db.collection('cards').doc('BdSxtZL8V4S576i2BTRs').update({
                  group: fieldValue.arrayUnion({ back: 'bla', front: 'blabla' })
              })
      
              }
          }
          }
          </script>
      

    然后,如果您想在前端反映添加,Vue.js 有很多可能性(重新获取集合,设置侦听器,在写入 Firestore 的同时将其推送到本地数组, ETC。)。您需要详细说明您的确切功能要求。

    【讨论】:

    • 我正在尝试但收到错误firebase is not defined
    • 您必须将您使用的代码添加到您的问题中所有:从 Vue.js 中的 Firebase 配置到您写入 Firestore 的方式。
    • 能否请您也添加firebaseInit 文件的内容。你需要在那里导出firebase.firestore.FieldValue
    • @MK01111000 您有时间查看建议的解决方案吗?
    猜你喜欢
    • 1970-01-01
    • 2020-02-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-25
    • 1970-01-01
    • 1970-01-01
    • 2019-07-04
    • 1970-01-01
    相关资源
    最近更新 更多