2

I want to fetch a document called settings from a Firestore subcollection, then load it into my local component (and Redux store) as a variable named settings with the following value:

settings: {
  name: 'Waldo Garply',
  email: '[email protected]',
  mobile: '555-789-1234',
  timestamp: '1546304499032',
}

Instead, my app fails to compile and I get the following error message in my console:

console.error

Uncaught TypeError: Cannot read property 'settings' of undefined at Function.mapStateToProps [as mapToProps]

What am I doing wrong and how can I achieve my expected behavior?

I am storing my Firestore data as follows.

Firestore
.
├── users
|   ├── OGk02kJbQUesTeVhTrLBnERSxrfm
|   |   ├── settings
|   |   |   ├── VrxDnSxpUw6wgX0n9c1FbapmLaLa
|   |   |   |   ├── name: Waldo Garply
|   |   |   |   └── timestamp: 1546304499030
|   |   |   ├── cGVHxSkU3Lcb9WAYWjnJKcLOTYf8
|   |   |   |   ├── name: Waldo Garply
|   |   |   |   ├── email: [email protected]
|   |   |   |   └── timestamp: 1546304499031
|   |   |   ├── qoDYG2xloEvUUhGQyF9zXy9MTMIq
|   |   |   |   ├── name: Waldo Garply
|   |   |   |   ├── email: [email protected]
|   |   |   |   ├── mobile: 555-789-1234
|   |   |   |   └── timestamp: 1546304499032

Notice, I am storing a unique snapshot of all the settings values (including a timestamp) each time any of the settings values changes; I then fetch the latest setting (sorted by timestamp) and load it. So I am needing an automatic listener on the settings object.

I am using the following code in my component (called DetailsTab.js) to try connect to Firestore to fetch the data then load it as a settings variable into my component and Redux store.

DetailsTab.js
function mapStateToProps( state ) {
  console.log('state\n', state);
  return {
    user: state.auth.user,
    // attempted all the following individually
    settings: state.firestore.data.users.settings, // throws error
    settings: state.firestore.ordered.users.settings, // throws error
    settings: state.firestore.ordered.users[0] // throws error
    settings: state.firestore.ordered.users // returns 'users' object
  }
}

export default compose(
  withStyles(styles, { withTheme: true }),
  connect(mapStateToProps, mapDispatchToProps),
  firestoreConnect(props => {
    return [
      {
        collection: 'users',
        doc: props.user.data.uid,
        subcollections: [
          {
            collection: 'settings',
            limit: 1,
            orderBy: ['timestamp', 'desc',],
            storeAs: 'settings',
          },
        ],
      },
    ];
  })
)(DetailsTab)

The following is how the data appears when my console logs it.

console.log
state
└── firestore
    ├── data
    |   └── users
    |       └── OGk02kJbQUesTeVhTrLBnERSxrfm
    |           └── settings
    |               └── qoDYG2xloEvUUhGQyF9zXy9MTMIq
    |                   ├── name: Waldo Garply
    |                   ├── email: [email protected]
    |                   ├── mobile: 555-789-1234
    |                   └── timestamp: 1546304499032
    ├── ordered
    |   └── users [Array(1)]
    |       └── 0
    |           ├── id: OGk02kJbQUesTeVhTrLBnERSxrfm
    |           └── settings [Array(1)]
    |               └── 0
    |                   ├── id: qoDYG2xloEvUUhGQyF9zXy9MTMIq
    |                   ├── name: Waldo Garply
    |                   ├── email: [email protected]
    |                   ├── mobile: 555-789-1234
    |                   └── timestamp: 1546304499032
2
  • In mapStateToProps try to fetch the data by state.firestore.ordered.users.settings to see if the data you are looking for is there. Commented Jan 1, 2019 at 22:13
  • @Dez: That did not work. I edited the question to show all the possible paths to settings I have attempted under mapStateToProps . Commented Jan 1, 2019 at 23:36

1 Answer 1

1

The solution was to add the appropriate error guards as follows.

function mapStateToProps( state ) {
  console.log('state\n', state);
  const settings = state.firestore.ordered.users
                && state.firestore.ordered.users[0]
                && state.firestore.ordered.users[0].settings
                && state.firestore.ordered.users[0].settings[0];
  return {
    user: state.auth.user,
    settings,
  }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.