-
-
Notifications
You must be signed in to change notification settings - Fork 555
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(core): new pattern for firebase instance in thunks/sagas (getFirebase not part of v3 API) #635
Comments
@sbtgE What version are you using? How/when are you using getFirebase. It depends on when your instance is initialized. |
@prescottprue trying "3.0.0-alpha.9" and I want to access firebase instance in thunk:
actions.js
|
@sbtgE I have personally been leaving the business logic within handlers (thunks were most often not needed in my cases), or where necessary passed the wrapped method through (i.e. Wondering for your case:
The reason I ask is that the v3 API is by no means stable, so I am trying to understand as many use cases as possible. Especially since there has been a middleware planned for a while that will handle calling async methods (like push/set) through dispatching an action like |
Thank you for the comprehensive answer. First of all, I have to admit, that I am not so experienced in the topic but I will do my best to describe the whole thing. According to my current experience context API is great, but I don't see an easy way to switch from using the store and thunk with a lot of custom actions to using context actually. Imho the best way for this moment would be to support both solutions at least for the next major version - dispatching e.g. CALL_FIREBASE could be helpful. I would like to follow this topic and see what others think about that - still learning - I think that slack/discord channel would help speed up discussion. Appreciate your help @prescottprue. |
@sbtgE No problem at all, glad to talk out the options. I like the idea of keeping the API similar for this version, but still need to look into how that would be done. As for a chat line, there is the the gitter channel. |
#607 was another duplicate of this question. Clearly something that will needs to be addressed. |
Related to this, I've hit myself this issue and I feel it's also caused by the fact that neither the release tabs nor the docs for v3.0 mention this (it's actually still there) - even the migration guide doesn't mention it. |
So I've also ran into this issue and only after a few hours of trying to fix this, did I stumble upon this thread. I am still quite new to react, redux and firestore but if you still require any insight into use cases for thunks, my thoughts are that the logic put in thunks are more so for organisational and re-usability purposes as action creators can be reused by multiple components. But again I am still very new to react, redux and firebase, and for the time being I'm using probably a really bad workaround where I take the firebase/firestore instance from the current prop (which is connected to firestore using "withFirestore"), and then pass the firebase/firestore instance into the dispatched function so It can be accessed in the action creator. Obviously this is not at all ideal since you need to get and pass the firestore instance everytime you call the action creator and have no clue as to the performance or structural implications and impacts of this workaround. |
@wen-l Your logic can be separated into actionCreators as you mentioned without needing to use thunks - thunks are only needed when dispatching in async. Dispatching Actions (Async & Sync)Since As an object (each item is assumed to be a named action creator, so it is wrapped in dispatch): const mapDispatchToProps = {
someActionCreator: () => {
return { type: 'SOME_ACTION_TYPE' }
}
}
export default connect(null, mapDispatchToProps) or as a function which receives function mapDispatchToProps(dispatch, ownProps) {
return {
someActionCreator: () => {
ownProps.firebase.push('some/path', { example: 'data' })
.then(() => {
dispatch({ type: 'SOME_ACTION_TYPE' })
})
}
}
}
const enhance = compose(
withFirebase, // add props.firebase
connect(null, mapDispatchToProps)
)
export default enhance(SomeComponent) Separating LogicSince we can pass an object full of handlers in this way, it is easy to move them all to another file then just import. This can be done a number of ways including directly with Directly With Connecthandlers.js // handler name is used to denote "props" being passed and it returns a function
//
export function someHandler(props) {
return () => {
ownProps.firebase.push('some/path', { example: 'data' })
.then(() => {
dispatch({ type: 'SOME_ACTION_TYPE' })
})
}
} SomeComponent.js
With Recomposeimport * as handlers from './handlers'
const enhance = compose(
withFirebase,
connect(), // add props.dispatch
withHandlers(handlers)
)
export default enhance(SomeComponent) |
Ok thanks for this, I'm learning new things about react 😄 Without Thunk actionCreator.js export const doSometing = (props, dispatch, data) => { // Need: props and dispatch as well as data
return () => {
props.firestore.collection('dataStore').add({
...data
}).then(() => {
dispatch({ type: 'DONE_SUCCESS', data });
}).catch((err) => {
dispatch({ type: 'DONE_FAILED', err });
})
}
} SomeComponent.js import { doSomething } from '/somewhere'
function mapDispatchToProps(dispatch, ownProps) {
return {
doAction: doSomething(ownProps, dispatch, data) // Must pass props, dispatch alongside data
}
}
export default connect(null, mapDispatchToProps)(SomeComponent) With Thunk actionCreator.js export const doSometing = (props, data) => {
return (dispatch, getState) => { // We get these from thunk
props.firestore.collection('dataStore').add({
...data
}).then(() => {
dispatch({ type: 'DONE_SUCCESS', data });
}).catch((err) => {
dispatch({ type: 'DONE_FAILED', err });
})
}
} SomeComponent.js import { doSomething } from '/somewhere'
function mapDispatchToProps(dispatch, ownProps) {
return {
doAction: doSomething(ownProps, dispatch, data) // Must pass props, dispatch alongside data
}
}
export default connect(null, mapDispatchToProps)(SomeComponent) So from this example, they are practically the same except without thunk means we need to for each reference to an external handler/actioncreator we must pass along with it the So with the previous version of this react-redux-firebase, we were able to add an extra argument to get an instance of firebase or firestore using thunk so that we did not need to pass around the props either(to fetch the firestore/firebase instance from those props). But I'm not sure how the new (Not new to me, just started learning react so everything is new) context system would allow access to these firebase/firestore instances outside of passing props around. So yeah, thats the only other reason I can think of for the use of thunk in this case, feel free to correct any mistake as Im still learning. 😄. |
Also further from this, since we do not use the |
I cannot speak on thunk, but I have been using redux-saga for the past two years. This is my first attempt at creating an app using firebase. In my opinion, running firebase commands prior to dispatching redux actions isn't a viable solution. The point of saga is to manage async and sync operations in a reasonable fashion. Imagine the following scenarios: updating / pushing multiple documents at the same time, calling an external api prior to making an update, debouncing / throttling calls, etc. Given the async nature of firebase, it makes sense to handle those calls inside a saga flow. It looks like the previous version created a singleton of the firebase instance. Now that instance is create within the provider. I can create a second instance within the store creation method and pass that as the second argument of sagaMiddleware.run. Would this be okay? Or would there be an adverse reaction?
|
@opula That was actually what I was thinking would be in the docs for the new version - that should be fine. Still need to investigate if there are issues with sharing listener count across instances, but other than that things should work as expected. What you are bringing up with saga may fit better with a middleware I have been proposing for a while which would allow dispatching an action (something like |
@prescottprue I am using original firebase instance. Is this correct way. export const signIn = (credentials) => { |
Yes, that should work just fine @Akash187. That said, if you are doing email login and want to dispatch an action, you can use |
If getFirebase is not part of the v3.0.0 api then why it is mentioned here: http://docs.react-redux-firebase.com/history/v3.0.0/docs/api/get-firebase.html ? |
@atultherajput That is because it was copied over from the v2 docs. I will remove it from there, thanks for posting. All of that said, we may end up having to keep If folks could post their reason for still wanting to use it, that would be a great way to gauge if it should be kept. Currently in v3, there is not an enhancer, which means that the firebase instance is not strapped to |
Hi, I was wondering if anyone could advise: Due to
And then later on, in say a Redux action, you could do something like this
is there anything wrong with that? It seems too simple? |
* fix(docs): remove remaining instances of getFirebase from docs - #635 (#694) * feat(core): Start React hook API - #684 - @illuminist
Hello Guys, i would like to share a working solution for getting redux, react-redux, react-redux-firebase, redux-firestore, redux-thunk and redux-devtools-extension completely working back up. The below code uses the latest version of all the libraries so please look at the Please take a look at this code-pen : https://codesandbox.io/s/8423o1m529 Here i have created separate actions file which has (actions / actionCreator as some say) and call firestore functions from there, which is one of the most common use case from what i have seen. I have organized everything as i have done in my original project just not added files to folders. Also it would be great if you could just have a glimpse through it @prescottprue. The reason for me not posting everything here is that it would take too much space and this will not be a great place to do it. |
I have struggled with the same issue. The solution is to import the firebase instance you created and use it. Example:
Now, in the v3 version, you access your "firebase" instance directly, by importing it:
I hope it was plain enough. |
Helllo @omern92 Using firebase instance directly might not be a good strategy going ahead, instead you should
Now you can pass
|
I'm currently facing the same issue, except that I would like to access to my firestore instance to pre-fetch data with SSR. The current v3 documentation seems outdated as it suggests to use store.firebase which isn't available anymore. useFirestore() or useFirebase() cannot be used either as hooks aren't allowed outside of the rendering functions. I'm looking to use it inside getInitialProps (Next.js) What would be a decent solution to access to it from server to pre-fetch data ? For redux, a wrapper can set the store in this function's context, like this :
|
If getFirebase is removed, please recommend a way to use firebase on thunk. |
hi, is there a way to wait for firebase for the auth to be ready in hooks and functional components |
|
To address this I have been considering adding back the |
…d back getFirebase to api) - #635
* feat(auth): remove `signIn` option from createUser (new user is automatically signed in through Firebase SDK) - #513 * feat(core): new pattern for getting extended firebase instance in thunks (added back `getFirebase` to api) - #635 * fix(HOCs): switch to `UNSAFE_componentWillReceiveProps` in class based HOCs to prevent warnings with 16.9.0 - #755 * fix(HOCs): switch `withFirebase` and `withFirestore` back to pre-hooks compatible logic * fix(core): replace lodash methods such as `isArray`, `isBoolean`, `isString`, `size`, `compact` and `isFunction` with native methods in a number of places * chore(deps): update lodash to 4.17.15 * chore(docs): add docs for how to reference data from state for reselect selectors - #614 * chore(docs): update client side role assign example in roles recipes - #699 * chore(docs): add example for assigning role in cloud function - #699
The v3.0.0-beta release includes adding back I also was able to run my own thunks with the Just wanted to say a huge thanks to everyone for all of the input - you all reaching out made it known that this needed to remain part of the API 😄 . As always, if it doesn't work as you expect, please reach out - it is hopefully just about ready to go to |
@prescottprue what do you mean with |
@daiky00 Yes, the examples have been updated and the material example uses thunk. |
getFirebase
is not returning firebase instance. Gettingundefined
.The text was updated successfully, but these errors were encountered: