Skip to content

🔥 onMessage not triggered when using onNotification - V6.0 #3236

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

Closed
2 of 10 tasks
ammarRajabA opened this issue Feb 24, 2020 · 8 comments · Fixed by #3339
Closed
2 of 10 tasks

🔥 onMessage not triggered when using onNotification - V6.0 #3236

ammarRajabA opened this issue Feb 24, 2020 · 8 comments · Fixed by #3339

Comments

@ammarRajabA
Copy link

ammarRajabA commented Feb 24, 2020

Issue

Describe your issue here

My goal is to receive Firebase Cloud Messages on iOS and have a push notification, and also cache the FCM locally in order to view it later.

  • First attempt is to trigger a local notification (using zo0r notifications library) after receiving the FCM. I have received the FCM and cached and was able to show a local notification but this method doesn't allow me to trigger this local notification when app is in background or killed.

  • Second attempt is to send a push notification (after specifying the "notification" field in Firebase admin send message function) and add a Data field to the notification. Problem was the data field is not available when the app is in background or killed. I got only the title and body. onMessage is not called as well in this method, only onNotification is triggered.

  • Third attempt is to send two different FCM messages, one with data only and the other with notification. So the push notification is received and onNotification is called but onMessage is never triggered.

So in summary, onMessage is not called when onNotification is called although two different messages are sent (one with notification field and other with data only field).

Below is the backend code that sends the notification:

module.exports=async (topic, title, body,payload=null)=>{
	const data=payload?JSON.stringify(payload):''
	try{
		const _id=payload?uuidv1():false;

		const message={
			"android":{
		      "priority":"high"
		    },
		    "apns":{
		      "headers":{
		        "apns-priority":"10"
		      }
		    },
			data:{
				title,
				body,
				data,
			},topic
		}

		if (_id) message['data']['_id']=_id;

		const msgRes=await admin.messaging().send(message);

		const notification={
			notification:{
				title,
				body
			},
            apns: {
                payload: {
                    aps: {
                        sound: 'default',
                        "content-available": 1
                    },
                }
            },topic:topic+'_ios'
		}

		if (_id) {
			notification['data']={},
			notification['data']['_id']=_id;
		}

		const notifRes=await admin.messaging().send(notification);
		console.log('Message sent',title,_id);
	}catch(err){
		console.log(err)
	}
}

And below is the code in the React-Native app:

export const configureNotifications = async () => {
  if (!messaging().isRegisteredForRemoteNotifications) {
    await messaging().registerForRemoteNotifications();
  }
  const permissionGranted = await messaging().requestPermission();

  messaging().onMessage(async remoteMessage => {
    if (remoteMessage.from.indexOf('_ios')>=0) return; // don't handle Push Notification at all!! leave it to the OS
    const {title, body, data} = remoteMessage.data;
    if (!isIOS){
      let notif = {
        title: remoteMessage.data.title,
        message: remoteMessage.data.body,
        data: remoteMessage.data.data,
        body: remoteMessage.data.body,
        priority: 'high',
        playSound: true,
        soundName: 'default',
      };
      //if (isIOS && data) {
      //  notif['userInfo'] = JSON.parse(remoteMessage.data.data);
      //  notif['userInfo']['title'] = remoteMessage.data.title;
      //}
      notif['actions'] = data ? '["Open Link"]' : '';
      PushNotification.localNotification(notif);
    }

    const _id=remoteMessage.data._id;
    if (data) {
      remoteMessage.data.data = JSON.parse(remoteMessage.data.data);
      cacheNotification({title, body, type: 'info', _id}, remoteMessage.data);
    } else {
      cacheNotification({title, body, type: 'info', _id});
    }
  });

  PushNotification.popInitialNotification(notification => {
    const {title, body} = notification;
    if (notification.action) {
      openExtURL(notification.data.link);
    } else if (notification.userInteraction) {
      if (notification.data) {
        notification.data = JSON.parse(notification.data);
        displayPopup(<PopupPublication content={notification} />);
      }
    }
    if (PushNotificationIOS) {
      notification.finish(PushNotificationIOS.FetchResult.NoData);
    }
  });

  PushNotification.configure({
    requestPermissions: true,
    popInitialNotification: true,
    onNotification: notification => {
      if (notification.action) {
        openExtURL(notification.data.link);
      } else if (notification.userInteraction || isIOS) {
        if (notification.data) {
          //if (isIOS) {
          //  notification.title = notification.data.title;
          //  notification.body = notification.message;
          //}
          if (isIOS){
            const notifications=store.getState().notifications.notifications;
            const notificationData=notifications.find(item=>item._id===notification.data._id);
            if (notificationData) displayPopup(<PopupPublication content={notificationData} />);
          }else{
            displayPopup(<PopupPublication content={notification} />);
          }
        }
      }
      if (PushNotificationIOS) {
        notification.finish(PushNotificationIOS.FetchResult.NoData);
      }
    },
  });
};

Project Files

Javascript

Click To Expand

package.json:

{
  "name": "bitmex_trading",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "react-native start",
    "test": "jest",
    "lint": "eslint ."
  },
  "dependencies": {
    "@egendata/react-native-simple-crypto": "^1.0.1",
    "@ptomasroos/react-native-multi-slider": "^1.0.0",
    "@react-native-community/async-storage": "1.2.4",
    "@react-native-community/netinfo": "^4.2.2",
    "@react-native-community/push-notification-ios": "^1.0.2",
    "@react-native-community/slider": "^2.0.0",
    "@react-native-firebase/app": "^6.0.2",
    "@react-native-firebase/crashlytics": "6.0.2",
    "@react-native-firebase/messaging": "^6.0.2",
    "axios": "^0.19.0",
    "bit_mex_api": "^1.2.1",
    "bollinger-bands": "^3.0.1",
    "html-entities": "^1.2.1",
    "ichimoku": "^1.0.4",
    "macd": "^1.0.2",
    "mathjs": "^6.2.2",
    "moment": "^2.24.0",
    "query-string": "^6.8.3",
    "react": "16.8.6",
    "react-native": "0.60.5",
    "react-native-animatable": "^1.3.2",
    "react-native-autogrow-textinput": "^5.3.0",
    "react-native-background-fetch": "^2.7.1",
    "react-native-camera": "^3.7.1",
    "react-native-date-ranges": "github:ammarrajaba/react-native-date-ranges",
    "react-native-echarts-wrapper": "github:ammarrajaba/react-native-echarts-wrapper",
    "react-native-elements": "^1.2.1",
    "react-native-event-listeners": "^1.0.3",
    "react-native-exception-handler": "^2.10.8",
    "react-native-gesture-handler": "^1.4.1",
    "react-native-in-app-message": "github:ammarrajaba/react-native-in-app-message",
    "react-native-keyboard-input": "^6.0.0",
    "react-native-keyboard-tracking-view": "^5.6.1",
    "react-native-keychain": "^4.0.1",
    "react-native-linear-gradient": "^2.5.6",
    "react-native-modal": "^11.4.0",
    "react-native-navigation-bar-color": "^0.1.0",
    "react-native-numeric-input": "^1.8.3",
    "react-native-paper": "^2.16.0",
    "react-native-push-notification": "^3.1.9",
    "react-native-qrcode-svg": "^5.2.0",
    "react-native-reanimated": "^1.3.0",
    "react-native-share": "^2.0.0",
    "react-native-splash-screen": "^3.2.0",
    "react-native-svg": "^9.13.3",
    "react-native-text-ticker": "^0.19.0",
    "react-native-vector-icons": "^6.6.0",
    "react-native-waveview": "github:ammarrajaba/react-native-waveview",
    "react-native-webview": "^7.4.1",
    "react-navigation": "^4.0.7",
    "react-navigation-material-bottom-tabs": "^2.1.2",
    "react-navigation-stack": "^1.8.1",
    "react-navigation-tabs": "^2.5.5",
    "react-navigation-transitions": "^1.0.12",
    "react-redux": "^7.1.1",
    "redux": "^4.0.4",
    "redux-thunk": "^2.3.0"
  },
  "devDependencies": {
    "@babel/core": "^7.6.0",
    "@babel/runtime": "^7.6.0",
    "@react-native-community/eslint-config": "^0.0.5",
    "babel-jest": "^24.9.0",
    "cavy": "^3.2.0",
    "enzyme": "^3.10.0",
    "enzyme-adapter-react-16": "^1.14.0",
    "eslint": "^6.4.0",
    "hermes-engine": "^0.3.0",
    "jest": "^24.9.0",
    "jsdom": "^15.1.1",
    "metro-react-native-babel-preset": "^0.56.0",
    "mock-socket": "^9.0.2",
    "react-dom": "^16.8.6",
    "react-native-mock-render": "^0.1.5",
    "react-native-testing-library": "^1.11.1",
    "react-test-renderer": "^16.8.6",
    "redux-mock-store": "^1.5.3",
    "sinon": "^7.5.0"
  },
  "jest": {
    "preset": "react-native",
    "setupFilesAfterEnv": [
      "<rootDir>/src/setupTests.js"
    ],
    "testURL": "https://example.com"
  },
  "rnpm": {
    "assets": [
      "./assets/fonts/"
    ]
  }
}

firebase.json for react-native-firebase v6:

# N/A

iOS

Click To Expand

ios/Podfile:

  • I'm not using Pods
  • I'm using Pods and my Podfile looks like:
platform :ios, '9.0'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'

target 'bitmex_trading' do
  # Pods for bitmex_trading
  pod 'React', :path => '../node_modules/react-native/'
  pod 'React-Core', :path => '../node_modules/react-native/React'
  pod 'React-DevSupport', :path => '../node_modules/react-native/React'
  pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS'
  pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation'
  pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob'
  pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image'
  pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS'
  pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network'
  pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings'
  pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text'
  pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration'
  pod 'React-RCTWebSocket', :path => '../node_modules/react-native/Libraries/WebSocket'

  pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact'
  pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi'
  pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor'
  pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector'
  pod 'yoga', :path => '../node_modules/react-native/ReactCommon/yoga'

  pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
  pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
  pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'



  pod 'RNVectorIcons', :path => '../node_modules/react-native-vector-icons'



  pod 'react-native-webview', :path => '../node_modules/react-native-webview'




  pod 'RNGestureHandler', :path => '../node_modules/react-native-gesture-handler'


  pod 'ReactNativeKeyboardInput', :path => '../node_modules/react-native-keyboard-input'

  pod 'ReactNativeKeyboardTrackingView', :path => '../node_modules/react-native-keyboard-tracking-view'

  target 'bitmex_tradingTests' do
    inherit! :search_paths
    # Pods for testing
  end

  use_native_modules!
end

target 'bitmex_trading-tvOS' do
  # Pods for bitmex_trading-tvOS

  target 'bitmex_trading-tvOSTests' do
    inherit! :search_paths
    # Pods for testing
  end

end

AppDelegate.m:

/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */
@import Firebase;

#import "RNSplashScreen.h"
#import "AppDelegate.h"
#import <RNCPushNotificationIOS.h>

#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>

@implementation AppDelegate
  
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  {
    [FIRApp configure];
    
    RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
    RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
                                                     moduleName:@"bitmex_trading"
                                              initialProperties:nil];
    
    rootView.backgroundColor = [[UIColor alloc] initWithRed:0.133333f green:0.133333f blue:0.1725490196f alpha:1];
    
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    UIViewController *rootViewController = [UIViewController new];
    rootViewController.view = rootView;
    self.window.rootViewController = rootViewController;
    [self.window makeKeyAndVisible];
    
    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    center.delegate = self;
    
    [RNSplashScreen showSplash:@"LaunchScreen" inRootView:rootView];
    
    return YES;
  }
  
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
  {
    completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge);
  }
  
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
  {
#if DEBUG
    return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
    return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
  }
  
  // Required to register for notifications
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
  {
    [RNCPushNotificationIOS didRegisterUserNotificationSettings:notificationSettings];
  }
  // Required for the register event.
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
  {
    [RNCPushNotificationIOS didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
  }
  // Required for the notification event. You must call the completion handler after handling the remote notification.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
  {
    [RNCPushNotificationIOS didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
  }
  // Required for the registrationError event.
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
  {
    [RNCPushNotificationIOS didFailToRegisterForRemoteNotificationsWithError:error];
  }
  // Required for the localNotification event.
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
  {
    [RNCPushNotificationIOS didReceiveLocalNotification:notification];
  }
  
  @end


Android

Click To Expand

Have you converted to AndroidX?

  • my application is an AndroidX application?
  • 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: macOS 10.14.1
    CPU: (8) x64 Intel(R) Core(TM) i5-8300H CPU @ 2.30GHz
    Memory: 6.48 GB / 16.00 GB
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 10.16.3 - /usr/local/bin/node
    npm: 6.9.0 - /usr/local/bin/npm
  SDKs:
    iOS SDK:
      Platforms: iOS 12.1, macOS 10.14, tvOS 12.1, watchOS 5.1
    Android SDK:
      API Levels: 23, 28, 29
      Build Tools: 28.0.3, 29.0.2
  IDEs:
    Android Studio: 3.5 AI-191.8026.42.35.5900203
    Xcode: 10.1/10B61 - /usr/bin/xcodebuild
  npmPackages:
    react: 16.8.6 => 16.8.6 
    react-native: 0.60.5 => 0.60.5 
  npmGlobalPackages:
    react-native-cli: 2.0.1
  • Platform that you're experiencing the issue on:
    • iOS
    • Android
    • iOS but have not tested behavior on Android
    • Android but have not tested behavior on iOS
    • Both
  • react-native-firebase version you're using that has this issue:
    • 6.0.2
  • Firebase module(s) you're using that has the issue:
    • Messaging, App
  • Are you using TypeScript?
    • N


Think react-native-firebase is great? Please consider supporting all of the project maintainers and contributors by donating via our Open Collective where all contributors can submit expenses. [Learn More]

@atomdmac
Copy link

atomdmac commented Feb 24, 2020

I have a very similar setup and am seeing the exact same thing (i.e. double notifications sent thru zo0r's lib, onMessage not firing.)

It may be worth noting that I've only tried sending notifications via the Firebase Cloud Messaging dashboard. I'm not sure if triggering them that way has an special properties but the quickstart guide seems to indicate that they're different than generic "messaging" that might not generate a visible notification.

@atomdmac
Copy link

FWIW, I just tried removing zo0r/react-native-push-notification from my project to see if it would allow onMessage to fire but it still doesn't seem to work.

@Ehesp
Copy link
Member

Ehesp commented Mar 17, 2020

This will be handled in the PR linked above 👍

@Ehesp
Copy link
Member

Ehesp commented Mar 23, 2020

Hey all 👋 There's a draft PR available which fixes this issue and others, please check it out: #3339

We'll be doing a RC release once a few more things are implemented.

@ahmad6242
Copy link

Hello Guys, Is there any update available on this issue ?

@mikehardy
Copy link
Collaborator

@ahmad6242 no, it was closed half a year ago with a merged PR. When configured correctly, and when handlers are hooked correctly, and device power management and app state and permissions etc allow, all react-native-firebase messaging APIs are functioning correctly as far as we know. Which is to say it's not easy to get right but it is working as well as it seems possible to make it?

@ahmad6242
Copy link

@mikehardy , Good to hear this.
Can you please brief it a bit so i can implement it in my application.
I have my android App working properly.
But on IOS the ONMessaging event handlers are not called when the app is in the foreground state . What should i do next to get it working.
Please Help!

@mikehardy
Copy link
Collaborator

@ahmad6242 you don't specify your exact json payload so I'm not sure. In general I try to stay out of helping users with specific messaging problems because it's so specific to app setup and the JSON sent. I want to be very clear that my onMessage handler is called in my app when I send data-only payloads and the app is in foreground. This module works, but the integration and JSON you send must be just right. What is "just right"? You have to read the docs and test and test and test

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants