Firestore не поддерживает объекты JavaScript с настраиваемыми прототипами?

Я использую узел Пакет BigQuery для выполнения простой работы. Глядя на результаты (скажем, data) задания, атрибут effective_date выглядит так:

 effective_date: BigQueryDate { value: '2015-10-02' }

который, очевидно, является объектом в возвращенном объекте data.

Импорт возвращенного json в Firestore дает следующую ошибку:

UnhandledPromiseRejectionWarning: Error: Argument "data" is not a 
valid Document. Couldn't serialize object of type "BigQueryDate". 
Firestore doesn't support JavaScript objects with custom prototypes 
(i.e. objects that were created via the 'new' operator).

Есть ли элегантный способ справиться с этим? Нужно ли перебирать результаты и преобразовывать / удалять все объекты?

Вероятно, вам нужно добавить .doc() в конец ссылки на firestore.

Ronnie Royston 29.10.2018 23:19
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
18
1
3 958
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Клиент firestore Node.js не поддерживает сериализацию пользовательских классов.

Более подробное объяснение вы найдете в этом выпуске:
https://github.com/googleapis/nodejs-firestore/issues/143
«Мы явно решили не поддерживать сериализацию пользовательских классов для веб-клиентов и клиентов Node.JS»

Решение состоит в том, чтобы преобразовать вложенный объект в простой объект. Например, используя lodash или JSON.stringify.

firestore.collection('collectionName')
    .doc('id')
    .set(JSON.parse(JSON.stringify(myCustomObject)));

Вот связанное сообщение:
Firestore: добавить настраиваемый объект в базу данных

Использование этого способа не позволяет вам устанавливать значения полей, такие как приращения и операции с массивами!

Ayyappa 26.06.2020 14:28

Также он разбивает типы даты.

Viacheslav Dobromyslov 19.02.2021 17:34

Другой способ менее ресурсоемкий:

firestore
  .collection('collectionName')
  .doc('id')
  .set(Object.assign({}, myCustomObject));

Примечание: работает только для объектов без вложенных объектов.

Также вы можете использовать class-transformer и его classToPlain() вместе с exposeUnsetFields вариант, чтобы опустить значения undefined.

npm install class-transformer
or
yarn add class-transformer
import {classToPlain} from 'class-transformer';

firestore
  .collection('collectionName')
  .doc('id')
  .set(classToPlain(myCustomObject, {exposeUnsetFields: false}));

это работает лучше для меня, потому что, если у вас есть дата в вашем настраиваемом объекте, firestore повторно записывает ее как метку времени. Если вы выполните JSON.stringify (), ваша дата станет строкой, и это может стать кошмаром позже

Andre Cytryn 19.02.2021 17:06

@AndreCytryn Подробнее о проблемах сериализации дат можно прочитать здесь stackoverflow.com/questions/53520674/… и здесь stackoverflow.com/questions/10286204/…

Viacheslav Dobromyslov 13.03.2021 09:07

Если у вас есть объект Timestamp, не используйте JSON.parse(JSON.stringify(obj)) или classToPlain(obj), так как они повредят его при сохранении в Firestore.

Лучше использовать метод {...obj}.

firestore
  .collection('collectionName')
  .doc('id')
  .set({...obj});

Другие вопросы по теме