【问题标题】:Firestore: Unable to fetch nested documents. Why?Firestore:无法获取嵌套文档。为什么?
【发布时间】:2019-11-29 04:45:14
【问题描述】:

我正在开发一个带有 firebase/firestore 后端的 Vue(使用 Vuex)应用程序,但在获取其他文档引用的文档时遇到了问题。具体来说,我有一个recipes 集合(连同链接照片中的userscomments 集合)集合,其中每个包含的文档都具有addedBycomments 字段等。两者都是引用的各个文档的id 字符串(cmets 字段是ids 的数组)。现在,我不确定这是否是最好的方法,但我有 MongoDB 背景,我认为可以像使用 MongoDB 一样获取这些字段的详细信息。

我已经尝试了几次,但似乎没有任何效果。下面的代码 sn-ps 就是一个例子。

主配方组件/容器(我在数据库中查询特定配方文档)

<template>
  <div class="recipe-detail">
    <loader v-if="isLoading" message="Loading Recipe" size="huge" />
    <div v-else-if="!recipe" class="no-recipe">
      No such recipe in DB
    </div>
    <div v-else class="comments-and-similar">
      <div class="comments">
        <h3 class="comments-title">Comments</h3>
        <comment-form />
        <comment-list :comment-list="recipe.comments" />
      </div>
      <div class="similar-recipes">
        <similar-recipes />
      </div>
    </div>
  </div>
</template>

<script>
import { mapGetters, mapActions } from "vuex";

import Loader from "@/components/shared/Loader";
import PostedBy from "@/components/recipes/detail/PostedBy";
import CommentForm from "@/components/forms/CommentForm";
import CommentList from "@/components/recipes/detail/CommentList";

export default {
  name: "recipe-detail",
  components: {
    Loader,
    PostedBy,
    CommentForm,
    CommentList,
  },
  data() {
    return {
      recipeId: this.$route.params.recipeId,
      fullPath: this.$route.fullPath
    };
  },
  computed: {
    ...mapGetters(["isLoading"]),
    ...mapGetters({ recipe: "recipes/recipe" }),
  },
  watch: {
    "$route.params.recipeId"(id) {
      this.recipeId = id;
    }
  },
  methods: {
    ...mapActions({ getRecipeById: "recipes/getRecipeById" })
  },
  created() {
    if (!this.recipe || this.recipe.id !== this.recipeId) {
      this.getRecipeById(this.recipeId);
    }
  }
};
</script>

<style lang="scss" scoped>
</style>

评论列表组件(这里我通过props收到评论id列表)

<template>
  <section class="comments">
    <div v-if="commentList.length === 0">Be the first to comment on recipe</div>
    <template v-else v-for="comment in commentList">
      <comment :comment-id="comment" :key="comment" />
    </template>
  </section>
</template>

<script>
import Comment from "./Comment";

export default {
  name: "comment-list",
  components: {
    Comment
  },
  props: {
    commentList: {
      type: Array,
      required: true
    }
  }
};
</script>

<style lang="scss" scoped>

</style>

评论组件

<template>
  <article>
    <div v-if="isLoading">Loading comment...</div>
    <div v-else>{{ JSON.stringify(comment) }}</div>
  </article>
</template>

<script>
import { mapGetters, mapActions } from "vuex";

export default {
  name: "comment",
  props: {
    commentId: {
      type: String,
      required: true
    }
  },
  computed: {
    ...mapGetters(["isLoading"]),
    ...mapGetters({ comment: "recipes/comment" })
  },
  methods: {
    ...mapActions({ getCommentById: "recipes/getCommentById" })
  },
  created() {
    this.getCommentById(this.commentId);
  }
};
</script>

现在,Comment 组件是我遇到问题的地方。我得到每个单独的评论 ID 并使用它来查询数据库,特别是 comments 集合。我实际上是从数据库中获取评论详细信息正文,此查询不会停止并导致无限循环。我必须注释掉 created 生命周期中的方法才能停止。我为 addedBy 字段尝试了相同的方法来查询用户并遇到了同样的问题。所以,我做错了什么。

数据库结构

PS:我觉得不需要包含 Vuex 方法(动作)来减少冗长。它们可以很好地发送相应的查询。

【问题讨论】:

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


    【解决方案1】:

    您似乎在所有组件之间共享isLoading 标志。

    我相信正在发生的事情是这样的:

    1. 您尝试加载评论并且isLoading 设置为true
    2. 组件recipe-detail 重新渲染以显示Loading Recipe 消息。请注意,这将破坏 comment-list
    3. 评论加载完毕后,isLoading 将被设置回false
    4. recipe-details 将再次重新渲染,这次显示 comment-list。这将创建一组新的comment 组件,每个组件都将尝试再次加载它们的数据。这让我们回到了第 1 步。

    在不相关的注释中,您的 comment 组件似乎依赖于商店中保存的单个评论。当只有一条评论时,这可能没问题,但当有多个 cmets 时,它们会同时加载,并且最终只有其中一个最终会出现在商店中。

    【讨论】:

    • 您的假设是正确的。例如,当用户添加新评论时,recipe-detail 组件会重新呈现,这是我不想要的行为,原因很明显。在找到当前问题的解决方案后,我打算立即对其进行调查。
    • @CollinsOrlando 从您的评论中我不清楚您是否理解我的回答。共享的 isLoading 标志是导致您当前问题的原因。
    • 哦,我可能误读/误解了您的评论。无论如何,我找到了另一种解决方案,但您的建议是:isLoading 标志导致除此之外的其他问题仍然是无价的。感谢您的帮助,我会接受您的回答。干杯!
    猜你喜欢
    • 1970-01-01
    • 2021-01-23
    • 2019-06-07
    • 1970-01-01
    • 2018-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多