Push Notification using React Native and Firebase – Part 3

Welcome to the third part of the tutorial ‘Push Notification using React Native’. In this part we will see how Push Notification can be coded and  can be sent to the  users phone. If you have directly landed on this page, make sure you check the first 2 parts of the tutorial here :

http://calsob.in/push-notification-using-react-native-and-firebase-part-1

and

http://calsob.in/push-notification-using-react-native-and-firebase-part-2

So first we have to add the following header file to AppDelegate.m

#import "RNFIRMessaging.h"

next we need to add the FIR configuration code snippet to didFinishLaunchingWithOptions method like this

[FIRApp configure];

Next, we need to add following method to AppDelegate.m file

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)notification fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))handler {
     [[NSNotificationCenter defaultCenter] postNotificationName:FCMNotificationReceived object:self userInfo:notification];
     handler(UIBackgroundFetchResultNewData);
   }

So, my final AppDeletgate.m file looks like this :

/**
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */

#import "AppDelegate.h"

#import "RCTBundleURLProvider.h"
#import "RCTRootView.h"
#import "RNFIRMessaging.h"
@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  NSURL *jsCodeLocation;

  jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];

  RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                      moduleName:@"RNF"
                                               initialProperties:nil
                                                   launchOptions:launchOptions];
  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];
  return YES;
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)notification fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))handler {
     [[NSNotificationCenter defaultCenter] postNotificationName:FCMNotificationReceived object:self userInfo:notification];
     handler(UIBackgroundFetchResultNewData);
   }
@end

Now we need to add code to our React Native js files. So, my new index.ios.js file looks like this

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View
} from 'react-native';
import FCM from 'react-native-fcm';
export default class RNF extends Component {
  componentDidMount() {
    FCM.requestPermissions(); // for iOS
    FCM.getFCMToken().then(token => {
      console.log(token)
      // store fcm token in your server
    });
    this.notificationUnsubscribe = FCM.on('notification', (notif) => {
      // there are two parts of notif. notif.notification contains the notification payload, notif.data contains data payload
    });
    this.refreshUnsubscribe = FCM.on('refreshToken', (token) => {
      console.log(token)
      // fcm token may not be available on first load, catch it here
    });

    FCM.subscribeToTopic('/topics/foo-bar');
    FCM.unsubscribeFromTopic('/topics/foo-bar');
  }
  componentWillUnmount() {
    // prevent leaking
    this.refreshUnsubscribe();
    this.notificationUnsubscribe();
  }
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          Welcome to React Native!
        </Text>
        <Text style={styles.instructions}>
          To get started, edit index.ios.js
        </Text>
        <Text style={styles.instructions}>
          Press Cmd+R to reload,{'\n'}
          Cmd+D or shake for dev menu
        </Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

AppRegistry.registerComponent('RNF', () => RNF);

The above codes you can also check in documentation of package react-native-fcm

Now, we need to run the application on our mobile. The first time we run, it will ask for the permission to send notification. We need to accept the permission. We need to turn on the debugger console where we will get a FCM Token.

Finally, we need to go to Firebase google console and click on Notification tab on left side and then click on ‘SEND YOUR FIRST MESSAGE’ button. Now, enter the message text, select ‘SingleDevice’ checkbox and enter the ‘FCM registration token’  that we have in the debugger console log. Now, when you click the send message button, you will see the message in you phone in which app is running. 

To understand the above steps please watch the below video :

 

 

11 thoughts on “Push Notification using React Native and Firebase – Part 3”

  1. Thanks for your awsome tutorial
    i got an error after importing the declaration and the methode inside of AppDelegate.m :

    FCMNotificationReceived use of undeclared identifier

    any help ?

      1. Yes I did…. but keep saying “Use of undeclared identifier ‘FCMNotificationReceived'” 🙁

  2. I followed the tutorial but I could not make it run.

    I’m having this error:

    /Users/imac1/Documents/REPOSITORY/MauritiusUnion/node_modules/react-native-fcm/ios/RNFIRMessaging.m:202:11: error: use of undeclared identifier ‘FIRMessagingConnectionStateChangedNotification’
    name:FIRMessagingConnectionStateChangedNotification object:nil];
    ^
    /Users/imac1/Documents/REPOSITORY/MauritiusUnion/node_modules/react-native-fcm/ios/RNFIRMessaging.m:206:35: error: no visible @interface for ‘FIRMessaging’ declares the selector ‘setDelegate:’
    [[FIRMessaging messaging] setDelegate:self];
    ~~~~~~~~~~~~~~~~~~~~~~~~ ^~~~~~~~~~~
    /Users/imac1/Documents/REPOSITORY/MauritiusUnion/node_modules/react-native-fcm/ios/RNFIRMessaging.m:213:31: error: no visible @interface for ‘FIRMessaging’ declares the selector ‘setShouldEstablishDirectChannel:’
    [[FIRMessaging messaging] setShouldEstablishDirectChannel:@YES];
    ~~~~~~~~~~~~~~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /Users/imac1/Documents/REPOSITORY/MauritiusUnion/node_modules/react-native-fcm/ios/RNFIRMessaging.m:218:39: error: no visible @interface for ‘FIRMessaging’ declares the selector ‘isDirectChannelEstablished’
    resolve([[FIRMessaging messaging] isDirectChannelEstablished] ? @YES: @NO);
    ~~~~~~~~~~~~~~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~
    /Users/imac1/Documents/REPOSITORY/MauritiusUnion/node_modules/react-native-fcm/ios/RNFIRMessaging.m:233:53: error: property ‘APNSToken’ not found on object of type ‘FIRMessaging *’
    NSData * deviceToken = [FIRMessaging messaging].APNSToken;
    ^
    /Users/imac1/Documents/REPOSITORY/MauritiusUnion/node_modules/react-native-fcm/ios/RNFIRMessaging.m:244:38: error: property ‘FCMToken’ not found on object of type ‘FIRMessaging *’
    resolve([FIRMessaging messaging].FCMToken);
    ^
    /Users/imac1/Documents/REPOSITORY/MauritiusUnion/node_modules/react-native-fcm/ios/RNFIRMessaging.m:508:93: error: property ‘isDirectChannelEstablished’ not found on object of type ‘FIRMessaging *’
    [self sendEventWithName:FCMDirectChannelConnectionChanged body:[FIRMessaging messaging].isDirectChannelEstablished ? @YES: @NO];
    ^
    /Users/imac1/Documents/REPOSITORY/MauritiusUnion/node_modules/react-native-fcm/ios/RNFIRMessaging.m:509:67: error: property ‘isDirectChannelEstablished’ not found on object of type ‘FIRMessaging *’
    NSLog(@”connectionStateChanged: %@”, [FIRMessaging messaging].isDirectChannelEstablished ? @”connected”: @”disconnected”);
    ^
    8 errors generated.
    Command /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang failed with exit code 1

    Can you please help ?

  3. Hello. I did not try follow this tutorial cause i need to developing for android. Have u analog for android push notification? I need to understand how it makes when application is closed (no active not in the background) in particular.

  4. I get the error as “RNFIRMessaging.h” file not found in Appdelegate.m. Please reply asap.

    Thank you

Comments are closed.