Функция DocumentReference.set() вызывается с недопустимыми данными. Неподдерживаемое значение поля: пользовательский объект бюджета
Ниже код работает отлично до сегодняшнего дня. Но я не знаю, теперь он не работает и дает ошибку ниже. Не могли бы вы рассказать мне, почему?
Ошибка: функция DocumentReference.set() вызывается с недопустимыми данными. Неподдерживаемое значение поля: пользовательский объект бюджета
export class Project {
id: string = null;
name: string;
budgetList?: Budget[];
}
export class Budget {
id: string;
amount: number;
contingency: number = 20;
budgetGroup: BudgetGroup = new BudgetGroup();
creationTime: string;
}
код:
async create(data: DtoProject): Promise<Project> {
try {
const projectId: string = this.fireStore.createId();
const budgets = this.budgetProvider.createBudgets(data.budgetList, projectId);//budgets
const proj: Project = {
id: data.id,
name: data.name,
budgetList: budgets,//here it has the error
}
proj.id = projectId;
await this.fireStore.doc<Project>('projects/${projectId}/').set(proj));//project
}
}
createBudgets(data: Budget[], projectId: string): Budget[] {
let budgets: Budget[] = [];
forEach(data, (d) => {
const budgetId: string = this.fireStore.createId();
d.id = budgetId;
budgets.push(d);
this.fireStore.doc<Budget>('projects/${projectId}/budgets/${budgetId}').set({
id: budgetId,
amount: d.amount,
contingency: d.contingency,
budgetGroup: d.budgetGroup,
creationTime: moment().format()
})
})
return budgets;
}
Ответы
Ответ 1
Вы должны преобразовать свой массив бюджетов в массив чистых объектов JavaScript.
Первый шаг:
const budgets = arrayOfBudget.map((obj)=> {return Object.assign({}, obj)});
Второй шаг:
const proj: Project = {
id: data.id,
name: data.name,
budgetList: budgets
}
Тогда тебе пора.
Кстати, при разработке на языке, который компилируется в JavaScript, вы не можете использовать пользовательские объекты. Вместо этого вам нужно использовать чистые объекты JavaScript для сохранения в базе данных Firestore.
Например, допустим, у вас есть этот класс ниже:
export class User {
id: string;
name: string;
}
И вы пытаетесь выполнить следующий код:
const user = new User();
this.db.collection('users').doc().set(user)
Вы получите ошибку вроде:
неверные данные. Данные должны быть объектом, но это был: пользовательский объект User
Теперь, если вы попытаетесь выполнить эту другую строку кода:
this.db.collection('users').doc().set(Object.assign({}, user))
Вы увидите, что ваш объект был сохранен в базе данных. В основном Object.assign
делает то же самое, что и:
this.db.collection('users').doc().set({id: user.id , name: user.name})
Так что используйте Object.assign
, это сэкономит вам много времени.
ОБНОВИТЬ
Как я указал в комментарии ниже, вы можете найти то, что документация говорит о пользовательских объектах здесь. Как видите, есть предупреждение:
//Веб использует объекты JavaScript
Ниже приведен скриншот того, что написано в документации.
Ответ 2
Вы можете преобразовать объект в строку и снова проанализировать его, чтобы удалить имена классов объекта.
const budgets = this.budgetProvider.createBudgets(JSON.parse(JSON.stringify(data.budgetList)), projectId);
Ответ 3
Ошибка просто говорит о том, что введенные данные неверны!
Я также столкнулся с ошибкой из ниоткуда, потому что я удалил поле ввода из интерфейса, который должен был получить его значение и загрузить его в документ некоторой коллекции!
примечание: проверьте ваш код в .ts файле firebase.firestore firebase.firestore().collection("some_name").add()/set()
если есть какое-то ненужное поле или нет.
Ответ 4
Вы также можете использовать оператор распространения как:
this.fireStore
.doc<Project>('projects/${projectId}/')
.set( {...proj} ))
Это работает для меня