react-native-firebase icon indicating copy to clipboard operation
react-native-firebase copied to clipboard

🔥 messaging().onNotificationOpenedApp is never triggered, messaging().getInitialNotification() is triggered but remoteMessage is always null

Open StefanoMartella opened this issue 4 years ago • 46 comments

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.


StefanoMartella avatar Apr 14 '20 20:04 StefanoMartella

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 ?

LucasGarcez avatar Apr 16 '20 11:04 LucasGarcez

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

StefanoMartella avatar Apr 16 '20 12:04 StefanoMartella

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.

LucasGarcez avatar Apr 16 '20 12:04 LucasGarcez

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

LucasGarcez avatar Apr 17 '20 01:04 LucasGarcez

You made my day. Same problem, your solution worked brilliantly. I think getInitialNotification() being always called is the wanted behaviour.

StefanoMartella avatar Apr 17 '20 07:04 StefanoMartella

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.

mircoservices avatar Apr 20 '20 07:04 mircoservices

@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).

Ehesp avatar Apr 20 '20 08:04 Ehesp

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.

mircoservices avatar Apr 20 '20 08:04 mircoservices

@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

girish54321 avatar May 01 '20 06:05 girish54321

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 avatar Jul 17 '20 11:07 jasperkuperus

@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 avatar Jul 17 '20 13:07 andersonaddo

@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 avatar Jul 17 '20 13:07 jasperkuperus

@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 avatar Jul 17 '20 13:07 andersonaddo

@andersonaddo Alright, there we go: https://github.com/invertase/react-native-firebase/pull/3966

jasperkuperus avatar Jul 17 '20 14:07 jasperkuperus

Thank you so much @LucasGarcez Sir, was stuck on it for 2 days, thanks a lot again

kmanishk1 avatar Sep 18 '20 06:09 kmanishk1

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 avatar Sep 24 '20 20:09 axeljeremy7

@axeljeremy7 you should try react-native-push-notification react-native-notifications is not good and not well maintain

girish54321 avatar Sep 25 '20 04:09 girish54321

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.

superdopey avatar Sep 29 '20 14:09 superdopey

I don't use react-native-splash-screen , any help?

miketrinh1995 avatar Nov 11 '20 01:11 miketrinh1995

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

mikehardy avatar Nov 11 '20 01:11 mikehardy

I'm having the same issue with react-native-bootsplash, I opened an issue there, maybe someone can help?

aprilmintacpineda avatar Dec 17 '20 01:12 aprilmintacpineda

@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

girish54321 avatar Dec 17 '20 04:12 girish54321

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.

aprilmintacpineda avatar Dec 17 '20 07:12 aprilmintacpineda

Same here. I'm not using any splash lib and onNotificationOpened not working on Android

ithustle avatar Dec 27 '20 13:12 ithustle

Same here. I'm not using any splash lib and onNotificationOpened not working on Android

same

victorlpgazolli avatar Jan 19 '21 21:01 victorlpgazolli

Same here. I'm not using any splash lib and onNotificationOpened not working on Android

Same here!

marquina-abreu avatar Apr 05 '21 19:04 marquina-abreu

but if I try to send push from firebase console, it works... but not the ones coming from my app backend

marquina-abreu avatar Apr 05 '21 19:04 marquina-abreu

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 avatar Apr 05 '21 20:04 mikehardy

@mikehardy thanks, it was that in the backend they were sending the push notification with 'send' and not with 'sendToDevice'.

marquina-abreu avatar Apr 07 '21 15:04 marquina-abreu

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.

vijya76 avatar Sep 15 '21 06:09 vijya76