【问题标题】:Firestore onSnapshot duplicates all DOM elements instead of replacing/updating themFirestore onSnapshot 复制所有 DOM 元素,而不是替换/更新它们
【发布时间】:2020-02-05 03:19:23
【问题描述】:

我正在更新我的数据库中的信息,我希望这些数据能够更新我用来实时显示数据的卡片。这很好用,但是当我对数据库进行更改时,我用来显示信息的卡片只会在每次更改时重复。

我希望它替换/更新我正在显示的卡片但它会制作一张新卡片并将其与所有旧卡片一起添加到屏幕上。

Vue 和 Firebase 的新手似乎无法让它工作。

<template>
<v-flex xs12 sm6 md4 lg3 xlg3 v-for="user in users" :key="user.id">  
          <v-card raised :class="`${user.Status} text-xs-center ma-3`" >            
            <v-responsive align="middle" class="pt-4">
              <v-icon :class=" `${user.Status} ma-n1 mb-n1`" size="55px" >account_box</v-icon>
            </v-responsive>
            <v-card-text>
              <div align="middle" class="subheading White">{{user.Name}}</div>
              <div align="middle" class="grey--text ma-1">
                <v-chip color="" small ripple  :class="`${user.Status} caption my-3`"><div class="White mr-2">Status: </div><div :class="`${user.Status}`"> {{user.Status}}</div> </v-chip>
              </div>
              <v-divider></v-divider>
              <div align="middle" class="White ma-1">Unit:  {{user.GroupHex}} - {{user.UserIDInt}} </div>          
              <div align="middle" class="grey--text mt-3">Last Message:<div class="Green">{{user.TimeStamp}}</div></div>       
            </v-card-text>
            <v-card-actions raised align="center">
              <v-spacer></v-spacer>
              <router-link class="noLink" :to="{ path: '/Logs'}" append>
             <v-btn color=" " small align="middle" flat class="" >
                <v-icon  color="grey" class="mr-2">assessment</v-icon>
                <span>Log Data</span>
               </v-btn>
               </router-link>
              <v-spacer></v-spacer>
            </v-card-actions>
          </v-card>
        </v-flex>

</v-layout>
<NewEmployee />
</v-container>
  </v-app>

</template>

<script>

import firestore from "firestore";
// eslint-disable-next-line
import EmployeePop from "@/components/updatePopups/EmployeePop";
import NewEmployee from "@/components/updatePopups/NewEmployee";
import db from "@/components/fbInit";
import firebase from "firebase";

export default {
// eslint-disable-next-line
  components: {EmployeePop, NewEmployee},
  data() {
    return {
      users: [],
      links: [
      { route: "/logs" },
      ]
    };
  },

  created() {

    var user = firebase.auth().currentUser;
    var employeeRef = db.collection('userProfiles').doc(user.uid).collection('employees')

   employeeRef.onSnapshot(snap => {
      snap.forEach(doc => {
        const data = {

         id: doc.id,
            Name: doc.data().Name,
            GroupHex: doc.data().GroupHex,
            UserIDInt: doc.data().UserIDInt,
            SuperID: doc.data().SuperID,
            misc: doc.data().misc,
            Status: doc.data().Status,
            TimeStamp: doc.data().TimeStamp,
            Original: doc.data().Original


          }
  this.users.push(data);
       });
    })      
  },
</script>

复制 v-card 而不是用新数据替换。

【问题讨论】:

    标签: firebase vue.js google-cloud-firestore snapshot real-time-updates


    【解决方案1】:

    这是因为每次将文档添加到集合中时,侦听器都会收到集合的整个文档集,并且您将这些文档推送到 users 数组无需重新初始化数组

    您可以通过添加console.log() 来验证这一点,如下所示,这将记录快照的大小:

       employeeRef.onSnapshot(snap => {
          console.log(snap.size);  <-- Add here
          snap.forEach(doc => {...})
          //...
       });
    

    您可以在每次触发监听器时重新初始化用户数组,如下:

       employeeRef.onSnapshot(snap => {
          this.users = [];  <-- re-initialize the array
          snap.forEach(doc => {...})
          //.....
       });
    

    但是有一个更好的解决方案,正如doc中解释的那样:分析“查询快照之间查询结果的实际变化”。

    例如,要仅捕获添加到集合中的文档,您可以执行以下操作:

      created() {
        const user = firebase.auth().currentUser;
        const employeeRef = db.collection('userProfiles').doc(user.uid).collection('employees')
    
    
        employeeRef.onSnapshot(snap => {
          snap.docChanges().forEach(change => {
            if (change.type === "added") {
              const data = {
                id: change.doc.id,
                Name: change.doc.data().Name,
                ....
              };
              this.users.push(data);
            }
          });
        });
      }
    

    【讨论】:

    • 雷诺的答案很好!
    猜你喜欢
    • 1970-01-01
    • 2019-10-12
    • 1970-01-01
    • 2019-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多