Updating an Items in a list in React

Hi everyone, I just started learning firebase and I’m creating this simple CRUD app. I’m currently having issues with updating the list. I tried several implementation but instead of updating existing list, it creates a new item in the list

The codesandbox to the problem is below:

https://codesandbox.io/embed/1cnsy?codemirror=1

Not familiar with this, but just doing a bit of testing

If I add a getDoc and console.log in under const cafeDoc = doc(db, 'Cafes', id);

e.g.

const cafeDoc = doc(db, 'Cafes', id);
const docSnap = await getDoc(cafeDoc);
console.log("Document data:", docSnap.data());

On clicking update on for example ‘Cafe: Escaladenero2’

The logged output is

Document data:
{rank: 10, name: "Escaladenero2", id: "HKsBjP7xN09PiFmxOZD0", city: "Abuja 3"}

I then change rank to 15 and click on the update cafe button. As you say a new entry is added rather than the existing one updated.

If I click on the new addition the output for that one is

Document data:
{city: "Abuja 3", rank: 15, name: "Escaladenero2"}

The standout is the lack of ‘id’ on this wrongly added entry.

Sorry if this isn’t helpful, but it is pointing towards ‘id’ for me.

@rpg_digital , thanks. Is there a trick I could use to add an id to this new entry

As I say not familiar with firebase and react

Apparently addDoc automatically generates an ‘id’

Changing this line

await addDoc(cafesCollection, { rank: rankNum, name: name, city: city });

to

const docRef = await addDoc(cafesCollection, { rank: rankNum, name: name, city: city });
console.log(docRef.id)

confirms that.

I think any further advice from me at this point, would do more harm than good. Sorry @adefesoq .

Hi,

Like @rpg_digital, I’m not overly familiar with Firebase. However, it seems to me that the problem is in your handleSubmit function.

Here, you have:

const handleSubmit = useCallback(
  async (e) => {
    e.preventDefault();
    await addDoc(cafesCollection, { rank: rankNum, name: name, city: city });

    if (edit) {
      const newCafe = cafes.map((cafe) => {
        if (cafe.id === editID) {
          return { ...cafe, city, name, rank };
        }
        return cafe;
      });
      setCafes(newCafe);
    }
    setRank('');
    setName('');
    setCity('');
    setEdit(false);
  },
  [name, rank, rankNum, city, edit, editID]
);

This is called whenever the form is submitted, regardless of whether you are editing an existing café, or creating a new one.

And as you can see on line 3, you are calling addDoc, which will, well, add a new document to the store. There is no logic there to update anything.

To fix this, you need something like:

const handleSubmit = useCallback(
  async (e) => {
    e.preventDefault();
    // Check if user is editing café or creating a new one
    // If editing, update existing record
    // If not editing, create new record
    // Clear form/state
);

In code, that would look something like this:

const handleSubmit = useCallback(
  async (e) => {
    e.preventDefault();
    
    if (edit) {
      const cafeRef = doc(db, 'Cafes', editID);
      await updateDoc(cafeRef, {
        rank, name, city
      });
    } else {
      await addDoc(cafesCollection, { rank: rankNum, name: name, city: city });
    }

    setRank('');
    setName('');
    setCity('');
    setEdit(false);
  },
  [name, rank, rankNum, city, edit, editID]
);

I tried that in your CodeSandbox and it works as expected. However, as mentioned, I am not too familiar with Firebase, so this might not be the most idiomatic way to do things.

Also, as a side note, you have a couple of errors in the console (related to duplicate IDs in the store) that you will want to address.

HTH

1 Like

@rpg_digital, thanks for the insight to the problem @James_Hibbard, thank you too

1 Like