ngxs-labs / firestore-plugin

Firestore plugin for NGXS
https://ngxs-firebase-plugin.netlify.com/
MIT License
19 stars 14 forks source link

How to add items or sub items? #25

Closed jaytonic closed 3 years ago

jaytonic commented 3 years ago

Hi,

I was using NGXS and I added firestore as backend to persist my data. all the Get operations are working properly, but I'm having some trouble with the insert part:

  1. I was thinking that when I update my local store, firestore would be updated also. So I tought something like this would work:

    @Action(CreateTripAction)
    createTrip(ctx: StateContext<TripsStateModel>, action: CreateTripAction) {
    const state = ctx.getState();
    
    const newTrip = {
    id: '',
    owner: firebase.auth().currentUser.uid,
    name: action.name,
    startDate: firebase.firestore.Timestamp.fromDate(action.startDate),
    endDate: firebase.firestore.Timestamp.fromDate(action.endDate),
    stops: [],
    };
    
    ctx.setState(
    patch({
      trips: insertItem(newTrip, 0),
    })
    );
    }

    But it doesn't, I had to call the create$ function. Am I missing something or is it what I should do?

  2. Because things get a(little) bit more complicated when I've a subcollection that I want to update. Currently I've this, that works in local, but nothing gets on firestore:

    @Action(AddStop)
    addStop(ctx: StateContext<TripsStateModel>, action: AddStop) {
    const state = ctx.getState();
    const trip = state.trips.filter((item: Trip) => item.id === state.activeTrip)[0];
    console.log(trip);
    ctx.setState(
      patch({
        trips: updateItem((item: Trip) => item.id === state.activeTrip, patch({ stops: [...trip.stops, action.stop] })),
      })
    );
    }

    I find cool to have all those nice methods on NGXS to update/append/... items. but here, am I supposed to call the upsert with the whole trip? Or again, am I missing something?

Here is my model for the reference:

export interface Trip {
  id: string;
  owner: string;
  name: string;
  startDate: Timestamp ;
  endDate: Timestamp;
  stops: Stop[];
}

export interface Stop {
  id: string;
  name: string;
  coordinates: firebase.firestore.GeoPoint;
}
joaqcid commented 3 years ago

hi @jgrossrieder

the way the plugin works is connecting data updates from Firestore -> NGXS, not the other way around.

1- For creating, updating documents the only thing you need to call is the create$ or update$, so your code should look like this. If you connected data in your state in ngxsOnInit and set the StreamEmitted action to update the state, the plugin will sync the changes that ocurr on Firestore back to NGXS, makes sense?

@Action(CreateTripAction)
createTrip(ctx: StateContext<TripsStateModel>, action: CreateTripAction) {

  const newTrip = {
    id: '',
    owner: firebase.auth().currentUser.uid,
    name: action.name,
    startDate: firebase.firestore.Timestamp.fromDate(action.startDate),
    endDate: firebase.firestore.Timestamp.fromDate(action.endDate),
    stops: [],
  };

 return this.tripFirestore.create$(newTrip)
}

Regarding subitems, you dont need to use update/apend/... just by calling the create$or 'update$ method passing the stopsfield, you'll save your data to firestore

const trip ={
  stops: [{
  //...
   }] 
}
this.tripsFirestore.create$(trip)

just remember, the idea is that you setup a connection to keep the data in the store synced with Firestore's, so you setup your connection, your StreamEmmited action to update your store, and after that you just need to write to firestore, and th plugin will handle the rest for you

joaqcid commented 3 years ago

if you need a more complete example you can take a look to this post https://indepth.dev/posts/1322/firebase-ngxs-the-perfect-couple

jaytonic commented 3 years ago

Yeah, I kind of understood that in between(that basically the plugin was "only" reflecting firebase state into NGXS. I initially tought it was kind of a two-way sync(since it was using angularfire that works like this).

if you need a more complete example you can take a look to this post https://indepth.dev/posts/1322/firebase-ngxs-the-perfect-couple

I did, it has been quite my bible up until now, but there is no update operation, no cases with subcollections either

joaqcid commented 3 years ago

no, its not a two-way, the source of truth is Firestore, and the plugin syncs the data from Firestore to NGXS, in order to make it easier to select data and merge it with data you might pull from other origins

In this section, you will see the example with create$ https://indepth.dev/posts/1322/firebase-ngxs-the-perfect-couple#firestore-plugin-in-action

About subcollections, if you are talking about an Array within an object, there's nothing special you need to do about it, just set the array in the object before you create it or update it

jaytonic commented 3 years ago

Thank you for your answer, sorry I forgot to close it earlier