Reputation: 47
I'm trying to delete a nested field in Firestore but I get FirebaseError: Function updateDoc() called with invalid data. deleteField() can only appear at the top level of your update data
So what I'm trying to delete is the individual fields (map) called bread, salt etc.
const listRef = doc(db, "lists", list.id);
const onDismiss = useCallback(async (id: string) => {
const onGoingIndex = onGoingItems.findIndex((item) => item.id === id);
let getName = onGoingItems.find((item) => item.id === id)?.name || "";
if (onGoingIndex !== -1) {
onGoingItems.splice(onGoingIndex, 1);
} else {
const doneIndex = doneItems.findIndex((item) => item.id === id);
getName = doneItems.find((item) => item.id === id)?.name || "";
doneItems.splice(doneIndex, 1);
}
await updateDoc(listRef, {
items: {
[getName]: deleteField(),
},
});
}, []);
I've also tried using FieldValue.delete() from firebase/firestore but it has no function called delete().
Any help would be appreciated!
Upvotes: 1
Views: 2407
Reputation: 268
If you are using react-native-firebase you should probably call it like this firestore.FieldValue.delete()
, based on the docs
The way to modify or delete a nested field is to generate a dot path like in the sample code.
const listRef = doc(db, "lists", list.id);
const onDismiss = useCallback(async (id: string) => {
const onGoingIndex = onGoingItems.findIndex((item) => item.id === id);
let getName = onGoingItems.find((item) => item.id === id)?.name || "";
if (onGoingIndex !== -1) {
onGoingItems.splice(onGoingIndex, 1);
} else {
const doneIndex = doneItems.findIndex((item) => item.id === id);
getName = doneItems.find((item) => item.id === id)?.name || "";
doneItems.splice(doneIndex, 1);
}
await updateDoc(listRef, {
[`items.${getName}`]: firestore.FieldValue.delete()
});
}, []);
If you are using javascript SDK. For v9 of firebase you should import it like so
import { deleteField } from 'firebase/firestore';
...
await updateDoc(listRef, {
[`items.${getName}`]: deleteField(),
});
Upvotes: 1
Reputation: 26196
Getting access to the "field delete" operation depends on which version of the Firebase SDKs you are using:
firebase.firestore.FieldValue.delete()
.deleteField()
(as in your case)react-native-firebase
, you currently use firestore.FieldValue.delete()
(based on the docs, as pointed out by @AlekssandarNikolic in their answer).The reason you can't use FieldValue.delete()
is because it was removed in v9 of the SDK in favour of deleteField()
.
However, as that error tells you, a "delete field" marker can only appear at the top level of your update data. This is because of the way Firestore handles updating fields that are in nested objects to prevent the wrong data from being deleted.
With the code as you have written it, and getName
was "Bread"
, you would be updating the entire items
object to { Bread: <deleteMe> }
, which would also delete "Salt"
.
await updateDoc(listRef, {
items: {
[getName]: deleteField(),
},
});
To correct this, use dot notation of the field you want to mutate (which will correctly leave the other nested fields alone):
await updateDoc(listRef, {
[`items.${getName}`]: deleteField()
});
See updating nested fields (and deleting fields) for more information.
Upvotes: 6