question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Push notifications not working. Do you need to use RNFirebase's notification module?

See original GitHub issue

I’ve followed the readme here but can’t get push notifications to work via Intercom’s backend.

I can see the user has accepted/sent the FCM token back to Intercom via the app, and I can target said user in Intercom to send a push notification to them.

But in-device it never shows up.

Am I missing something? Do I need to implement some other parts of React Native Firebase to make this integration work? (perhaps their messaging/notification platforms?) Or should this work out of the box?

Here’s some code for good measure (Just testing in Android at the moment)

build.gradle:


apply plugin: 'com.android.application'

apply from: project(':react-native-config').projectDir.getPath() + '/dotenv.gradle'

import com.android.build.OutputFile

def username = System.properties['user.name']

project.ext.react = [
    bundleInStaging: true,
    bundleInUat: true,
    devDisabledInStaging: true,
    devDisabledInUat: true,
    entryFile: "index.js"
]

apply from: '../../node_modules/react-native/react.gradle'


android {
    compileSdkVersion 26
    buildToolsVersion '27.0.3'

    dexOptions {
        preDexLibraries false
        javaMaxHeapSize '4g'
    }

    defaultConfig {
        applicationId 'com.APP_NAME'
        minSdkVersion 16
        targetSdkVersion 26
        versionCode 233
        versionName '1.5.0'

        ndk {
            abiFilters 'armeabi-v7a', 'x86'
        }
        resValue 'string', 'build_config_package', 'com.APP_NAME'
        multiDexEnabled true
    }
    
}

dependencies {
    compile project(':react-native-fbsdk')
    compile project(':react-native-image-resizer')
    // NOTE: The following line is added to force android to compile
    // against the correct version of react-native.
    // See https://github.com/facebook/react-native/issues/16762
    implementation ("com.facebook.react:react-native:0.54.4") {
        force = true
    }

    implementation project(':react-native-device-info')
    implementation project(':react-native-intercom')
    implementation project(':react-native-sentry')
    implementation project(':react-native-config')
    implementation project(':react-native-auth0')
    implementation project(':react-native-keychain')
    implementation project(':lottie-react-native')
    implementation project(':react-native-svg')
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.facebook.react:react-native:+'

    // RNFirebase required dependencies
    implementation(project(':react-native-firebase')) {
        transitive = false
    }
    // Firebase dependencies
    implementation "com.google.android.gms:play-services-base:15.0.0"
    implementation "com.google.firebase:firebase-core:15.0.0"
    implementation "com.google.firebase:firebase-analytics:15.0.0"

    // other dependancies.
    implementation project(':react-native-image-picker')
    implementation project(':react-native-share')
}

// Run this once to be able to run the application with BUCK
// puts all compile dependencies into folder libs for BUCK to use
task copyDownloadableDepsToLibs(type: Copy) {
    from configurations.compile
    into 'libs'
}

apply plugin: 'com.google.gms.google-services'


AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.goodwork"
  android:versionCode="1"
  android:versionName="1.0"
  xmlns:tools="http://schemas.android.com/tools"
  >

  <uses-sdk
    android:minSdkVersion="16"
    android:targetSdkVersion="26" />

  <uses-permission android:name="android.permission.INTERNET" />
  <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
  <uses-permission android:name="android.permission.BLUETOOTH"/>
  <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  <uses-permission android:name="android.permission.CAMERA" />
  <uses-permission android:name="android.permission.TYPE_APPLICATION_OVERLAY"/>
  <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
  <uses-permission android:name="android.permission.VIBRATE" />

  <uses-feature android:name="android.hardware.camera" android:required="false"/>
  <uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>

  <application
    android:name=".MainApplication"
    android:allowBackup="false"
    android:label="@string/app_name"
    android:icon="@mipmap/ic_launcher"
    android:theme="@style/AppTheme">

    <meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/>

    <activity
      android:name=".SplashActivity"
      android:label="@string/app_name"
      android:theme="@style/SplashTheme">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>

    <activity
      android:name=".MainActivity"
      android:screenOrientation="portrait"
      android:label="@string/app_name"
      android:launchMode="singleTask"
      android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
      android:windowSoftInputMode="adjustResize"

    >
    </activity>
    <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />

    <provider
      android:name="android.support.v4.content.FileProvider"
      android:authorities="${applicationId}.provider"
      android:grantUriPermissions="true"
      android:exported="false">
    </provider>

    <provider android:authorities="com.facebook.app.FacebookContentProvider1717347231677583"
        android:name="com.facebook.FacebookContentProvider"
        android:exported="true" />

    <!-- Intercom Service Setup -->
   <service
        android:name="com.robinpowered.react.Intercom.IntercomIntentService"
        android:exported="false">
      <intent-filter
          android:priority="999">
        <action android:name="com.google.android.c2dm.intent.RECEIVE"/>
      </intent-filter>
    </service>
    <receiver
        android:name="io.intercom.android.sdk.push.IntercomPushBroadcastReceiver"
        tools:replace="android:exported"
        android:exported="true" />

  </application>
</manifest>

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:5

github_iconTop GitHub Comments

7reactions
jvgeeecommented, Jul 5, 2018

@Rajat421 Here’s what I’ve done to get it working. Note that all of this is just harried-together stuff I found in various Github threads offering support, so some of it may be very redundant. I dunno! But push notifications in intercom AND notifications from Firebase FCM are working for us now so that’s all that matters to me 😃 Feel free to suggest any edits if I’ve done anything dumb:

### IOS

Pods:

  # Required by RNFirebase
  pod 'Firebase/Core'
  pod 'Firebase/Messaging'

  # React Native Intercom
  pod 'react-native-intercom', :path => '../node_modules/react-native-intercom'

AppDelegate.m

#import <Firebase.h>
#import "RNFirebaseNotifications.h"
#import "RNFirebaseMessaging.h"
#import <UserNotifications/UserNotifications.h>

#import "Intercom/intercom.h"

.....


// Within didFinishLaunchingWithOptions(){

[FIRApp configure]; // Required by react-native-firebase
  [RNFirebaseNotifications configure];
  // Setup Notifications
  if ([UNUserNotificationCenter class] != nil) {
    // iOS 10 or later
    // For iOS 10 display notification (sent via APNS)
    [UNUserNotificationCenter currentNotificationCenter].delegate = self;
    UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert |
    UNAuthorizationOptionSound | UNAuthorizationOptionBadge;
    [FIRMessaging messaging].delegate = self;
    [[UNUserNotificationCenter currentNotificationCenter]
     requestAuthorizationWithOptions:authOptions
     completionHandler:^(BOOL granted, NSError * _Nullable error) {
       if (error) { NSLog(@"%@", error); }
     }];
  } else {
    // iOS 10 notifications aren't available; fall back to iOS 8-9 notifications.
    UIUserNotificationType allNotificationTypes =
    (UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge);
    UIUserNotificationSettings *settings =
    [UIUserNotificationSettings settingsForTypes:allNotificationTypes categories:nil];
    [application registerUserNotificationSettings:settings];
  }
  [application registerForRemoteNotifications];

// Initialize Intercom

  NSString *intercomApiKey = [ReactNativeConfig envFor:@"INTERCOM_IOS_KEY"];
  NSString *intercomAppId  = [ReactNativeConfig envFor:@"INTERCOM_APP_ID"];

  [Intercom setApiKey:intercomApiKey forAppId:intercomAppId];

Then all of these at the end of the file (outside of didFinishLaunchingWithOptions):


- (void)applicationDidBecomeActive:(UIApplication *)application {
  [application registerUserNotificationSettings:
   [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert)
                                     categories:nil]];
  [application registerForRemoteNotifications];
}


- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
     [Intercom setDeviceToken:deviceToken];
}

- (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];
}

In AppDelegate.h:


#import <UIKit/UIKit.h>

@import UserNotifications;

@interface AppDelegate : UIResponder <UIApplicationDelegate, UNUserNotificationCenterDelegate>

@property (nonatomic, strong) UIWindow *window;

@end

That got it working in IOS.

For Android:

/android/build.gradle, I’m importing these files (Can’t remembver if react-native-fcm is actually necessary tbh):

include ':react-native-fcm'
project(':react-native-fcm').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-fcm/android')

include ':react-native-firebase'
project(':react-native-firebase').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-firebase/android')

include ':react-native-intercom'
project(':react-native-intercom').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-intercom/android')

in /android/app/build.gradle, I use these implementations:

    implementation project(':react-native-intercom')
    implementation 'io.intercom.android:intercom-sdk-base:5.+'
    implementation 'io.intercom.android:intercom-sdk-fcm:5.+'

    // Firebase dependencies
    implementation 'com.google.android.gms:play-services-base:15.0.0'
    implementation 'com.google.firebase:firebase-core:15.0.0'
    implementation 'com.google.firebase:firebase-analytics:15.0.0'
    implementation 'com.google.firebase:firebase-messaging:15.0.0'

In android/app/src/main/java/AppName/MainApplication.java:


// Required by RNFirebase
import io.invertase.firebase.RNFirebasePackage;
import io.invertase.firebase.analytics.RNFirebaseAnalyticsPackage;
import io.invertase.firebase.messaging.RNFirebaseMessagingPackage;
import io.invertase.firebase.notifications.RNFirebaseNotificationsPackage;

// Required by Intercom
import com.robinpowered.react.Intercom.IntercomPackage;
import io.intercom.android.sdk.Intercom;

..... // within protected List<ReactPackage> getPackages():
          // Other page imports go here
          new RNFirebaseAnalyticsPackage(),
          new RNFirebaseMessagingPackage(),
          new RNFirebaseNotificationsPackage(),
          new IntercomPackage()

I also made two new handler files to handle incoming notifications, which both go in the same folder as MainApplication.java:

MainInstanceIdService.java:

package com.goodwork;

import io.invertase.firebase.messaging.*;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import io.intercom.android.sdk.push.IntercomPushClient;
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.FirebaseInstanceIdService;

public class MainInstanceIdService extends FirebaseInstanceIdService {
  private final IntercomPushClient intercomPushClient = new IntercomPushClient();
  private static final String TAG = "InstanceIdService";

  /**
   * Called if InstanceID token is updated. This may occur if the security of
   * the previous token had been compromised. This call is initiated by the
   * InstanceID provider.
   */
  @Override
  public void onTokenRefresh() {
    // Get updated InstanceID token.
    String refreshedToken = FirebaseInstanceId.getInstance().getToken();
    intercomPushClient.sendTokenToIntercom(getApplication(), refreshedToken);
    Log.d(TAG, "Refreshed token: " + refreshedToken);

    // Broadcast refreshed token
    Intent i = new Intent("io.invertase.firebase.messaging.FCMRefreshToken");
    Bundle bundle = new Bundle();
    bundle.putString("token", refreshedToken);
    i.putExtras(bundle);
    sendBroadcast(i);
  }
}

First is MainMessagingService.java:

package com.goodwork;
import io.invertase.firebase.messaging.*;
import android.content.Intent;
import android.content.Context;
import io.intercom.android.sdk.push.IntercomPushClient;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
import android.util.Log;
import java.util.Map;

public class MainMessagingService extends FirebaseMessagingService {
    private static final String TAG = "MainMessagingService";
    private final IntercomPushClient intercomPushClient = new IntercomPushClient();

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        Map message = remoteMessage.getData();

        if (intercomPushClient.isIntercomPush(message)) {
            Log.d(TAG, "Intercom message received");
            intercomPushClient.handlePush(getApplication(), message);
        } else {
            super.onMessageReceived(remoteMessage);
        }
    }
}

THEN (nearly done!) in /android/app/src/AndroidManifest.xml, you need to reference those two files you just made:

   <application>
    // Lots of other stuff here
    <!-- Intercom Service Setup -->
    <service
        android:name="com.robinpowered.react.Intercom.IntercomIntentService"
        android:exported="false">
      <intent-filter
          android:priority="999">
        <action android:name="com.google.android.c2dm.intent.RECEIVE"/>
      </intent-filter>
    </service>
    <receiver
        android:name="io.intercom.android.sdk.push.IntercomPushBroadcastReceiver"
        tools:replace="android:exported"
        android:exported="true" />

     <service
        android:name=".MainMessagingService"
        android:enabled="true"
        android:exported="true">
          <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
          </intent-filter>
      </service>
      <service android:name=".MainInstanceIdService" android:exported="false">
          <intent-filter>
            <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
          </intent-filter>
      </service>
</application>

React Native Javascript:

The only other thing to do was, in my app, after a user logs in, I’m getting their FCM token with React Native Firebase and sending it to Intercom. I also send it to my database (as we’re also using Firebase Cloud Messaging to send transactional push notifications to our users, so need to store their FCMToken on their user profile):

firebase
      .messaging()
      .hasPermission()
      .then(async enabled => {
        if (enabled) {
          // user has permissions
          const FCMToken = await firebase.messaging().getToken();
          console.log('Had permission and got FCM', FCMToken);
        } else {
          // user doesn't have permission
          firebase
            .messaging()
            .requestPermission()
            .then(async () => {
              // User has authorised
              const FCMToken = await firebase.messaging().getToken();
              console.log('Got FCM', FCMToken);
              // Save the FCM token to a user's profile
              store.dispatch(userSaveFCM(user, FCMToken))
              
              // Send the token to Intercom (this is AFTER i've done Intercom.registerIdentifiedUser() )
              Intercom.sendTokenToIntercom(data.FCMToken);

            })
            .catch(error => {
              // User has rejected permissions
              console.log('User has rejected permissions', error);
            });
        }
      });
1reaction
cbrwizardcommented, Feb 20, 2019

@jascination’s code for Android worked for me 🎉 Same for iOS. Thank you!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Notifications | React Native Firebase
Notifications are an important tool used on the majority of Android & iOS applications, used to improve user experience, used to engage users...
Read more >
IOS push notifications not working on react native using ...
To implement push notifications using Firebase, please use https://rnfirebase.io/messaging/usage. Just upload APN Key to firebase and Add ...
Read more >
React Native push notifications with Firebase Cloud Messaging
This means you can use React Native to build a complete mobile app ... Cloud Messaging and the device's push notifications to notify...
Read more >
Firebase Push Notification In React Native - Medium
In this blog, we'll learn how to integrate push notifications in React ... By default, rnfirebase does not support displaying notification popups when...
Read more >
Sending Push Notifications to React Native Using Firebase
Let's look at how we can integrate Firebase into a React Native app. ... React-native-push-notification: Necessary to send local ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found