#javascript #firebase #google-cloud-firestore
#javascript #firebase #google-облако-firestore
Вопрос:
У меня есть карта объектов firebase под названием «Список курсов», которая содержит вложенные поля. Эти вложенные поля сами по себе являются картами объектов, которые содержат дополнительные вложенные поля. Кроме того, некоторые из этих карт объектов будут иметь случайно сгенерированные имена.
Цель состоит в том, чтобы удалить карту объектов со случайно сгенерированным именем «352oIP3fdc6IIvuBbajR0» (подчеркнуто СИНИМ цветом). Имена «CourseList» и «LectureList» являются статическими именами, однако красный идентификатор курса (со случайно сгенерированным именем «2dfPipFRKiB6TAKab4jv8»).
Следуя другим вопросам по StackOverflow, я смог заставить работать функцию удаления, если я хотел удалить карту красных объектов «2dfPipFRKiB6TAKab4jv8».
let CID = '2dfPipFRKiB6TAKab4jv8';
await db.collection('users').doc(UID).set( {
CourseList : { [CID]: FieldValue.delete() }
},{ merge: true }
);
Однако, когда я пытаюсь удалить карту подобъектов, подчеркнутую синим цветом «352oIP3fdc6IIvuBbajR0», операция, похоже, ничего не сделала, и документ Firebase не изменился.
let CID = "2dfPipFRKiB6TAKab4jv8";
let LID = "352oIP3fdc6IIvuBbajR0";
await db.collection('users').doc(UID).set( {
CourseList : { [`${CID}.LectureList.${LID}`]: FieldValue.delete() }
},{ merge: true }
);
Любая ясность относительно того, как правильно удалить глубоко вложенное поле внутри карты объектов, была бы весьма признательна.
Комментарии:
1. Что именно делает этот код, кроме того, что вы ожидаете? «кажется, не работает» — недостаточно информации для работы. Пожалуйста, также жестко закодируйте значения вместо использования переменных, значения которых мы не видим. Здесь должно быть достаточно информации, чтобы любой мог запустить код и увидеть те же результаты.
2. Конечно. Я отредактирую вопрос, чтобы улучшить ясность для читателей.
Ответ №1:
Хотя сообщение старое, на случай, если кто-нибудь найдет это позже
для работы с точечными путями вы должны использовать update
вместо set
, set
не обрабатывает точечные пути, даже слияние. Слияние объединит весь предоставленный вложенный объект, чтобы данные не были разбиты.
РЕШЕНИЕ:
Чтобы удаление сработало, вам нужно вызвать
let CID = "2dfPipFRKiB6TAKab4jv8";
let LID = "352oIP3fdc6IIvuBbajR0";
await db.collection('users').doc(UID).update( {
[`CourseList.${CID}.LectureList.${LID}`]: FieldValue.delete()
} )
КАК СДЕЛАТЬ ТО ЖЕ САМОЕ С ПОМОЩЬЮ SET MERGE:
для того же, чтобы работать с set merge:true
ним, должно быть
let CID = "2dfPipFRKiB6TAKab4jv8";
let LID = "352oIP3fdc6IIvuBbajR0";
await db.collection('users').doc(UID).set({
'CourseList': {
[CID]: {
'LectureList': {
[LID]: {
FieldValue.delete()
}
}
}
},
{ merge: true }
);
Здесь нет причин выполнять set
маршрут, как update
это ясно, но это помогает прояснить разницу с операциями he
ПОЧЕМУ СРАБОТАЛО ОДНО ИЗ УДАЛЕНИЙ:
@andrewB ваше удаление с помощью CID сработало, потому что нет вложенного пути
Приведенный ниже код работал, потому что он выполнял следующее:
let CID = '2dfPipFRKiB6TAKab4jv8';
await db.collection('users').doc(UID).set( {
CourseList : { [CID]: FieldValue.delete() }
},{ merge: true }
);
- попытка заменить ключ
CourseList
наusers/${UID
{ [CID]: FieldValue.delete() }
- из
merge: true
-за того, что замена объединяется с существующим значением там и заканчивается только касанием ключа[CID]
, а не уничтожением всего объекта
Ответ №2:
РЕШЕНИЕ:
Для будущих читателей, это код, который я использовал для удаления сильно вложенных полей внутри карты объектов.
const userRec = db.collection('users').doc(UID);
let userRecData = await userRec.get();
let userRecResp = {};
userRecResp = userRecData.data();
delete userRecResp.CourseList[CID]['LectureList'][LID];
await db.collection('users').doc(UID).update(userRecResp);
Пожалуйста, обратите внимание, что «UID», «CID» и «LID» являются именами переменных.
Комментарии:
1. смотрите мое решение ниже для простого подхода без необходимости извлечения объекта. Вы почти добрались до своего вопроса, необходимого для использования
update
вместоset
с ТОЧЕЧНЫМИ путями, документ firestore сбивает с толку
Ответ №3:
Вам необходимо указать полный путь к вложенному значению в качестве ключа переданного объекта set()
. Вы не можете выразить это как серию вложенных объектов, как сейчас.
await db.collection('users').doc(UID).set({
[`CourseList.${CID}`]: FieldValue.delete()
},
{ merge: true }
);
Комментарии:
1. Прошу прощения за путаницу, но когда я пытаюсь включить полный путь, все равно кажется, что поле не удаляется. [
CourseList.${CID}.LectureList.${LID}
]: значение поля. удалить ()2. вы должны использовать
update
с ТОЧЕЧНЫМИ путями вместоset