in a react-native app that stores data in both a redux store as well as firebase firestore, I have a onSnapshot listener thats listens to a collection. in each document in this collection, there is an object with a couple properties that will change in value over time. ideally, when one of these object property values change, it should be reflected win the redux store, and thus the UI. the problem is, that when one of these values changes, the redux store is not updated.
listener:
export const onAgendaChange = (uid, role, dispatch) => {
let query;
if (role == 'A') {
query = 'a.uid';
} else {
query = 'b.uid';
}
console.log('(actions/agenda) Firestore Read: getAgenda()');
return firebase
.firestore()
.collection('events')
.where(query, '==', uid)
.orderBy('date')
.onSnapshot((querySnapshot) => {
const agenda = []
querySnapshot.docChanges().forEach(change => {
console.log(`change: ${change.type}`) // does not log anything
})
querySnapshot.forEach((doc) => {
let event = doc.data();
event.id = doc.id;
agenda.push(event);
dispatch({ type: types.LOAD_AGENDA_SUCCESS, payload: agenda });
});
});
};
reducer:
const INITIAL_STATE = {
loading: false,
events: []
};
export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case types.LOAD_AGENDA:
return {
...state,
loading: true
};
case types.LOAD_AGENDA_SUCCESS:
return {
loading: false,
events: action.payload
};
default:
return {
...state
};
}
};
screen component using this data:
<View style={styles.container}>
<FlatList
data={this.props.events}
extraData={this.props}
keyExtractor={(item) => {
return (
item.toString() +
new Date().getTime().toString() +
Math.floor(Math.random() * Math.floor(new Date().getTime())).toString()
);
}}
renderItem={({ item, index }) => {
const title = this.props.role == 'A' ? item.b.legalName : item.a.legalName;
const participantCheckInStatus =
this.props.role == 'A' ? item.checkedIn.b : item.checkedIn.a;
const currentUserCheckInStatus =
this.props.role == 'A' ? item.checkedIn.a : item.checkedIn.b;
console.log("agenda type B: " + item.checkedIn.b + " agenda type A: " + item.checkedIn.a)
return (
<Components.AgendaItem
title={title}
participant={participantCheckInStatus}
checkedIn={currentUserCheckInStatus}
navigation={this.props.navigation}
evnt={item}
/>
);
}}
/>
</View>
the document's structure in this collection looks something like:
{
exampleMap: { a: false, b: false },
string: '',
string: '',
map: { ... },
map: { ... }
}
other notes:
- whether the document is updated by action or from firebase console, the document is successfully updated in firestore
- even if the react native application is refreshed, the component using the data in question does not update
- I have another collection with documents that also have maps. when changing the values in this other collection's map, the component using this data updates properly. they have similar reducers, both reducers are persisted, and the listeners are identical.
- im also using redux-persist on these relevent reducers ive mentioned, both the working and non-working reducers
- im using redux-thunk
PECULIAR OBSERVATION:
- the ONLY time the component receives prop updates properly is if the app install is fresh, meaning the app has been deleted and freshly installed on simulator. any subsequent runs the prop data will not update.
Ive confirmed inside the parent and child components using this redux store, that the document's exampleMap sub-properties value does not change in redux when I change the value in firebase console. so I played around with FlatList's extraData prop, to no avail.
Anyway, any thoughts on how to get these changes to the redux store?