react-native-firebase
react-native-firebase copied to clipboard
🔥 messaging().onNotificationOpenedApp is never triggered, messaging().getInitialNotification() is triggered but remoteMessage is always null
Issue
I successfully registered a background handler with setBackgroundMessageHandler
and everything works fine. Now I'm trying to handle notification tap when the app is in background/quit and I'm using onNotificationOpenedApp
/getInitialNotification
respectively. The problem I'm facing is that the first method is never triggered while the second is triggered but remoteMessage
parameter is always null
. I've also tried to generate a release build but the result is the same.
index.js
import React from 'react';
import {AppRegistry} from 'react-native';
import {name as appName} from './app.json';
import messaging from '@react-native-firebase/messaging';
import App from './src/App';
messaging().setBackgroundMessageHandler(async remoteMessage => {
// storing the message with redux
});
function HeadlessCheck({isHeadless}) {
return isHeadless ? null : <App />;
}
AppRegistry.registerComponent(appName, () => HeadlessCheck);
App.js
// other imports
import messaging from '@react-native-firebase/messaging';
import {store, persistor} from './Store';
export default function App() {
useEffect(() => {
(async () => await messaging().registerDeviceForRemoteMessages())();
const unsubscribe = messaging().onMessage(async remoteMessage => {
store.dispatch(storeNews(remoteMessage));
});
messaging().onNotificationOpenedApp(remoteMessage => {
// The below code gets never executed
Alert.alert('here');
console.log(
'Notification caused app to open from background state:',
remoteMessage,
);
});
messaging()
.getInitialNotification()
.then(remoteMessage => {
console.log(remoteMessage); // always prints null
if (remoteMessage) {
// Never reached
Alert.alert('here');
console.log(
'Notification caused app to open from quit state:',
remoteMessage,
);
}
});
return unsubscribe;
}, []);
return (
<>
<StatusBar barStyle="dark-content" />
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<RootNavigator />
</PersistGate>
</Provider>
</>
);
}
Project Files
Javascript
Click To Expand
package.json
:
{
...
"@react-native-firebase/app": "^6.4.0",
"@react-native-firebase/messaging": "^6.4.0",
...
}
react-native info:
#### `firebase.json` for react-native-firebase v6:
```json
# N/A
iOS
Click To Expand
ios/Podfile
:
- [ ] I'm not using Pods
- [ ] I'm using Pods and my Podfile looks like:
# N/A
AppDelegate.m
:
// N/A
Android
Click To Expand
Have you converted to AndroidX?
- [ ] my application is an AndroidX application?
- [x] I am using
android/gradle.settings
jetifier=true
for Android compatibility? - [ ] I am using the NPM package
jetifier
for react-native compatibility?
android/build.gradle
:
// N/A
android/app/build.gradle
:
// N/A
android/settings.gradle
:
// N/A
MainApplication.java
:
// N/A
AndroidManifest.xml
:
<!-- N/A -->
Environment
Click To Expand
react-native info
output:
System:
OS: Windows 10 10.0.18363
CPU: (8) x64 Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz
Memory: 6.90 GB / 15.73 GB
Binaries:
Node: 10.15.3 - C:\Program Files\nodejs\node.EXE
Yarn: 1.9.4 - C:\Users\user\AppData\Roaming\npm\yarn.CMD
npm: 6.14.1 - C:\Program Files\nodejs\npm.CMD
SDKs:
Android SDK:
API Levels: 21, 22, 23, 24, 25, 26, 27, 28
Build Tools: 23.0.1, 25.0.0, 26.0.1, 26.0.2, 26.0.3, 27.0.3, 28.0.2, 28.0.3
System Images: Google APIs Intel x86 Atom, android-27
Intel x86 Atom
IDEs:
Android Studio: Version 3.5.0.0 AI-191.8026.42.35.6010548
npmPackages:
react: 16.9.0 => 16.9.0
react-native: 0.61.5 => 0.61.5
-
Platform that you're experiencing the issue on:
- [ ] iOS
- [x] Android
- [ ] iOS but have not tested behavior on Android
- [x] Android but have not tested behavior on iOS
- [ ] Both
-
react-native-firebase
version you're using that has this issue:-
6.4.0
-
-
Firebase
module(s) you're using that has the issue:-
react-native-firebase/messaging
-
-
Are you using
TypeScript
?-
N
-
I tried to run the code on both a physical Android device and on an Android emulator and I got the same behaviour.
Physical device specs:
Model code: SM-G975F
Android version: 10
Emulator specs:
Name: Nexus_5X_API_27_x86
Device: Nexus 5X (Google)
Path: C:\Users\user\.android\avd\Nexus_5X_API_27_x86.avd
Based on: Android API 27 Tag/ABI: google_apis/x86
I appreciate any help. Many thanks in advance.
- 👉 Check out
React Native Firebase
andInvertase
on Twitter for updates on the library.
Almost the same problems here. In IOS the onNotificationOpenedApp
works on both state, background and quit. But on Android never work.
And getInitialNotification
is always called if App is in Quit state, but I think that it's OK, because this method isn't a listener, so always the component is mounted it will be called. But the remoteMessage
is always null, here are the problem :(
Using 6.4.0
How do you implemented the listener for notification interaction before the introduction this methods on version 6.4.0 ?
Before this version I was working with v5.5.5, there I was able to handle these behaviours throught notifications
module. In particular, .notifications().getInitialNotification
allowed me to manage the cold start and .notifications().onNotificationOpened
the tap on the notification when the app was in background
Before this version I was working with v5.5.5, there I was able to handle these behaviours throught
notifications
module. In particular,.notifications().getInitialNotification
allowed me to manage the cold start and.notifications().onNotificationOpened
the tap on the notification when the app was in background
I'm thinking that I will have to go back do V5, two days working on that an nothing for now.
I find what cause my problem. I have in my app a config for native Splash Screen, implementation necessary to use the react-native-splash-screen package.
I added a news file called SplashActivity.java
:
public class SplashActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
try {
super.onCreate(savedInstanceState);
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish();
}
catch(Exception e) {
System.out.println(e.getMessage());
}
}
}
I mande the SplashActivity my main Activity , in AndroidManifest.xml
:
<activity
android:name=".SplashActivity"
android:theme="@style/SplashTheme"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:windowSoftInputMode="adjustResize"
android:exported="true" />
Then changes some logic on my MainActivity.java
, that looks like :
import android.os.Bundle;
import org.devio.rn.splashscreen.SplashScreen;
public class MainActivity extends ReactActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
SplashScreen.show(this);
super.onCreate(savedInstanceState);
}
}
So the events are not passed correctly, more information about see this comments on issue #1272
- About problem on this comment: https://github.com/invertase/react-native-firebase/issues/1272#issuecomment-417484397
My solution to this problem is pretty implementation specific, but you never know what might help.
My issue was that I had a splash activity which was the actual launcher activity. To get the callbacks to fire in App.js I had to: Add "singleTop" to the activity tag for SplashActivity.java in AndroidManifest.xml Use "this.getIntent();" within the onCreate method of SplashActivity.java to intercept the intent from the firebase notification open event Use .getExtras() to take the bundle from the intercepted intent and attach it to a new intent forwarded to .MainActivity As soon as .MainActivity had access to the intent all of the callbacks began firing on the correct events.
- Implementation to solve the problem on this comment: https://github.com/invertase/react-native-firebase/issues/1272#issuecomment-421424104
So I added this logic on may SplashActivity:
Bundle extras = getIntent().getExtras();
if (extras != null) {
intent.putExtras(extras);
}
Now looks like:
public class SplashActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
try {
// Block of code to try
super.onCreate(savedInstanceState);
Intent intent = new Intent(this, MainActivity.class);
// Pass along FCM messages/notifications etc.
Bundle extras = getIntent().getExtras();
if (extras != null) {
intent.putExtras(extras);
}
startActivity(intent);
finish();
}
catch(Exception e) {
// Block of code to handle errors
System.out.println(e.getMessage());
}
}
}
Now I can get getInitialNotification()
return and onNotificationOpenedApp()
events.
On Android if the app is in background or quit state it's always calling getInitialNotification()
, this is probably because my logic from Splash Screen. But for me it's OK for now, I would do exactly the same thing on both
You made my day. Same problem, your solution worked brilliantly. I think getInitialNotification()
being always called is the wanted behaviour.
We are using https://github.com/zo0r/react-native-push-notification to emit local notifications (since its not part of this library) and expected that onNotificationOpenedApp
would be able to handle these.
To make this work for iOS we simply added 'gcm.message_id': '123'
to the userInfo
and thus passed the necessary if statements of the native code.
On Android this is not as easy.. react-native-push-notification
emits an intent similar to this:
{
notification: {
message: "My Notification Message",
message_id: "123"
}
}
But ReactNativeFirebaseMessagingModule
expects message_id
to be a key at the root-level of the Extras in the Intent.
Maybe this will help someone who also trys to integrate with react-native-push-notification
.
@mirco312312 the problem is, if we don't check for a message_id
then we'll be overriding everything that comes through on the device (even if it's nothing to do with FCM, like an APNs message, or one from react-native-push-notification
).
Yap makes sense! Just wanted to note here, maybe somebody else wants to handle local notifications as well as firebase.
If there is an issue I think its on react-native-push-notification
side since the local notifications payloads differ on Android and iOS.
@LucasGarcez thanks worked form me i had SplashActivity so your same code worked for me too thank you bro... if any one has SplashActivity in there app plz try out this way.. @LucasGarcez
Awesome, thanks @LucasGarcez ! This worked for me.
I think a lot of people use react-native-splash-screen
, so this might be worth a note in the documentation for getInitialNotification
and onNotificationOpenedApp
?
@jasperkuperus your can go ahead and submit a PR using the edit button at the to of the doc pages. If you do, though, you should take note of this: https://github.com/invertase/react-native-firebase/issues/3894#issuecomment-655006173
@andersonaddo Thanks for pointing that out! I'll givereact-native-bootsplash
a shot soon. If indeed react-native-bootsplash
is a better alternative nowadays, I will not edit the documentation to reflect the suggestion in this topic.
@jasperkuperus I think regardless it couldn't hurt for the docs to talk about this a bit to prevent people from using react-native-splash-screen
@andersonaddo Alright, there we go: https://github.com/invertase/react-native-firebase/pull/3966
Thank you so much @LucasGarcez Sir, was stuck on it for 2 days, thanks a lot again
I don't use react-native-splash-screen
or react-native-bootsplash
and the following methods onNotificationOpenedApp
and getInitialNotification
are never triggered, but onMessage
and setBackgroundMessageHandler
are fine. I am using react-native-notifications
to show the notifications and the issue I am having is to show the notification when the app is closed.
@axeljeremy7 you should try react-native-push-notification
react-native-notifications
is not good and not well maintain
I had the same problem on react-native 0.60.4
. Upgrading to the latest react-native version 0.63.2
fixed the problem.
edit:
After the react-native upgrade onNotificationOpenedApp
is working as intended. getInitialNotification()
always return null.
This behavior is the same in a newly created RN (0.63.2) app. I will create a new issue for this.
I don't use react-native-splash-screen , any help?
All I can is I strongly recommend using react-native-boot-splash in order to do a boot screen If you have something else going on where on android you pass control between Activities you need to pass the Intent Extras as well
I'm having the same issue with react-native-bootsplash, I opened an issue there, maybe someone can help?
@aprilmintacpineda
@Override protected void onCreate(Bundle savedInstanceState) {
try {
super.onCreate(savedInstanceState);
Intent intent = new Intent(this, MainActivity.class);
// Pass along FCM messages/notifications etc.
Bundle extras = getIntent().getExtras();
if (extras != null) {
intent.putExtras(extras);
}
startActivity(intent);
finish();
}
catch(Exception e) {
// Block of code to handle errors
System.out.println(e.getMessage());
}
}
}
This helped me to get data form notification
but i will recommended you to try react-native-push-notification
for more fetchers
I was able to reproduce it from scratch without adding react-native-bootstrap, can someone please take a look? https://github.com/aprilmintacpineda/repro-rn-firebase-194
messaging().getInitialNotification
works fine.
EDIT:
All good now, my mistake, onNotificationOpened
is only called when the app was on the background. For killed state, I need to use getInitialNotification
instead.
Same here. I'm not using any splash lib and onNotificationOpened
not working on Android
Same here. I'm not using any splash lib and
onNotificationOpened
not working on Android
same
Same here. I'm not using any splash lib and
onNotificationOpened
not working on Android
Same here!
but if I try to send push from firebase console, it works... but not the ones coming from my app backend
So...what's different in the JSON between the two? :thinking: The firebase console sends a very simple JSON with a notification block. No idea about your backend code. But you can easily just guess at what the firebase console sends and test it via the FCM REST API, and compare with yours, then tweak yours until get delivery.
@mikehardy thanks, it was that in the backend they were sending the push notification with 'send' and not with 'sendToDevice'.
try { // Block of code to try super.onCreate(savedInstanceState); Intent intent = new Intent(this, MainActivity.class); // Pass along FCM messages/notifications etc. Bundle extras = getIntent().getExtras(); if (extras != null) { intent.putExtras(extras); } startActivity(intent); finish(); } catch(Exception e) { // Block of code to handle errors System.out.println(e.getMessage()); }
What if I don't have a SplashScreen.java file but I'm still using react-native-splash-screen library.