React Native: Show Push Notification(FCM) in Foreground mode on your iOS App
This is a short article about the recent issue which I came across. One of my friends recently encountered an issue integrating Firebase Cloud Messaging(FCM) in an iOS app developed using React-Native codebase.
To provide a short context, when you develop an app using React-Native, you would be having two folders one for Android and another for iOS. All the javascript code that you write using React-Native framework is exported into a main.jsbundle which is then compiled by Android and iOS separately.
Native iOS experience missing on Foreground Push Notification
Coming back to the issue, The notification is received and the native notification popup is shown in both background as well as in terminated mode. The core problem is that the notification is received in the callback provided by firebase, but the native notification which drops from the top of the screen isn't showing up.
Adding more context on the npm package used for Firebase Cloud Messaging is @react-native-firebase/messaging. Below is the callback provided by firebase, which gets triggered after a notification is received, when the app is in the foreground.
// App.js
import messaging from '@react-native-firebase/messaging';
// Foreground Notification Callback when the notification is received
messaging().onMessage((notification: any) => {
console.log("Notification received in foreground")
}
// Background Notification Callback when the notification is clicked
messaging().onNotificationOpenedApp((notification: any) => {
console.log('onNotificationOpened', notification);
}
The callback is triggered whenever the notification is received in the foreground and the log "Notification received in foreground" is printed in the console. But the native experience of notification dropping at the top of the screen is still missing.
Conformance to UNUserNotificationCenterDelegate
After checking out, we found out that just like native iOS Push Notification integration, we need to make AppDelegate conform to the UNUserNotificationCenterDelegate, add the willPresentNotification delegate. After confirming to the delegate we need to redirect the notification call to the RNCPushNotificationIOS:didReceiveRemoteNotification method, so that this would trigger the above onNotificationOpenedApp.
Here's the code for AppDelegate.h conformance
// AppDelegate.h
// In AppDelegate.h file conform to the UNUserNotificationCenterDelegate
@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate,UNUserNotificationCenterDelegate>
Next we need to set the UNUserNotificationCenterDelegate, implement it and then redirect it to RNCPushNotificationIOS:didReceiveRemoteNotification
// In AppDelegate.m
// In AppDelegate.m file under didFinishLaunchingWithOptions Method, set the UNUserNotificationCenterDelegate to the AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//....
[UNUserNotificationCenter currentNotificationCenter].delegate = self;
return YES;
}
// Once the delegation is set, Add the below implementation to the AppDelegate
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
// Getting the userInfo from the notification
NSDictionary *userInfo = notification.request.content.userInfo;
// Calling the RNCPushNotificationIOS:didReceiveRemoteNotification using the userInfo obtained from the notification, so that the callback onNotificationOpenedApp in js file would be called
[RNCPushNotificationIOS didReceiveRemoteNotification:userInfo
fetchCompletionHandler:^void (UIBackgroundFetchResult result){}];
// Finally invoking the iOS completionHandler Callback
completionHandler(UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionSound);
}
At last, After completing the above implementations, we could see the native notification which drops from the top of the screen.
Well, that's a wrap for the article, Hope you enjoyed reading it. Happy Coding!!!