skip to Main Content

I am making something which allows logged user to report their lost items to the firestore firebase.
Now what I’ve done successfully registers details of the user’s report to the ‘reports’collection.

but everytime the same user reports another item, the details of previously reported item gets overwritten.
I want it in such a way that the new report gets added to the same collection, without overwriting the previous one.
Something like in an array, in which when u add an item, it doesn’t get overwritten, but adds to the array

i have done this

 await setDoc(doc(db,"reports",auth.currentUser.uid),{ 
      
      description: descref.current.value,
      email: auth.currentUser.email,
      timestamp: serverTimestamp(),
     
    
    }).then(async () =>{
      if (image) {
     
        const storageRef = ref(storage,`images/${ image.name + auth.currentUser.uid }`)
    const uploadTask =  uploadBytesResumable(storageRef,image);
    setimage(null);  
    uploadTask.on(
      'state_changed',
      null,        
      (err) => console.log(err),
      () => {
          // download url
          getDownloadURL(uploadTask.snapshot.ref).then(async (url) => {
              console.log(url);

             //adding the image URL to collection
              await setDoc(doc(db,'reports', auth.currentUser.uid ),{imgurl:url},{merge:true});

It looks like this 
[(https://i.stack.imgur.com/SYo73.png)](https://i.stack.imgur.com/SYo73.png)

but whenever i upload new data, the previous one gets overwritten.

what i want is this

{
  "posts": {
    "0": {
      "author": "gracehop",
      "title": "Announcing COBOL, a New Programming Language"
    },
    "1": {
      "author": "alanisawesome",
      "title": "The Turing Machine"
    }
  }
}

can anyone help how to do this?

2

Answers


  1. Assuming that the goal is to add new posts to reports/user.id/ without overwriting existing ones, try this way:

    1. First create a ref with an auto-generated ID for the new post under reports/user.id, this will be the newPostRef
    2. Use newPostRef to set the report content
    3. Upload the image and get download url (same as original)
    4. Use newPostRef again to update post with download url, using { merge: true }

    Example:

    import { collection, doc, setDoc } from "firebase/firestore";
    
    const newPostRef = doc(collection(db, "reports", auth.currentUser.uid));
    
    await setDoc(newPostRef, {
      description: descref.current.value,
      email: auth.currentUser.email,
      timestamp: serverTimestamp(),
    }).then(async () => {
      if (image) {
        const storageRef = ref(storage, `images/${image.name + newPostRef.id}`);
        const uploadTask = uploadBytesResumable(storageRef, image);
        setimage(null);
        uploadTask.on(
          "state_changed",
          null,
          (err) => console.log(err),
          () => {
            // download url
            getDownloadURL(uploadTask.snapshot.ref).then(async (url) => {
              console.log(url);
    
              //adding the image URL to collection
              await setDoc(newPostRef, { imgurl: url }, { merge: true });
            });
          }
        );
      }
    });
    

    The reports/user.id will be a collection accepting multiple posts with auto IDs, hopefully that is the desired result here.

    Login or Signup to reply.
  2. Calling setDoc() without merge: true will overwrite the doc. You are also passing the user id as the doc id written this way. Try calling addDoc() instead and use update after getting the download URL. Some of this also cleans up your async statements a bit:

    const newDoc = doc(collection(db,"reports", auth.currentUser.uid));
    
    await addDoc(newDoc, {}).then(() => {
     if (image) {
      const storageRef = ref(storage, `images/${image.name + auth.currentUser.uid}`)
      const uploadTask = uploadBytesResumable(storageRef, image);
       setimage(null);
       uploadTask.on(
        'state_changed',
        null,
        (err) => console.log(err),
         async () => {
          const url = await getDownloadURL(uploadTask.snapshot.ref)
           console.log(url)
           await updateDoc(newDoc, { imgurl: url });
        });
      } else {
        console.log(newDoc)
      }
    });
    

    If you do not want each report to be saved by user id and instead just have the reports collection be an array of records, you should remove the user id portion.

    const newDoc = doc(collection(db,"reports"));
    
    // this will still work because the auto-generated ID is returned to the update method
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search