react-native-redux-saga-firebase-patterns
react-native-redux-saga-firebase-patterns copied to clipboard
Any runnable example application?
Hi there, i like your suggested patterns, bundling react-native, redux-saga and firebase together. My aim is to understand the 'whole thing' and figure out, how these patterns work in a runnable application. Is there any example of how to use/call the redux-actions/-sagas in a react-native component? what about calls that depend on each other? how do i call them?
Hi @ralcon, Thanks! The whole idea is not to mess with async stuff with the component. So all you have to do in the components is to call an action (you don't call a saga - it responses to actions).
Let's look at the example in this repo: Say you want to update user contact while pressing a button.
We've already prepared an action creator named updateUserContactsRequested (at actions.js file).
All you have to do in your component is to map that action to props and connect it to react-redux (as usual in redux) and then call this prop with appropriate parameters when you press the button.
In our case it would look like this: this.props.updateUserContactsRequested(this.props.uid, 'contactUid', this.props.username, this.props.userPhone)
In order to load the user contacts and initialize the listener, you just have to call listenToUserContacts(this.props.uid) in the componentDidMount lifecycle method.
Note: I assumed that in your props you have uid, username and phone, which were probably mapped from redux state.
Regarding calls that depend on each other - what do you exactly mean? can you give an example?
Hi @omer88, loading main data is easy with this pattern (like you mentioned). First, for example, let's say, we have following data structure in a firebase database:
tasks
|-- taskOneId
| |-- name: My first Task
| |-- completed: false
| |-- participants
| |-- firstParticipantId
| |-- secondParticipantId
| |-- thirdParticipantId
|-- taskTwoId
|-- ...
participants
|-- firstParticipantId
| |-- part_completed: false
| |-- user: firstUserId
|-- secondParticipantId
| |-- part_completed: false
| |-- user: firstUserId
|-- thirdParticipantId
| |-- part_completed: false
| |-- user: firstUserId
|-- fourthParticipantId
|-- ...
users
|-- firstUserId
| |-- name: Leonardo
| |-- age: 13
|-- secondUserId
| |--name: Donatello
| |-- age: 22
|-- thirdUserId
| |--name: Michaelangelo
| |-- age: 21
|-- fourthUserId
|-- ...
Second, let's say we got a list of taskIds, where i am involved in. In the data structure, it is only taskOneId and my userId is firstUserId. My goal is to have a query (and data) for all participans of taskOneId and the inherent user! So i query the data like this:
// ----- saga_registration.js -----
export default function* rootSaga() {
yield all([
sagas.watchListener(metaTypes.tasks),
sagas.watchListener(metaTypes.participants),
sagas.watchListener(metaTypes.users)
])
}
// ----- actions.js -----
export function listenToTasks() {
const ref = firebase.database().ref('tasks')
return firebaseListenRequested(ref, metaTypes.tasks)
}
// ----- MyTasksMask.js => React.Component -----
class MyTasks extends React.Component {
componentDidMount() {
this.props.getTasks()
}
....
}
export default connect(
// MAP_STATE_TO_PROPS
(state, props) => { ... },
// MAP_DISPATCH_TO_PROPS
(dispatch) => {return {getTasks: () => {return dispatch(listenToTasks())}}}
)(MyTasks)
With this, i got my listener installed and receive task data. Now i want to iterate through the participants, register the listener and receive participants data for every participant item. The same with users data.
Lets describe it in plain text: Receive the tasks, where i am involved to (by ID). Get all participants of the tasks, where i am involved to and query and receive user data of the users in participants.
A little bit clearer? How do i get this work in only one React.Component?
I think the propblem is to identify, when the previous request is loaded!?
Maybe, my expected state result is the best description. I expect my state to be...
state.firebase: Object
|-- users: Object
| |-- error: ""
| |-- inProgress: false
| |-- items: Object
| |-- firstUserId:Object
| | |-- name: Leonardo
| | |-- age: 13
| |-- secondUserId:Object
| | |-- name: Donatello
| | |-- age: 22
| |-- thirdUserId:Object
| |-- name: Michaelangelo
| |-- age: 21
|-- participants: Object
| |-- error: ""
| |-- inProgress: false
| |-- items: Object
| |-- firstParticipantId:Object
| | |-- part_completed: false
| | |-- user: firstUserId
| |-- secondParticipantId:Object
| | |-- part_completed: false
| | |-- user: secondUserId
| |-- thirdParticipantId:Object
| |-- part_completed: false
| |-- user: thirdUserId
|-- tasks: Object
|-- error: ""
|-- inProgress: false
|-- items: Object
|-- taskOneId:Object
|-- name: My first Task
|-- completed: false
|-- participants: Object
|-- firstParticipantId
|-- secondParticipantId
|-- thirdParticipantId