Firestore: add custom object in db

Good morning,

I tried adding a newly created object from this class:

export class Sponsor implements ISponsor { title: string; description?: string; creation: ICreation; constructor(title: string, description: string, author: string) { this.title = title; this.description = description; this.creation = new Creation(author); } } 

and in my service, the create function looks like this:

 createSponsor(sponsor) { sponsor.id = this.afs.createId(); return this.collection.doc(sponsor.id).set(sponsor); } 

When I try to do this, I get the following error:

FirebaseError: [code = invalid-argument]: The DocumentReference.set () function was called with invalid data. Data should be an object, but it was: a sponsor user object

How can I solve this problem?

+10
source share
8 answers

You can also use Object.assign ({}, sponsor)

so in case of yor it will be

 this.collection.doc(sponsor.id).set(Object.assign({}, sponsor)); 
+17
source

You can also serialize your object in JSON and deserialize it back to a regular JavaScript object, for example

 this.collection.doc(sponsor.id).set(JSON.parse( JSON.stringify(sponsor))); 

works with deep embedding.

+6
source

thanks to Fabian Wiles - I get it!

while firebase can send data inside your object to the database when the data command cannot return it back to an instance of your class. Therefore classes are prohibited

just save the object as follows:

 interface Person{ name: string; age: number } var person: Person = { name: 'Toxicable', age: 22} ; 
+3
source

This is really weird behavior from firebase. And how I fixed it - by creating a new interface and adding a conversion method to my class:

 export class Happening { constructor( public date: EventDate, public participants: Array<string>, public title: string, public text: string, public uid?: string, public id?: string ){} public toDto = (): HappeningDto => { return { date: { year: this.date.year, month: this.date.month, day: this.date.day }, participants: this.participants ? this.participants : [], title: this.title, text: this.text ? this.text : '', uid: this.uid, id: this.id ? this.id : null } } } export interface HappeningDto { date: { year: number, month: number, day: number }, participants: Array<string>, title: string, text: string, uid?: string, id?: string } 

Now i can do

 add(event: Happening){ event.uid = this.uid; this.$afs.collection<HappeningDto>('events').add(event.toDto()) .then( (success) => console.log(success), (err) => console.warn(err) ) } 
+1
source

For my solution, I had an Interface :

 export interface Launch { id: string; date: Date; value: number; 

}

const project = {} as a run;

this.db.collection ('starts') add (project) ;.

+1
source

If you use Angular and AngularFire2, you can use AngularFirestype. This module is intended to replace AngularFirestore and allows you to receive and install data in Firestore directly with user objects.

To do this, you need to perform 3 steps:

1. Install angular-firestype

 `npm install angular-firestype --save` 

2. Initialize the AngularFirestype module with the mapping object

 import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { AngularFireModule } from 'angularfire2'; import { AngularFireAuthModule } from 'angularfire2/auth'; import { AngularFirestypeModule, ModelType } from 'angular-firestype'; import { environment } from '../environments/environment'; import { User } from './user.ts'; import { Address } from './address.ts'; import { Message } from './message.ts'; /** * Definition of the app model mapping. * For more information, see https://github.com/bricepepin/angular-firestype#mapping-object. */ const model: {[key: string]: ModelType<any>} = { users: { type: User, arguments: ['username', 'image'], structure: { adress: Address }, subcollections: { messages: Message } } }; @NgModule({ imports: [ AngularFireModule.initializeApp(environment.firebase), AngularFireAuthModule, AngularFirestypeModule.forRoot(model), // Import module using forRoot() to add mapping information ], declarations: [ AppComponent ], bootstrap: [ AppComponent ] }) export class AppModule {} 

3. Inject AngularFirestype Service

 import { Component } from '@angular/core'; import { AngularFirestype, Collection, Document } from 'angular-firestype'; import { User } from './user.ts'; @Component({ selector: 'app-root', templateUrl: 'app.component.html', styleUrls: ['app.component.css'] }) export class AppComponent { const users: Observable<User[]>; const user: User; constructor(db: AngularFirestype) { const usersCollection: Collection<User> = db.collection<User>('users'); usersCollection.valueChanges().subscribe(users => this.users = users); const userDoc: Document<User> = usersCollection.doc('user1'); userDoc.valueChanges().subscribe(user => this.user = user); userDoc.set(this.user); } } 

Basically you can use AngularFirestype as you use Angularfirestore.
For more information, see the Homepage here: https://github.com/bricepepin/angular-firestype .

0
source

Firestore does not support this. But you can use https://github.com/typestack/class-transformer. This works great for us.

0
source

Yeah. The @sgt_lagrange solution is helpful.

 this.collection.doc(theObjectId).set(Object.assign({}, objectWantToSave)) 

The @Peter solution with JSON.parse and JSON.stringify has a problem with firestore.Timestamp. JSON.parse creates a map field, not a timestamp field.

0
source

Source: https://habr.com/ru/post/1272357/


All Articles