0

I'm trying to run a delete function that should be fairly straight forward but i'm not getting it.

I referenced the document within the sub-collection but it doesn't seemed to be referenced correctly. When I hard code the answer documents id it performs the function but when I try to reference it doesn't work.

I have the document information stored in an array but I need to cycle through the array to find the id that matches the post. I'm having trouble grabbing the reference from 'getAnswer' once it is stored.

Here is the code:

    const [getAnswer, setGetAnswer] = useState([]);

    useEffect(() => {
    let mounted = true;

    db.collection("questions")
      .doc(questionId)
      .collection("answer")
      .orderBy("timestamp", "desc")
      .onSnapshot((snapshot) => {
        if (mounted) {
          setGetAnswer(
            snapshot.docs.map((doc) => ({
              id: doc.id,
              answers: doc.data(),
            }))
          );
        }
      });

    return () => (mounted = false);
  }, []);

  const handleDeletePost = (e) => {
    if (user) {
      db.collection("questions")
        .doc(questionId)
        .collection("answer")
        .doc(getAnswer.id)
        .delete();
    }
  };

  const answerMenuId = "primary-answer-account-menu";
  const answerRenderMenu = (
    <Menu
      anchorEl={anchorEl}
      anchorOrigin={{ vertical: "top", horizontal: "right" }}
      id={answerMenuId}
      keepMounted
      transformOrigin={{ vertical: "top", horizontal: "right" }}
      open={isMenuOpen}
      onClose={handleMenuClose}
    >
      <MenuItem onClick={handleMenuClose}>Edit</MenuItem>
      <MenuItem onClick={handleMenuClose} onClick={handleDeletePost}>
        Delete
      </MenuItem>
    </Menu>
  );

For a bit more context I would like to delete an answer document based on the id of the document. Here is a screenshot of the database:

enter image description here

cjmc
  • 101
  • 8
  • When you are fetching data from db, you can store the question id and answer id as the key of that element like `quesID-ansID`. That way you have both and when you click on it you can easily get it as mentioned [here](https://stackoverflow.com/questions/40044861/get-key-index-on-click-es6-react). Then just split them using the `-` and pass them in the delete function? – Dharmaraj Jun 17 '21 at 14:42
  • I'm not sure I understand: which answer are you trying to delete? Or are you trying to delete all answers for a specific question? – Frank van Puffelen Jun 17 '21 at 14:54
  • I'm trying to delete one answer for a specific question – cjmc Jun 17 '21 at 14:56

2 Answers2

1

Assuming that answerId is a variable that is holding the document ID of the answer to delete, you're looking for:

const answersDocumentRef = db.doc("answer/"+answerId);

Or alternatively:

const answersDocumentRef = db.doc(`answer/${answerId}`);

Or (without the answersDocumentRef):

db.collection("questions")
    .doc(questionId)
    .collection("answer")
    .doc(answerId)
    .delete();

Or alternatively for that:

db.doc(`questions/${questionId}/answer/${answerId}`).delete();
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • The issue I'm having is that answerId isn't a variable and I can't seem to store it. When I try to store it via doc.id I get the parent collection id instead of the answer's – cjmc Jun 17 '21 at 14:04
  • 1
    I don't understand what you mean there. Can you edit your question to show a screenshot of the document you're trying to delete in the Firestore console? – Frank van Puffelen Jun 17 '21 at 14:24
  • Ok, added some more information to the post – cjmc Jun 17 '21 at 14:38
1

Your getAnswer is an array, and it is NOT indexed by id. It is an array of objects, each of which has properties id and answers, in the order the query returns documents by timestamps.

getAnswer.id is meaningless in this context, and it's completely unclear what user, questionId and id even are in the context you show.

what event are you processing? how do you know which answer is indicated by the event? is it a button? select? checkbox? radio button?

Also note: each DocumentSnapshot in the QuerySnapshot INCLUDES doc.ref.path, which you could pass directly for db.doc(refPath).delete() - no need to construct the .collection().doc().collection() etc etc.

I use a wrapper package for FirebaseFirestore that always includes the doc.ref.path as refPath in my Record objects for exactly this reason - also, you can parse it to find parent documents, etc

LeadDreamer
  • 3,303
  • 2
  • 15
  • 18