Store: 馃悶[BUG]: STORE X Firebase @angular/fire - DocumentReference

Created on 3 Jun 2020  路  9Comments  路  Source: ngxs/store

Affected Package

The issue is caused by package @ngxs/store

Is this a regression?

Do not know.

Description

I use firebase in my projects, when I'm going to dispatch a document that has a field of type DocumentReference, I get an NGXS error.

ERROR TypeError: Cannot read property 'ignoreUndefinedProperties' of undefined

馃敩 Minimal Reproduction

stackblitz: https://stackblitz.com/edit/ngxs-firebase-issue
github: https://github.com/gustavodamazio/ngxs-firebase-issue

馃敟 Exception or Error


ERROR TypeError: Cannot read property 'ignoreUndefinedProperties' of undefined
    at Object.get [as JT] (vendor.js:70452)
    at vendor.js:77428
    at Array.forEach ()
    at deepFreeze (vendor.js:77421)
    at vendor.js:77431
    at Array.forEach ()
    at deepFreeze (vendor.js:77421)
    at vendor.js:77431
    at Array.forEach ()
    at deepFreeze (vendor.js:77421)

Environment


Libs:
- @angular/core version: 9.1.9
- @ngxs/store version: 3.6.2


Browser:
- [ X ] Chrome (desktop) version 83.0.4103.97

Most helpful comment

@gustavodamazio I've written a handful of angular and firebase apps, and I never stored firebase objects in NGXS. The Firebase SDK has a ton of optimizations in it and I always just pulled from firebase directly. I found that most of the time, when using Firebase, it was much easier to use it directly and keep NGXS around for non-firebase things. That being said, you could use the facade pattern in NGXS and merge your firebase data with your NGXS data. TBH in all the firebase apps I've done, I've never had a need to do that. My advice would be go straight firebase.

All 9 comments

please add github repo for reproduce or stackblitz

@splincode , thanks, i updated and improved the description.

@gustavodamazio I could be wrong, but I don't think it's recommended to save objects like a DocumentReference in the store. I think I've always saved serializable objects in my store. Maybe @splincode or @markwhitfeld could clarify, but I think the problem is that the object you're storing (DocumentReference) is too complex.

I would probably store it with just the path, not the entire ref:
Screen Shot 2020-06-09 at 2 24 44 PM

https://www.ngxs.io/recipes/style-guide#avoid-saving-class-based-instances-in-your-state

@richarddavenport, @splincode. Thank you for your help. I understand that DocumentReference is an object and a very complex class. But being able to access DocumentReference makes interaction with the database much easier. And I have objects that come with more than 7 properties that are DocumentReference, in very large data collections, this DocumentReference simplification solution for an object example: ref: {id: string, path: string}. ends up being a bit expensive and very manual with the structure that we already have today.
I would like to have another way to solve it, without going through my data collection and simplifying all the properties that are DocumentReference.
But I don't think it will be possible, due to the way the stores were designed to work.
Anyway, thanks again for the help.

I use ngxs data plugin if I need to work with entities from my state as a service

@StateRepository()
@State({
 //...
})
@Injectable()
export class MyState extends NgxsDataRepository<Entity> {
  public otherData: OtherData = new OtherDate();

  public ngxsOnChanges(changes): void {
    // this.otherData.setValue(changes.next);
  }
}

@gustavodamazio I've written a handful of angular and firebase apps, and I never stored firebase objects in NGXS. The Firebase SDK has a ton of optimizations in it and I always just pulled from firebase directly. I found that most of the time, when using Firebase, it was much easier to use it directly and keep NGXS around for non-firebase things. That being said, you could use the facade pattern in NGXS and merge your firebase data with your NGXS data. TBH in all the firebase apps I've done, I've never had a need to do that. My advice would be go straight firebase.

Forgot to mention, if you must use DocRef's (which I agree are incredibly useful), the reason I would just store the path string, is because you can always get the docRef from the path.
AngularFire Way
RxFire Way

So, you could easily create a selector that would hand back to you all the docRefs you need without storing them in the store.

Thank you, I believe I was able to better understand and learn how the store works, the possible restrictions on very complex objects and classes and the possible solutions to solve this problem. To implement the store in the current scenario that I have, we will have to refactor some things.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mailok picture mailok  路  19Comments

zygimantas picture zygimantas  路  32Comments

sanchezcarlosjr picture sanchezcarlosjr  路  40Comments

markwhitfeld picture markwhitfeld  路  41Comments

internalsystemerror picture internalsystemerror  路  33Comments