undefined
undefined

Reputation: 441

update only one document id in subcollection in firestore in reactjs

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.

Upvotes: 0

Views: 1450

Answers (3)

undefined
undefined

Reputation: 441

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.

Upvotes: 2

Renaud Tarnec
Renaud Tarnec

Reputation: 83048

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}`)

Upvotes: 0

Hassan Ali
Hassan Ali

Reputation: 1029

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.

Upvotes: 0

Related Questions