简体   繁体   English

如何在 Vuejs 3 中获取 firebae 文档 ID

[英]How to get the firebae document id in Vuejs 3

I'm trying to build a crud vuejs3 application (book store), and in the update operation I didn't figure out how to get the document id in order to update the book details, following are some of my code snippets where I'm currently working on:我正在尝试构建一个 crud vuejs3 应用程序(书店),并且在更新操作中我没有弄清楚如何获取文档 ID 以更新书籍详细信息,以下是我的一些代码片段我目前正在从事:

UpdateDcoment.js更新文档.js

const updatingDoc = (collection, id) => {
  const isPending = ref(false);
  const error = ref(null);

  let documentRef = db.collection(collection).doc(id);

  const handleUpdateDoc = async (updates) => {
    isPending.value = true;
    error.value = null;
    try {
      const response = await documentRef.update(updates);
      isPending.value = false;
      console.log("update was successfully!", response);
      return response;
    } catch (err) {
      err.value = err.message;
      console.log(err.value);
      error.value = err.message;
      isPending.value = false;
    }
  };

  return { error, isPending, handleUpdateDoc };
};

export default updatingDoc;

BookDetails.vue BookDetails.vue

<template>
  <div>
    <div v-if="document" class="book-detail-view">
      <div class="book-cover">
        <img :src="document.coverUrl" :alt="`${document.title} book cover`" />
      </div>
      <div class="book-details">
        <h4 class="book-title">
          {{ document.title }}
        </h4>
        <div class="book-description">
          <p>{{ document.description }}</p>
        </div>
        <div class="book-author">
          <p>{{ `Author: ${document.author}` }}</p>
        </div>
        <div v-if="currentAuthenticatedUser">
          <button v-if="!isDeleting" @click="handleDelete">
            Delete the book
          </button>
          <button v-else disabled>processing...</button>
          <router-link :to="{ path: `/books/${document.id}/update` }">
            Update here
          </router-link>
        </div>
      </div>
    </div>
    <div v-else class="error">{{ error }}</div>
  </div>
</template>

<script>
import { computed } from "@vue/runtime-core";
import getDocument from "../../controllers/getDocument";
import getUser from "../../controllers/getUser";
import deleteDocument from "../../controllers/deleteDocument";
import getStoredBook from "../../controllers/userStorage";
import { useRouter } from "vue-router";

export default {
  props: ["id"],
  setup(props) {
    const { error, document } = getDocument("books", props.id);
    const { user } = getUser();
    const { removeDoc, isDeleting } = deleteDocument("books", props.id);
    const { handleDeleteCover } = getStoredBook();
    const router = useRouter();

    const currentAuthenticatedUser = computed(() => {
      return (
        document.value && user.value && user.value.uid === document.value.userId
      );
    });

    const handleDelete = async () => {
      await handleDeleteCover(document.value.filePath);
      await removeDoc();
      router.push({ name: "home" });
    };

    return {
      document,
      error,
      currentAuthenticatedUser,
      handleDelete,
      isDeleting,
    };
  },
};
</script>

UpdateBook.vue更新书.vue

<template>
  <form @submit.prevent="handleSubmit">
    <h4>Update book:</h4>
    <input type="text" required placeholder="book name" v-model="title" />
    <input type="text" required placeholder="author name" v-model="author" />
    <textarea
      required
      placeholder="book description"
      v-model="overview"
    ></textarea>
    <label for="bookCover">Upload the cover book</label>
    <input type="file" id="bookCover" @change="handleAddCoverBook" />

    <label for="book">Upload the book</label>
    <input type="file" id="book" @change="handleAddBook" />

    <button v-if="!isPending">Update</button>
    <button v-else disabled>Updating...</button>

    <div v-if="fileError" class="error">{{ fileError }}</div>
  </form>
</template>

<script>
import { ref } from "vue";
import userStorage from "@/controllers/userStorage";
import getUser from "@/controllers/getUser";
import { createdAtTime } from "@/firebase/firebaseConfig";
import { useRouter } from "vue-router";
import updatingDoc from "@/controllers/updateDocument";

export default {
  setup() {
    const { url1, url2, handleUploadBook, bookCoverPath, bookPath } =
      userStorage();
    const { user } = getUser();
    const { error, isPending, handleUpdateDoc } = updatingDoc(
      "books",
      document.id
    );
    const router = useRouter();

    const title = ref("");
    const author = ref("");
    const overview = ref("");
    const bookCover = ref(null);
    const book = ref(null);
    const fileError = ref(null);

    const handleSubmit = async () => {
      if (bookCover.value) {
        // Truthy value will show 'uploading...' text whenever the adding books process is processing
        isPending.value = true;
        await handleUploadBook(bookCover.value, book.value);
        // log the result of the event listener wherever the upload was successful
        console.log("book uploaded successfully", url1.value, url2.value);
        const response = await handleUpdateDoc({
          title: title.value,
          author: author.value,
          description: overview.value,
          createdAt: createdAtTime(),
          userId: user.value.uid,
          userName: user.value.displayName,
          coverUrl: url1.value,
          bookUrl: url2.value,
          bookCover: bookCoverPath.value,
          book: bookPath.value,
        });
        // Truthy value will remove 'uploading...' text whenever the adding books process is finished
        isPending.value = false;
        if (!error.value) {
          console.log("updating process successful");
          router.push({ name: "BookDetail", params: { id: response.id } });
        }
      }
    };

    // Upload Cover Book
    const bookCoverTypes = ["image/png", "image/jpg", "image/jpeg"];

    const handleAddCoverBook = (e) => {
      const newBookCover = e.target.files[0];
      if (newBookCover && bookCoverTypes.includes(newBookCover.type)) {
        bookCover.value = newBookCover;
        fileError.value = null;
      } else {
        bookCover.value = null;
        fileError.value = "Please add a cover book (png, jpg or jpeg)";
      }
    };

    // Upload book
    const bookTypes = ["application/pdf", "application/epub"];

    const handleAddBook = (e) => {
      const newBook = e.target.files[0];
      if (newBook && bookTypes.includes(newBook.type)) {
        book.value = newBook;
        fileError.value = null;
      } else {
        book.value = null;
        fileError.value = "Please add a book (pdf or epub)";
      }
    };

    return {
      title,
      author,
      overview,
      handleSubmit,
      handleAddCoverBook,
      handleAddBook,
      fileError,
      isPending,
    };
  },
};
</script>

I'm trying to get the document id from the bookDetails.vue and then use it inside the updateBook.vue but whenever I hit the update button in the UpdateBook.vue I have the following log:我试图从 bookDetails.vue 获取文档 ID,然后在 updateBook.vue 中使用它,但是每当我点击 UpdateBook.vue 中的更新按钮时,我都会得到以下日志:

No document to update: projects/books-store-71c7f/databases/(default)/documents/books/pVIg6OytEKE4nEUE8uqd

I appreciate your hints and help guys!感谢您的提示和帮助!

SOLVED!解决了!

So, the trick was to use the params for the current URL in order to get the document id and update the document fields: here I passing the router-link to redirect to update form:因此,诀窍是使用当前 URL 的参数来获取文档 ID 并更新文档字段:这里我传递路由器链接以重定向到更新表单:

<router-link
   :to="{ name: 'UpdateBook', params: { id: document.id } }"
   >
     Update here
 </router-link>

And here inside the setup() of the updateBook.vue component I use params to access the document id:在 updateBook.vue 组件的 setup() 中,我使用参数来访问文档 ID:

const router = useRouter();
// Get the current document id from the route id
const id = router.currentRoute.value.params.id;
// And here I pass the document id as parameter
const { error, isPending, handleUpdateDoc } = updatingDoc("books", id);

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

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