Reputation: 1107
I have a react native project. I am able to receive the FCM token successfully but when trying to send a notification, the app doesn't receive the notification.
The steps I followed are as below:
npm install --save react-native-firebase
pod ‘Firebase/Core’
pod install
#import <Firebase.h>
and [FIRApp configure];
using const fcmToken = await firebase.messaging().getToken();
I am able to get token.
Below is the code for the notification listener.
async createNotificationListeners() {
/*
* Triggered when a particular notification has been received in foreground
* */
this.notificationListener = firebase.notifications().onNotification((notification) => {
const {
title,
body
} = notification;
this.custom_data = notification.data;
const localNotification = new firebase.notifications.Notification({
show_in_foreground: true,
})
.setSound('default')
.setNotificationId(notification.notificationId)
.setTitle(notification.title)
.setBody(notification.body)
firebase.notifications()
.displayNotification(localNotification)
.catch(err => Alert.alert(err));
});
/*
* If your app is in foreground and background, you can listen for when a notification is clicked / tapped / opened as follows:
* */
this.notificationOpenedListener = firebase.notifications().onNotificationOpened((notificationOpen) => {
if ("title" in notificationOpen.notification.data) {
const {
title,
body,
secret_key,
user_id,
realm_id,
user_os,
user_location
} = notificationOpen.notification.data;
this.props.navigation.navigate('Verify', {
title: title,
body: body,
secret_key: secret_key,
user_id: user_id,
realm_id: realm_id,
user_os: user_os,
user_location: user_location
});
} else {
const {
title,
body,
secret_key,
user_id,
realm_id,
user_os,
user_location
} = this.custom_data;
this.props.navigation.navigate('Verify', {
title: title,
body: body,
secret_key: secret_key,
user_id: user_id,
realm_id: realm_id,
user_os: user_os,
user_location: user_location
});
}
});
/*
* If your app is closed, you can check if it was opened by a notification being clicked / tapped / opened as follows:
* */
const notificationOpen = await firebase.notifications().getInitialNotification();
if (notificationOpen) {
const {
title,
body,
secret_key,
user_id,
realm_id,
user_os,
user_location
} = notificationOpen.notification.data;
this.props.navigation.navigate('FCM', {
title: title,
body: body,
secret_key: secret_key,
user_id: user_id,
realm_id: realm_id,
user_os: user_os,
user_location: user_location
});
}
/*
* Triggered for data only payload in foreground
* */
this.messageListener = firebase.messaging().onMessage((message) => {
console.log("JSON.stringify:", JSON.stringify(message));
});
}
Please do let me know if more details required.
EDIT
I have updated the code. Now I am able to get firebase.messaging().onMessage()
code working and receive a trigger in the foreground. Still unable to get the notification when the app is in the background. Below is the change which I have made.
const fcmToken = await firebase.messaging().getToken();
firebase.messaging().ios.registerForRemoteNotifications().then((flag)=>{
console.log("registered", flag);
}).catch((err)=>{
console.log("message", err);
});
AppDelegate.m
#import "AppDelegate.h"
#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <Firebase.h>
#import "RNFirebaseNotifications.h"
#import "RNFirebaseMessaging.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[FIRApp configure];
[[UNUserNotificationCenter currentNotificationCenter] setDelegate:self];
[RNFirebaseNotifications configure];
//[FIRApp configure];
[Fabric with:@[[Crashlytics class]]];
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:@"CymmAuth"
initialProperties:nil];
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
return YES;
}
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo
fetchCompletionHandler:(nonnull void (^)(UIBackgroundFetchResult))completionHandler{
[[RNFirebaseNotifications instance] didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
[[RNFirebaseMessaging instance] didRegisterUserNotificationSettings:notificationSettings];
}
-(void) userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
[[RNFirebaseMessaging instance] didReceiveRemoteNotification:response.notification.request.content.userInfo];
completionHandler();
}
@end
Do let me know if I am missing anything. firebase.notifications().onNotification()
doesn't get triggered
Upvotes: 3
Views: 11450
Reputation: 1107
After referring multiple articles from google, I managed to solve the problem. I have realized that many are facing the issue. So I am mentioning all the steps and code which I have implemented.
App Id and APNs key need to be generated from Apple's Developer Account. After generating App Id and APNs key, add the generated APNs key in your Firebase Project. In the App Id where you have added Push Notification as capability configure it with developer and production service SSL Certificates.
Also, make sure the GoogleService-Info.plist file is added in your iOS project through Xcode under the project name.
In Signing & Capabilities of Xcode add Push Notifications and Background Modes > Remote notification, Background fetch, Background processing (confirm if the capabilities are reflecting in both Debug and Release).
In info.plist FIRAnalyticsDebugEnabled, FirebaseAppDelegateProxyEnabled, FirebaseScreenReportingEnabled set to No
In Xcode Scheme > Edit Scheme... check if Run modes Build Configuration is set to Debug. This will help to generate the console in Xcode when you debug the app in your device.
npm install --save react-native-firebase
pod 'Firebase/Core'
pod 'Firebase/Messaging'
pod 'Firebase/Crashlytics'
pod 'Firebase/Analytics'
pod 'RNFirebase', :path => '../node_modules/react-native-firebase/ios'
cd ios
> pod install
Code to get FCM token and APNs token.
const fcmToken = await firebase.messaging().getToken();
console.log("FCM_Token", fcmToken);
firebase.messaging().ios.registerForRemoteNotifications().then((flag) => {
firebase.messaging().ios.getAPNSToken().then(apns => {
console.log("Apn Token", apns);
}).catch((e) => {
})
}).catch((err) => {
console.log("message", err);
});
AppDelegate.m
#import "AppDelegate.h"
#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <Firebase.h>
#import "RNFirebaseNotifications.h"
#import "RNFirebaseMessaging.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[FIRApp configure];
[RNFirebaseNotifications configure];
[[UNUserNotificationCenter currentNotificationCenter] setDelegate:self];
[application registerForRemoteNotifications];
[Fabric with:@[[Crashlytics class]]];
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:@"CymmAuth"
initialProperties:nil];
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
return YES;
}
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
}
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
[[RNFirebaseNotifications instance] didReceiveLocalNotification:notification];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo
fetchCompletionHandler:(nonnull void (^)(UIBackgroundFetchResult))completionHandler{
[[RNFirebaseNotifications instance] didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
[[RNFirebaseMessaging instance] didRegisterUserNotificationSettings:notificationSettings];
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
[FIRMessaging messaging].APNSToken = deviceToken;
}
@end
AppDelegate.h
#import <React/RCTBridgeDelegate.h>
#import <UIKit/UIKit.h>
#import <Firebase.h>
#import <UserNotifications/UserNotifications.h>
@import UserNotifications;
@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate, UNUserNotificationCenterDelegate>
@property (nonatomic, strong) UIWindow *window;
@end
This will get the notification on your Apple Device.
To test the notification, FCM token validity, and to regenerate valid FCM token from APNs token, there is an API call of Firebase. This could be an additional help to test.
Endpoint: https://fcm.googleapis.com/fcm/send
Type: POST
Header: Authorization: "key:fcm_server_key"
Body:{ "to": "fcm_token", "content_available": true, "mutable_content": true, "data": { "message": "Batman!", "mediaUrl": "https://upload.wikimedia.org/wikipedia/commons/thumb/2/2a/FloorGoban.JPG/1024px-FloorGoban.JPG" }, "notification": { "body": "Enter your message", "sound": "default" } }
Endpoint: https://iid.googleapis.com/iid/info/your_fcm_token
Type: GET
Header: Authorization: "key:fcm_server_key"
Endpoint: https://iid.googleapis.com/iid/v1:batchImport
Type: POST
Header: Authorization: "key:fcm_server_key"
Body:{ "application":"package Id", "sandbox":true, "apns_tokens":[ "apnstoken 1","apnstoken 2" ] }
I hope this helps. Thank you.
Upvotes: 17