Home > Net >  allows user to store data into firestore without overwriting the previous data using reactjs
allows user to store data into firestore without overwriting the previous data using reactjs

Time:11-10

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?

CodePudding user response:

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

CodePudding user response:

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.

  • Related