invertase / react-native-notifee

Moved to https://github.com/invertase/notifee
https://invertase.io/blog/open-sourcing-notifee
Other
466 stars 31 forks source link

Background notification: how to modify app data with useContext() ? #334

Closed GaylordP closed 3 years ago

GaylordP commented 3 years ago

Hello and thank you for your fabulous library, I have a paid license :) Sorry for my bad English, I'm French.

I have a "theoretical" question with Notifee and Firebase. I have already asked the question on the Firebase github without getting a clear answer.

I have instant messaging in my app. From my back-office I send the message ID, which I retrieve in HTTP from my mobile application in order to display the message in a Notifee notification. To manage data persistence inside my application I am using useContext() (no redux).

When the app is in the foreground everything is working fine :

useEffect(() => {
  const unsubscribe = messaging().onMessage(async onMessageReceived => {
    OnMessageReceived(onMessageReceived)
    // OnMessageReceived = onMessageReceived contains the ID of the message. Then I get the whole message with an HTTP request, persist it in the application with a useContext() then I display a notification
  })

  return unsubscribe
}, [])

But I don't know how to handle this when the app is in the background. The documentation says this :

To setup a background handler, call the setBackgroundMessageHandler outside of your application logic as early as possible :

import { AppRegistry } from 'react-native';
import messaging from '@react-native-firebase/messaging';
import App from './App';

// Register background handler
messaging().setBackgroundMessageHandler(async remoteMessage => {
  console.log('Message handled in the background!', remoteMessage);
});

AppRegistry.registerComponent('app', () => App)

Since background notifications must be managed outside of the app, how do you handle new messages?

I can receive the message ID, make an HTTP request to retrieve the message, but I cannot manipulate the application data with useContext () to add the message. But this step is necessary (because if I press the notification, the app should open with the new message)

I hope I have been clear but I am not sure in English thank you in advance

mikehardy commented 3 years ago

I think you have been clear, and your English is great. My French is non-existent :sweat_smile:

Can you link to the question in react-native-firebase as well? Just out of curiosity - I work on both repos.

Even though you need to register the background handler before registerComponent, the handler itself may be inside the app in my experience. I believe the handler itself can be a reference to some code somewhere else, however I do not use hooks or the useContext hook specifically in my app...so I am not sure.

I can say this: I'm concerned about whether you will be successful with this solution design.

If I understand correctly your flow is:

1- send an FCM with data-only JSON ? 2- application receives the JSON and makes an external HTTP request ? 3 - application processes result of HTTP request and generates visible notification?

If I have that right, these 2 specific issues may affect you:

For 1, iOS does not guarantee delivery of data-only JSON via FCM. There are many cases where it is the opposite in fact: data-only JSON will never be delivered it the app is force quit / swiped away, and it will never be delivered if the user has toggled on low power mode or turned off background refresh for the app.

For 2, Android at least (and I think iOS as well?) have very tight requirements on how long your app has to work when a background message is received. By contrast, you are not in control of external HTTP calls' duration. Depending on network environment of the device they may fail to complete or take too long, and Android at least will actually kill your app in these situations if I am not mistaken.

If at all possible I would figure out how to get your whole message inside the JSON payload in the FCM, and at least for iOS I would use a notification block / mixed payload plus iOS extension handlers so you may style the notification, to make sure you have reliable FCM delivery

helenaford commented 3 years ago

@GaylordP did you find a solution? I'd probably suggest using AsyncStorage out of the box if you don't want to use redux. Please re-open if it's still unclear.