firebase - 带有 VueJS 2 数据的 Firestore where 子句

标签 firebase vue.js vuejs2 google-cloud-firestore

在我的应用中,我需要获得与所选产品相似的产品,因此我有两种方法:

import firebase from "firebase";
import db from "../firebase/firebaseInit";

export default {
  data() {
    return {
      carousel: this.$nextTick(() => (this.carousel = true)),
      interval: 6000,
      title: "",
      imgs: [],
      price: "",
      ref: "",
      desc: "",
      types: [],
      skin: "",
      colors: [],
      similars: [],
      tabs: [{
          id: 0,
          title: "Beskrivelse",
          text: this.desc
        },
        {
          id: 1,
          title: "Rengøring",
          text: "Der er mange tilgængelige udgaver af Lorem Ipsum, men de fleste udgaver har gennemgået forandringer, når nogen har tilføjet humor eller tilfældige ord, som på ingen måde ser ægte ud."
        }
      ]
    };
  },
  metaInfo() {
    return {
      title: this.title
        .toString()
        .charAt(0)
        .toUpperCase() +
        this.title.slice(1) +
        " Urrem i " +
        this.skin
        .toString()
        .charAt(0)
        .toUpperCase() +
        this.skin.slice(1) +
        " " +
        this.ref,
      meta: [{
        name: "description",
        content: this.desc
          .toString()
          .charAt(0)
          .toUpperCase() + this.desc.slice(1)
      }]
    };
  },
  filters: {
    capitalize: function(value) {
      if (!value) return "";
      value = value.toString();
      return value.charAt(0).toUpperCase() + value.slice(1);
    }
  },
  beforeRouteEnter(to, from, next) {
    db.collection("straps")
      .where(firebase.firestore.FieldPath.documentId(), "==", to.params.id)
      .onSnapshot(querySnapshot => {
        querySnapshot.forEach(doc => {
          next(
            vm => (
              (vm.title = doc.data().title),
              (vm.price = doc.data().price),
              (vm.desc = doc.data().desc),
              (vm.skin = doc.data().skin),
              (vm.types = doc.data().types),
              (vm.imgs = doc.data().imgs),
              (vm.ref = doc.data().ref),
              (vm.colors = doc.data().colors)
            )
          );
        });
      });
  },
  beforeRouteUpdate(to, from, next) {
    db.collection("straps").where(
      firebase.firestore.FieldPath.documentId(),
      "==",
      to.params.id
    );
    onSnapshot(querySnapshot => {
      querySnapshot.forEach(doc => {
        (this.id = doc.id),
        (this.title = doc.data().title),
        (this.price = doc.data().price),
        (this.desc = doc.data().desc),
        (this.skin = doc.data().skin),
        (this.types = doc.data().types),
        (this.imgs = doc.data().imgs),
        (this.colors = doc.data().colors);
      });
    });
    this.$nextTick(() => (this.carousel = true));
    next();
  },
  created() {
    this.getSimilar();
    this.fetchData();
  },
  watch: {
    $route: "fetchData"
  },
  methods: {
    fetchData() {
      db.collection("straps")
        .where(
          firebase.firestore.FieldPath.documentId(),
          "==",
          this.$route.params.id
        )
        .onSnapshot(querySnapshot => {
          querySnapshot.forEach(doc => {
            (this.id = doc.id),
            (this.title = doc.data().title),
            (this.price = doc.data().price),
            (this.desc = doc.data().desc),
            (this.skin = doc.data().skin),
            (this.types = doc.data().types),
            (this.imgs = doc.data().imgs),
            (this.colors = doc.data().colors);
          });
        });
    },
    getSimilar() {
      db.collection("straps")
        .where("skin", "==", this.skin)
        .orderBy("date", "desc")
        .limit(4)
        .onSnapshot(querySnapshot => {
          const similars = [];
          querySnapshot.forEach(doc => {
            const data = {
              id: doc.id,
              title: doc.data().title,
              skin: doc.data().skin,
              img: doc.data().imgs[0].url,
              price: doc.data().price,
              types: doc.data().types,
              date: doc
                .data()
                .date.toString()
                .slice(0, 15)
            };
            similars.push(data);
          });
          this.similars = similars;
        });
    }
  }
};
<template>
  <v-container>
    <v-layout justify-center wrap>
      <v-flex xs12 sm10 lg8>
        <v-layout>
          <v-flex>
            <v-layout class="strapinfotoside" justify-center wrap>
              <v-flex xs12 sm12>
                <v-container>
                  <v-layout>
                    <v-flex xs12>
                      <v-carousel :cycle="false" v-if="carousel" hide-controls class="elevation-0" :interval="interval">
                        <v-carousel-item v-for="img in imgs" :key="img.url" :src="img.url">
                        </v-carousel-item>
                      </v-carousel>
                    </v-flex>
                  </v-layout>
                </v-container>
              </v-flex>
              <v-flex xs12 sm12 class="text-xs-left strapinfo">
                <v-flex>
                  <h1 class="titles">RIOS1931 {{this.types[0].title | capitalize}} {{this.title | capitalize}} Urrem i {{this.skin | capitalize}} {{this.ref}}</h1>
                  <p class="ref grey--text">Reference nr. {{this.ref | capitalize}}</p>
                  <p class="price mb-5">{{this.price | capitalize}} kr.</p>
                </v-flex>
                <!-- <v-flex sm6>
                                    <v-select :items="this.colors" label="Vælg farve" outline></v-select>
                                </v-flex> -->
                <v-flex>
                  <v-tabs color="grey darken-1" slider-color="primary">
                    <v-tab color="white--text" class="tab" v-for="tab in tabs" :key="tab.id" ripple>
                      {{tab.title}}
                    </v-tab>
                    <v-tab-item>
                      <v-card color="grey lighten-4" flat>
                        <v-card-text>
                          <p>{{ desc }}</p>
                          <h3 class="my-2"><strong>Produktdetaljer</strong></h3>
                          <p><strong>Fås i:</strong> <span class="colors" v-for="color in colors" :key="color.title">{{color.title | capitalize}}</span></p>
                          <p class="mt-2"><strong>Materiale:</strong> {{skin | capitalize}}</p>
                          <p><strong>Rem til:</strong> <span class="types" v-for="type in types" :key="type.title"> {{type.title | capitalize}}</span></p>
                          <p><strong>Materiale:</strong> {{skin | capitalize}}</p>
                        </v-card-text>
                      </v-card>
                    </v-tab-item>
                    <v-tab-item v-for="tab in tabs.slice(1,2)" :key="tab.id">
                      <v-card color="grey lighten-4" flat>
                        <v-card-text>{{ tab.text }}</v-card-text>
                      </v-card>
                    </v-tab-item>
                  </v-tabs>
                </v-flex>
              </v-flex>
            </v-layout>
          </v-flex>
        </v-layout>
      </v-flex>
    </v-layout>
    <v-layout justify-center class="section">
      <v-flex xs12 sm10 lg9>
        <h2>Nyeste urremme</h2>
        <v-layout mt-3 justify-center wrap>
          <v-flex pa-3 xs6 sm3 lg2 v-for="similar in similars" :key="similar.id">
            <v-hover>
              <v-card :to="{name: 'Strap', params: {id: similar.id}}" flat slot-scope="{ hover }">
                <v-img :src="similar.img" aspect-ratio="1">
                  <v-layout slot="placeholder" fill-height align-center justify-center ma-0>
                    <v-progress-circular indeterminate color="black"></v-progress-circular>
                  </v-layout>
                </v-img>
                <v-card-title primary-title>
                  <h3 class="text-xs-left">RIOS1931 {{similar.title | capitalize}} Urrem i {{similar.skin | capitalize}}</h3>
                </v-card-title>
                <v-card-text style="padding: 0 !important;">
                  <p class="text-xs-left">{{similar.price}} kr.</p>
                </v-card-text>
              </v-card>
            </v-hover>
          </v-flex>
        </v-layout>
      </v-flex>
    </v-layout>
  </v-container>
</template>

我的问题是,在 getSimilar() 方法中,它不会获得皮肤等于带有 ".where("skin", "==", this.skin) 的所选产品皮肤的产品.

如果我写 console.log(this.skin) 它会返回正确的值。

最佳答案

.onSnapshot() 为 QuerySnapshot 事件附加一个监听器,参见 https://firebase.google.com/docs/reference/js/firebase.firestore.Query#onSnapshot

因此,我认为在created生命周期钩子(Hook)中调用(或attach)更合适,如下所示:

  methods: {
     .....
  },
  created: function() {
     db.collection("straps")
       .where("skin", "==", this.skin)
       .orderBy("date")
       .limit(4)
       .onSnapshot(querySnapshot => {
           ....
       });
       ...
     });
  }

如果你想在一个方法中获取数据(即按需调用它的方式,即通过单击按钮)我建议你使用 get()方法,如下:

  getSimilar() {
    db.collection("straps")
      .where("skin", "==", this.skin)
      .orderBy("date")
      .limit(4)
      .get()
      .then(querySnapshot => {
        const similars = [];
        querySnapshot.forEach(doc => {
          const data = {
            id: doc.id,
            title: doc.data().title,
            skin: doc.data().skin,
            img: doc.data().imgs[0].url,
            price: doc.data().price,
            types: doc.data().types,
            date: doc
              .data()
              .date.toString()
              .slice(0, 15)
          };
          similars.push(data);
        });
        this.similars = similars;
        console.log(this.skin);
      });
  }

关于firebase - 带有 VueJS 2 数据的 Firestore where 子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52906823/

相关文章:

firebase - Flutter cloud_firestore 系统日期对象的设置/警告

javascript - 强参数要求

javascript - VueJS 2 中 <template> 中的 <template> 有什么用?

javascript - 将数组数据从 v-for 循环发送到 prop (VUE)

java - 如何修复从设置 Activity 到主要 Activity 的移动?

node.js - 使用云函数时限制对第三方API的请求

javascript - vue.js中如何触发元素?

python - 通过 axios 将数据发送到 django rest 框架时获取错误请求 400

css - Vue2 : v-move not applied to "leave" transition

firebase - flutterfire 尚未配置任何应用程序。检索线程信息时出错 : (ipc/send) invalid destination port