0

I'm currently build a React Native application using Redux the state management and Firebase Cloud Messaging for my real time communication.

To use FCM in the background on Android you are required to create file called bgMessaging.js.

// @flow
import firebase from 'react-native-firebase';
// Optional flow type
import type { RemoteMessage } from 'react-native-firebase';

export default async (message: RemoteMessage) => {
    // handle your message

    return Promise.resolve();
}

My problem is that I need to dispatch an action here. The only solution I found for this was to import my store and call store.dispatch(). I've been told this is an anti-pattern and considered bad practice. What else could I do that is not an anti-pattern?

Edit: Mark Erikson himself was so kind and gave his opinion on this topic. Thanks Mark!

J. Hesters
  • 13,117
  • 31
  • 133
  • 249
  • Example of redux usage outside of React components are sparse, because they are usually advanced use cases (like your own). I think it would be an anti-pattern in a react component but not outside in a pure JS code. Do you have sources about it being a bad practice? – Eric Burel Sep 24 '18 at 14:19
  • 1
    afaik the anti-pattern is making the redux store a singleton, and that is mainly because it makes writing tests more complicated as it's harder to isolate a store instance for a particular test. – lecstor Sep 26 '18 at 02:31

2 Answers2

2

I've also come into the same scenario when writing my application. My approach to my React Native App was to create React Components, but deal with a lot of my data fetching/handling outside of React Components - because I didn't know whether I'd be using React all of the time, but wanted to create re-usable modules for my other Type/JavaScript projects. For example I'd created a few helper files which dealt with various APIs, but when I integrated Redux into my project - I had the same issue. How do I dispatch without re-adding in your store (as I can see this can be considered Anti-Pattern).

Reading into a few articles, there's no real place to suggest that this approach is 'Anti Pattern'. A lot of the time, stores are imported within the React Context (which is doesn't need to be) - this is Anti Pattern. In your use case, I don't really see how that can be Anti Pattern, I certainly came to this conclusion when I was doing the same thing. In my view 'Common' parts of the app should be used by many other parts of the application.

JRK
  • 3,686
  • 1
  • 13
  • 19
0

What I'm seeing is that you need to provide a function which has a single arg, typed as RemoteMessage which returns a promise, and you need to provide that function to registerHeadlessTask (wrapped in another function for some reason..)

So what if your bgMessaging file looked like this..

// @flow
import firebase from 'react-native-firebase';
// Optional flow type
import type { RemoteMessage } from 'react-native-firebase';

export default store => {
  return async (message: RemoteMessage) => {
    // handle your message
    store.dispatch();
    return Promise.resolve();
  }
}

and in your index you did..

import bgMessaging from './src/bgMessaging';

const store = redux.createStore();

const bgMessagingFn = bgMessaging(store);

// Current main application
AppRegistry.registerComponent('ReactNativeFirebaseDemo', () => bootstrap);
// New task registration
AppRegistry.registerHeadlessTask('RNFirebaseBackgroundMessage', () => bgMessagingFn);
lecstor
  • 5,619
  • 21
  • 27