prescottprue / redux-firestore

Redux bindings for Firestore

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

FirestoreReducer Typescript not working as expected

bawahakim opened this issue · comments

What is the current behavior?

Using Typescript, I wanted to get access to the properties of my firestore data. Reading the docs, I realized it was possible with firebase, but notmention of firestore. I tried to implement it and when I created my RootState interface, I noticed a couple of things:

  1. There is no FirestoreReducer.Reducer implemented in redux-firestore. I only found it in react-redux-firebase.
  2. In the FirestoreReducer in react-redux-firebase, I noticed there was no Schema type that could be implemented. I don't know if it's normal, because we need to pass in our own Schema so it knows what to expect when you fetch the data. This works fine with the FirebaseReducer.
  3. So I tried something out. I am new to Typescript, so it might not be proper, or maybe I don't understand something fundamental :

I added FirestoreReducer to redux-firestore, and added a Schema type. Also copied over the data and ordered types from FirebaseReducer :

export namespace FirestoreReducer {
  export interface Reducer<Schema extends Record<string, any> = {}> {
    composite?: Data<any | Dictionary<any>>;
    data: { [T in keyof Schema]: Record<string, Schema[T]> };
    errors: {
      allIds: string[];
      byQuery: any[];
    };
    listeners: Listeners;
    ordered: {
      [T in keyof Schema]: Array<Schema[T]>;
    };
    queries: Data<ReduxFirestoreQuerySetting & (Dictionary<any> | any)>;
    status: {
      requested: Dictionary<boolean>;
      requesting: Dictionary<boolean>;
      timestamps: Dictionary<number>;
    };
  }

  const prototype: {};
}

My Schema and RootState :

interface Schema {
  programs: Program;
}
export interface RootState {
  firebase: FirebaseReducer.Reducer<UserAccount, Schema>;
  firestore: FirestoreReducer.Reducer<Schema>;
}

I also noticed something else : ordered: { [T in keyof Schema]: Array<{ key: string; value: Schema[T] }> }. I don't know if this is intended, but with this I don't get the right data unless you specify .value when you fetch your data. For example :

const programs = useSelector((state: RootState) => state.firestore.ordered.programs);
programs.map(p => p.value.ProgramField)

Changing this to ordered: {[T in keyof Schema]: Array<Schema[T]>; }; fixes this. With these changes, I can now call

programs.map(p => p.ProgramField)

Am I doing this right? Or is there already a way to do it properly with the current version? Appreciate any help!

Which version of redux-firestore are you using? What about other dependencies?
react-redux-firebase: 3.6.0
redux-firestore: 0.13.0

Thanks for posting! Will look closer, but on initial glance it looks great - feel free to open a PR with proposed changes if you get a chance and we can start testing it out

@feelthepain444 do you need any help with this?

I would like to be able to add type checking to my firestore reducer as well.

Something to keep in mind is that firestore can hold the user profile instead of RTDB, so two generic parameters (Profile & Schema) may be desired by some users.

@alexandermckay, we recently had a switch in our project, and we won't be using Firebase. But I already made a PR here : #296

v0.15.0 release has types for the reducer

Please reach out if things aren't working as expected

Please reach out if things aren't working as expected

@prescottprue That link 404's, seems there is no v0.15.0 release yet?

For some reason it was storing just as a draft - published now