I'm trying to upgrade our RN project to 0.66 (from 0.63). When I build the project in debug mode, the app crashes on startup due to uncaught exception 'NSInvalidArgumentException', reason: '-[REAEventDispatcher setBridge:]: unrecognized selector sent to instance 0x600002f51cc0' when initializing the RCTRootView in the AppDelegate.m file (entire file at the end).
After some googling, I found the unrecognized selector bit is because some function is undefined on an object. The error is marked in the code, its about halfway through the file.
I need some help finding out why this function isn't available (or what else is wrong). As far as I can see, the files have an implementation of the functions that are called. Am I missing any imports? Not that well versed in Swift, only used it in combination with React Native.
I haven't made a reproducible example, but I hope someone else has come over this already in porting to this version. If you need any more information, please ask. I've also attached the podfile below the relevant file.
Appdelegate.m
#import "AppDelegate.h"
#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <React/RCTLinkingManager.h>
#import "RNBootSplash.h"
#import <GoogleMaps/GoogleMaps.h>
#import <UserNotifications/UserNotifications.h>
#import <RNCPushNotificationIOS.h>
#import <Firebase.h>
#ifdef FB_SONARKIT_ENABLED
#import <FlipperKit/FlipperClient.h>
#import <FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.h>
#import <FlipperKitNetworkPlugin/FlipperKitNetworkPlugin.h>
#import <FlipperKitReactPlugin/FlipperKitReactPlugin.h>
#import <FlipperKitUserDefaultsPlugin/FKUserDefaultsPlugin.h>
#import <SKIOSNetworkPlugin/SKIOSNetworkAdapter.h>
static void InitializeFlipper(UIApplication *application) {
FlipperClient *client = [FlipperClient sharedClient];
SKDescriptorMapper *layoutDescriptorMapper =
[[SKDescriptorMapper alloc] initWithDefaults];
[client addPlugin:[[FlipperKitLayoutPlugin alloc]
initWithRootNode:application
withDescriptorMapper:layoutDescriptorMapper]];
[client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]];
[client addPlugin:[FlipperKitReactPlugin new]];
[client addPlugin:[[FlipperKitNetworkPlugin alloc]
initWithNetworkAdapter:[SKIOSNetworkAdapter new]]];
[client start];
}
#endif
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if([FIRApp defaultApp] == nil){
[FIRApp configure];
}
[GMSServices provideAPIKey:#"AIzaSyC-BV0Dp46BQ1iP1HRws-oP_90FV0Aewfo"]; // add this line using the api key obtained from Google Console
#ifdef FB_SONARKIT_ENABLED
InitializeFlipper(application);
#endif
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions]
//This is where the application crashes
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:#"Flatz"
initialProperties:nil];
if (#available(iOS 13.0, *)) {
rootView.backgroundColor = [UIColor systemBackgroundColor];
} else {
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];
[RNBootSplash initWithStoryboard:#"LaunchScreen" rootView:rootView]; // <- initialization using the storyboard file name
// Define UNUserNotificationCenter
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
return YES;
}
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge {
#ifdef FB_SONARKIT_ENABLED
return
[[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:#"index"
fallbackResource:nil];
#else
return [[NSBundle mainBundle] URLForResource:#"main"
withExtension:#"jsbundle"];
#endif
}
// 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 localNotification event
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void (^)(void))completionHandler
{
[RNCPushNotificationIOS didReceiveNotificationResponse:response];
}
//Called when a notification is delivered to a foreground app.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
completionHandler(UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge);
}
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
return [RCTLinkingManager application:application openURL:url options:options];
}
- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity
restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
{
return [RCTLinkingManager application:application
continueUserActivity:userActivity
restorationHandler:restorationHandler];
}
#end
Podfile
require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/#react-native-community/cli-platform-ios/native_modules'
platform :ios, '11.0'
target 'Flatz' do
# No individual tracking of people or their phones
$RNFirebaseAnalyticsWithoutAdIdSupport=true
# React Native Maps dependencies
rn_maps_path = '../node_modules/react-native-maps'
pod 'react-native-google-maps', :path => rn_maps_path
pod 'GoogleMaps'
pod 'Google-Maps-iOS-Utils'
config = use_native_modules!
use_react_native!(
:path => config["reactNativePath"],
:hermes_enabled => true
)
target 'FlatzTests' do
inherit! :complete
# Pods for testing
end
# Enables Flipper.
#
# Note that if you have use_frameworks! enabled, Flipper will not work and
# you should disable these next few lines.
use_flipper!({ 'Flipper-Folly' => '2.5.3', 'Flipper' => '0.87.0', 'Flipper-RSocket' => '1.3.1' })
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
#1
deployment_target = config.build_settings['IPHONEOS_DEPLOYMENT_TARGET']
#2
target_components = deployment_target.split
#3
if target_components.length > 0
#4
target_initial = target_components[0].to_i
#5
if target_initial < 9
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = "9.0"
end
end
end
end
installer.pods_project.build_configurations.each do |config|
config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64"
end
end
permissions_path = '../node_modules/react-native-permissions/ios'
pod 'Permission-Camera', :path => "#{permissions_path}/Camera"
end
As jnpdx pointed out, I needed to follow the upgrade helper. Turns out there were quite a few steps I had missed doing it without it.
For me I had the iOS Deployment target under build settings on 9, while on the Podfile on 11. Changing to 11 solved the problem, see how to change iOS Deployment target. Also, remember to npx react-native-clean-project
Background notifications are received on Android but not on IOS in react native.
index.js
messaging().setBackgroundMessageHandler(async (message)=>{
console.log(message)
});
This is called before registering the component as is mentioned in a certain Github issues.
This problem arises after migrating to react native firebase v6.
Package versions:-
"#react-native-firebase/app": "^11.0.0",
"#react-native-firebase/messaging": "^11.0.0"
AppDelegate.m
#import "AppDelegate.h"
#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#ifdef FB_SONARKIT_ENABLED
#import <FlipperKit/FlipperClient.h>
#import <FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.h>
#import <FlipperKitUserDefaultsPlugin/FKUserDefaultsPlugin.h>
#import <FlipperKitNetworkPlugin/FlipperKitNetworkPlugin.h>
#import <SKIOSNetworkPlugin/SKIOSNetworkAdapter.h>
#import <FlipperKitReactPlugin/FlipperKitReactPlugin.h>
static void InitializeFlipper(UIApplication *application) {
FlipperClient *client = [FlipperClient sharedClient];
SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults];
[client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application withDescriptorMapper:layoutDescriptorMapper]];
[client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]];
[client addPlugin:[FlipperKitReactPlugin new]];
[client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]];
[client start];
}
#endif
#import <GoogleMaps/GoogleMaps.h>
#import <Firebase.h>
#import <React/RCTLinkingManager.h>
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
#ifdef FB_SONARKIT_ENABLED
InitializeFlipper(application);
#endif
[GMSServices provideAPIKey:#"AIzaSyA19U0nRV9PKyWHz-252DKVkShrzooWt5Q"];
[FIRApp configure];
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:#"Sociana"
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;
}
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *, id> *) options {
return [RCTLinkingManager application:app openURL:url options:options];
//return [self.authorizationFlowManagerDelegate resumeExternalUserAgentFlowWithURL:url];
}
- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity
restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
{
return [RCTLinkingManager application:application
continueUserActivity:userActivity
restorationHandler:restorationHandler];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo
fetchCompletionHandler:(nonnull void (^)(UIBackgroundFetchResult))completionHandler{
}
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:#"index" fallbackResource:nil];
#else
return [[NSBundle mainBundle] URLForResource:#"main" withExtension:#"jsbundle"];
#endif
}
#end
AppDelegate.h
#import <React/RCTBridgeDelegate.h>
#import <UIKit/UIKit.h>
#import "RNAppAuthAuthorizationFlowManager.h"
#interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate,RNAppAuthAuthorizationFlowManager>
#property (nonatomic, strong) UIWindow *window;
#property(nonatomic, weak)id<RNAppAuthAuthorizationFlowManagerDelegate>authorizationFlowManagerDelegate;
#end
The notification payload that I am sending through the REST API is:-
apns: {
payload: {
aps: {
"content-available": "true"
}
},
headers: {
"apns-priority": "10",
}
}
I have used an external device for testing, enabled all the background modes and push notifications in xcode and also from the apple dev account.
Current xcode version is 12.4
Any help will be appreciated. Thank you!
Replace the value of content-available in apns header to be 1 instead of "true":
"content-available":1
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:
Created a project in Firebase Console.
Added the Firebase .plist in the projectName through Xcode.
ran npm install --save react-native-firebase
Added in podfile: pod ‘Firebase/Core’
ran pod install
Update AppDelegate.m with #import <Firebase.h> and [FIRApp configure];
Added the APNS in the Firebase Dashboard for iOS App Cloud Messaging.
Updated the capabilities with Push Notification and Background Modes > Remote notification
In info.plist FIRAnalyticsDebugEnabled, FirebaseAppDelegateProxyEnabled, FirebaseScreenReportingEnabled is set to No
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
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.
In React App npm install --save react-native-firebase
Update pods in Podfile of ios project
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.
Send Push Notification
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"
}
}
Validate your FCM token
Endpoint: https://iid.googleapis.com/iid/info/your_fcm_token
Type: GET
Header: Authorization: "key:fcm_server_key"
Regenerate FCM token using APNs token
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.
My project is importing 'react-native-firebase' and I'm trying sending test messages through firebase console using a device token. The method firebase.notifications().onNotification((notification)=>{}) triggers on android devices, but doesn't trigger on ios devices.
Notifications don't pop up both on foreground and background. I've tried 'console.log' in the method but doesn't present anything. please let me know what the problem is.
I tried 'onMessage()' but it triggers on foreground only.
here's my code:
if (Platform.OS == 'android') {
this.notificationListener = firebase.notifications().onNotification((notification: Notification) => {
console.log("onNotification");
console.log(notification);
notification
.setSound("default")
.android.setChannelId('default')
.android.setBigText(notification.body, notification.title, '')
// .android.setSmallIcon('#mipmap/icon_noti');
firebase.notifications().displayNotification(notification);
});
}
else {
this.notificationListener = firebase.notifications().onNotification((notification) => {
notification.setNotificationId(notification.messageId)
notification.setSound("default");
notification.setTitle(notification.data.title)
notification.ios.setBadge(notification.ios.badge ? notification.ios.badge + 1 : 0);
firebase.notifications().displayNotification(notification);
});
appDelegate.m:
#import "AppDelegate.h"
#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <GoogleMaps/GoogleMaps.h>
#import <Firebase.h>
#import <FirebaseMessaging.h>
#import "RNFirebaseNotifications.h"
#import "RNFirebaseMessaging.h"
#import "RNSplashScreen.h"
#import Firebase;
#import UserNotifications;
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[GMSServices provideAPIKey:#"aasdfsafdadgadgadfasf"];
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:#"asdb"
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];
[FIRApp configure];
[RNFirebaseNotifications configure];
[RNSplashScreen show];
[[UIApplication sharedApplication] registerForRemoteNotifications];
[[UNUserNotificationCenter currentNotificationCenter] setDelegate:self];
return YES;
}
- (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 didReceiveLocalNotification:(UILocalNotification *)notification {
[[RNFirebaseNotifications instance] didReceiveLocalNotification:notification];
}
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:#"index" fallbackResource:nil];
#else
return [[NSBundle mainBundle] URLForResource:#"main" withExtension:#"jsbundle"];
#endif
}
#end
My FB Deferred deep link is: einee://free_marilyn_monroe=true.
Clicking on Install in the test ad (when the app is already installed) works fine.
However, when the app is not yet installed and clicking on the FB ad Install button which takes the user to the App Store, the deep link is not found when the app launches.
This is my code in React Native to detect the deep link:
Linking.getInitialURL().then((url) => {
if(url){
if(url.includes('free_marilyn_monroe=true')){
// Deep link detected code
}
}
// ...
This is my AppDelegate.m code:
/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "AppDelegate.h"
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import "SplashScreen.h"
#import <Fabric/Fabric.h>
#import <Crashlytics/Crashlytics.h>
#import <FBSDKCoreKit/FBSDKCoreKit.h>
#import <react-native-branch/RNBranch.h>
#import GoogleMobileAds;
#import Firebase;
#implementation AppDelegate
- (void)applicationDidBecomeActive:(UIApplication *)application {
[FBSDKAppEvents activateApp];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[FIRApp configure];
// Uncomment this line to use the test key instead of the live one.
// [RNBranch useTestInstance];
[RNBranch initSessionWithLaunchOptions:launchOptions isReferrable:YES];
NSURL *jsCodeLocation;
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:#"index" fallbackResource:nil];
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:#"Einee"
initialProperties:nil
launchOptions:launchOptions];
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
[[FBSDKApplicationDelegate sharedInstance] application:application
didFinishLaunchingWithOptions:launchOptions];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
[SplashScreen show];
[Fabric with:#[[Crashlytics class]]];
[GADMobileAds configureWithApplicationID:#"ca-app-pub-3594094751431969~9145980369"];
return YES;
}
// Respond to URI scheme links
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
if (![RNBranch.branch application:application openURL:url options:options]) {
// Facebook scheme click detect
return [[FBSDKApplicationDelegate sharedInstance] application:application openURL:url sourceApplication:sourceApplication annotation:annotation];
}
return YES;
}
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler {
return [RNBranch continueUserActivity:userActivity];
}
#end
Am I detecting the deep link wrong? Please help!
You have used url scheme for deep linking, suggest to use universal linking to handle the case when the app is not installed. Checkout the difference between two here.