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

mm9b1k5b  于 2023-01-21  发布在  其他
关注(0)|答案(1)|浏览(131)

我正在尝试构建一个crud vuejs 3应用程序(书店),在更新操作中我没有弄清楚如何获取文档ID以更新书籍详细信息,以下是我目前正在编写的一些代码片段:
UpdateDcoment.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>

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

我很感激你们的提示和帮助!

vuktfyat

vuktfyat1#

解决!
因此,技巧是使用当前URL的参数来获取文档id并更新文档字段:这里我传递路由器链接重定向到更新表单:

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

在updateBook.vue组件的setup()中,我使用params访问文档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);

相关问题