Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firestore doesn't support JavaScript objects with custom prototypes?

I'm using the node Bigquery Package, to run a simple job. Looking at the results (say data) of the job the effective_date attribute look like this:

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

which is obviously an object within the returned data object.

Importing the returned json into Firestore gives the following error:

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).

Is there an elegant way to handle this? Does one need to iterate through the results and convert / remove all Objects?

like image 694
Jan Krynauw Avatar asked Sep 07 '18 11:09

Jan Krynauw


People also ask

Can I use firestore with node js?

If you are developing a Web or Node. js application that accesses Cloud Firestore on behalf of end users, use the firebase Client SDK. Note: This Cloud Firestore Server SDK does not support Firestore databases created in Datastore mode. To access these databases, use the Datastore SDK.

Can firestore store objects?

Cloud Firestore is optimized for storing large collections of small documents. All documents must be stored in collections. Documents can contain subcollections and nested objects, both of which can include primitive fields like strings or complex objects like lists.

Can I add to an array firestore?

Firestore lets you write a variety of data types inside a document, including strings, booleans, numbers, dates, null, and nested arrays and objects.

How do I get the size of an array in firestore?

There is no simple function to get the length of an array in a document. What you will have to do is get() the document, then get() the array field from the DocumentSnapshot, and get the size of the List object from that field.


2 Answers

The firestore Node.js client do not support serialization of custom classes.

You will find more explanation in this issue:
https://github.com/googleapis/nodejs-firestore/issues/143
"We explicitly decided to not support serialization of custom classes for the Web and Node.JS client"

A solution is to convert the nested object to a plain object. For example by using lodash or JSON.stringify.

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

Here is a related post:
Firestore: Add Custom Object to db

like image 89
volvotrax Avatar answered Oct 14 '22 07:10

volvotrax


Another way is less resource consuming:

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

Note: it works only for objects without nested objects.

Also you may use class-transformer and it's classToPlain() along with exposeUnsetFields option to omit undefined values.

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

firestore
  .collection('collectionName')
  .doc('id')
  .set(instanceToPlain(myCustomObject, {exposeUnsetFields: false}));
like image 9
Viacheslav Dobromyslov Avatar answered Oct 14 '22 05:10

Viacheslav Dobromyslov