0
votes

is it possible to update only one document id in a firestore subcollection, I have been searching for solution but all I can find is to query all documents. if I use querySnapshot.foreach() all documents in a subcollection with the same field value gets updated. Using .where() also query all documents and not a specific id, but I am only trying to update one. I am trying to use the document id but I could not figure out how to call the id for the subcollection. Is there a way to do that?

const currentUser=firebase.auth().currentUser;
const userPost= firebase.firestore().collection('users') 
                .doc(currentUser.uid).collection("post");

const EditPost = async (event) => {
 event.preventDefault();

 await userPost
  .doc() <-- here I've been trying to put the subcollection doc id 
  .set({
    title: title,
    body: body,
    updatedAt: date,
  }, { merge: true })
  .catch((err) => {
    console.log(err)
  })
 }

here is a sample screenshot of the firestore subcollection structure enter image description here subcollection structure. Currently I tried using uuidv4 so I can also create a field value of postId upon adding a new document, because I was planning on just calling the postId as a document id but it was also inside the subcollection ducument.

3
I'm unclear where you are stuck. It's definitely possible to update a single document if you know it's ID. This is covered in the documentation. You have to pass the ID to doc(). - Doug Stevenson
yeah I could not figure out the right way to call one document id for the sub collection - undefined
There is only one way - pass the ID to doc(). You're passing nothing right now. - Doug Stevenson
yeah I have already pass an id where I even used a uuidv4 but does not work either. So that is just an example of what I am currently using where I couldn't figure out the right way to call the id for the doc() in a sub collection. What I am talking about is the sub collection not the root collection. I am currently trying something for now don't know if this will work. - undefined
I'm still not clear where you're stuck. Either you know the ID of the existing document, or you don't. If you don't, you have to query to find it. - Doug Stevenson

3 Answers

2
votes

I finally figured out how to call a document id for a single document in a subcollection and edit only the field of a specific document. Might not be the best solution but I'm sharing this for those who are having similar problem to mine.

I have a queried list of post in my postlist.js and each has a unique key which is equivalent to the document id inside the subcollection.

post 1 - edit
post 2 - edit
post 3 - edit

then on my route I used the useParams id using react router. using Link I go to the posteditor page, PostEditor.js.

<Route path="/posteditor/:id" component={PostEditor} />

by using the id from useParams inside the PostEditor.js I can now assigned the id inside the .doc() in my EditPost function.

const PostEditor = () => {
  const { id } = useParams

  const userPosts = ....;

  const EditPost = async (event) => {
    event.preventDefault();

    await userPosts
     .doc(id) <------*here I used the id from useParams*
     .set({
       title: title,
       body: body,
       updatedAt: date,
     }, { merge: true })
     .catch((err) => {
      console.log(err)
     })
  }

  return ( //// )
}

Now I can edit a single document and manage each document separately inside the subcollection. As I said it might not be the best solution but it works for me without error.

0
votes

You no need to use collectoin.set({}) you can also use collection.update({}) for update specific collection field.

db.collection("cities").doc("DC").update({
    capital: true
})

Here I mention code. this is Link of reference site.

0
votes

With the assumption that you know the ID of the document in the users collection and the ID of the document in the userPosts collection, you can update this last document as follows:

const currentUser = firebase.auth().currentUser;
const userPosts = firebase.firestore().collection('users') 
                .doc(currentUser.uid).collection("userPosts");  // <= note the change here, from collection("post") to collection("userPosts")
 
const userPostId = "8ea3....";

const EditPost = async (event) => {
 event.preventDefault();

 await userPosts
  .doc(userPostId) 
  .set({
    title: title,
    body: body,
    updatedAt: date,
  }, { merge: true })
  .catch((err) => {
    console.log(err)
  })
 }

More generally, to create a DocumentReference to a document for which you know the path, you need to alternatively call the collection() and doc() methods.

You could also call the doc() method with a slash-separated path to a document, as shiwn below. Note that, since you point to a document, the slash-separated path contains an even number of elements.

const currentUser = firebase.auth().currentUser;
const userPostId = "8ea3....";

const userPostRef = firebase.firestore().doc(`users/${currentUser}/userPosts/${userPostId}`)