簡體   English   中英

如何在 Vuejs 3 中獲取 firebae 文檔 ID

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

我正在嘗試構建一個 crud vuejs3 應用程序(書店),並且在更新操作中我沒有弄清楚如何獲取文檔 ID 以更新書籍詳細信息,以下是我的一些代碼片段我目前正在從事:

更新文檔.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

<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>

更新書.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>

我試圖從 bookDetails.vue 獲取文檔 ID,然后在 updateBook.vue 中使用它,但是每當我點擊 UpdateBook.vue 中的更新按鈕時,我都會得到以下日志:

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

感謝您的提示和幫助!

解決了!

因此,訣竅是使用當前 URL 的參數來獲取文檔 ID 並更新文檔字段:這里我傳遞路由器鏈接以重定向到更新表單:

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

在 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