Skip to content

feat: Add push notification support for expo#191

Merged
TheNerdGuyLulu merged 4 commits intomainfrom
feat/add-push-support-expo
Apr 30, 2024
Merged

feat: Add push notification support for expo#191
TheNerdGuyLulu merged 4 commits intomainfrom
feat/add-push-support-expo

Conversation

@TheNerdGuyLulu
Copy link
Contributor

@TheNerdGuyLulu TheNerdGuyLulu commented Apr 26, 2024

@TheNerdGuyLulu TheNerdGuyLulu force-pushed the feat/add-push-support-expo branch from 6fe35e3 to b81e919 Compare April 26, 2024 10:31
@TheNerdGuyLulu TheNerdGuyLulu force-pushed the feat/add-push-support-expo branch from b81e919 to d8231c0 Compare April 26, 2024 10:32
uddish
uddish previously approved these changes Apr 26, 2024
Copy link
Contributor

@uddish uddish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice one!

@TheNerdGuyLulu TheNerdGuyLulu disabled auto-merge April 30, 2024 13:51
@TheNerdGuyLulu TheNerdGuyLulu enabled auto-merge (squash) April 30, 2024 13:51
@TheNerdGuyLulu TheNerdGuyLulu merged commit e1df100 into main Apr 30, 2024
@TheNerdGuyLulu TheNerdGuyLulu deleted the feat/add-push-support-expo branch April 30, 2024 14:03
@josh-
Copy link
Contributor

josh- commented May 2, 2024

we're eagerly awaiting this feature! if it would be possible to release a new version with this included in the next few days that would be super appreciated 🙏

@yonitou
Copy link

yonitou commented May 2, 2024

This is Christmas :D
Just one question though : why are you asking to add this snippet to infoPlist ?


      "infoPlist": {
        "NSCameraUsageDescription": "This is just a sample text to access the Camera",
        "NSPhotoLibraryUsageDescription": "This is just a sample text to access the Photo Library"
      }

For me, we don't need it to use push notifications

@Br1an-Boyle
Copy link
Contributor

@yonitou 👋🏻
On iOS, we now have the ability to select your camera in the message composer. It uses the camera API, therefore you will need to provide the NSCameraUsageDescription in your info.plist otherwise your app will get rejected from the AppStore.
You can ignore the NSPhotoLibraryUsageDescription.

@yonitou
Copy link

yonitou commented May 3, 2024

Okay didn't know about that ! Maybe you could add it to the readme so people know why they're adding these new permissions ? (it's not always obvious :D)
Thanks

@yonitou
Copy link

yonitou commented May 3, 2024

I also notice that in this PR, you're saying that there's no "deep links support". What does that mean exactly ?

  • Can I still handle deep links contained in push notifications manually (by looking at the uri property in the push notification) ?
  • Can I still use Intercom.handlePushMessage() to open a push notification message ?
  • Can I still use IntercomAutoIntegratePushNotifications to disable automatic integration of push notifications ?

@Br1an-Boyle
Copy link
Contributor

@yonitou I'll need to get clarification on that.

@yonitou
Copy link

yonitou commented May 4, 2024

Alright :) keep me/us in touch. We'll need these infos to update to the last intercom version (we are currently stuck to v4 with the old config plugin 😅)

@TheNerdGuyLulu
Copy link
Contributor Author

Hi @yonitou,
deep link is supported with expo, though it's not yet documented how to configure it.
Using app.json / app.config.js, we need to add the necessary configurations. You can take a look here on how to configure app links for android as an example.

Also the following example creates a custom uri.

"ios": {
      "infoPlist": {
        "CFBundleURLTypes": [
          {
            "CFBundleURLSchemes": ["myapp"]
          }
        ]
      }
}

@yonitou
Copy link

yonitou commented May 6, 2024

Hi
Thanks for your answer.
My app is already configured for deep linking with expo. :)
My question was about the fact you put "Deep links are not supported yet" in your PR.
Does that mean that intercom push notifications that contain deep links won't work as excepted ? If so, how can we handle push messages for example (when having a chat between a client and an Intercom agent) ?

@nekode-dev
Copy link

nekode-dev commented May 8, 2024

Thanks for this feature, the timing on this was perfect for us and our use case! 🙌🏻

Tested on iOS and it works fantastically. However, testing on Android has proved to not be working. Taking a look at this PR, it looks like you have only implemented the config-plugin for iOS and not Android unless I am mistaken?

I have run npx expo prebuild --clean and can see the code mods have been applied for iOS but not Android to confirm the above.

Am I possibly missing something, or is Android support still to come?

Thanks!

@josh-
Copy link
Contributor

josh- commented May 10, 2024

Similar to @nekode-dev, can confirm that iOS is working great here but so far we've been unable to get push notifications working on Android.

@TheNerdGuyLulu is there anything extra we need to do in order to get Android working?

@Br1an-Boyle
Copy link
Contributor

Hi @josh- @nekode-dev 👋🏻
Thanks for your feedback about Android push. Just to let you know that we'll be picking this up next week and we will look into the problem.
Thanks for your patience.

@yonitou
Copy link

yonitou commented May 20, 2024

Hi !

@Br1an-Boyle : except the discussion happening about the Android part (which is quite important for us to use your expo plugin), did you get some clarifications about the do and don't regarding push notfications setup and deep linking (especially for people who come from the old plugin with intercom v4) ? That would be really helpful to get ready and understand what works or not !

@TheNerdGuyLulu
Copy link
Contributor Author

Hi @josh- @yonitou,

I created a new expo project from scratch. The push notifications works fine for me. For this test I enabled the notifications permission directly from the android settings, but while developing the plugin I used the react-native-permissions and also fine.

I'm happy to jump on a call to try to sort it out.

@yonitou
Copy link

yonitou commented May 21, 2024

Thanks !
I think it will be easier for @josh- to test it to confirm since he already upgraded Intercom SDK (it's not our case yet since a lot of things rely on the old version). @josh- Can you confirm that it's working?

@josh-
Copy link
Contributor

josh- commented May 27, 2024

Thanks very much for verifying and the offer to jump on a call @TheNerdGuyLulu, however since we need to support badging the app icon when receiving a notification (and this isn't supported by intercom) we've instead moved to listening to Intercom webhooks and sending our own notifications.

@yonitou
Copy link

yonitou commented May 28, 2024

So looks like that this thread can be closed if everything works as expected ? @TheNerdGuyLulu, what about deep links setup in push notifications ?

@yonitou
Copy link

yonitou commented Aug 28, 2024

Hi

I'm updating this thread because I still have questions about push notifications and deep link support and especially, the differences between the old plugin and the new one.
In the old plugin, I needed to setup everything I'm listing below and I need to know what should I keep, remove or update by installing the new one :

  • I needed a specific Android channel for notifications
Notifications.setNotificationChannelAsync("intercom_chat_replies_channel", {
					description: "Channel for intercom replies",
					importance: Notifications.AndroidImportance.MAX,
					name: "Intercom Replies Channel"
				});
  • I needed to add to my infoPlist this key to manually handle push notifications for iOS :
IntercomAutoIntegratePushNotifications: "NO"
  • I needed to manually intercept intercom notifications to handle deep links and messages manually
const payload = (lastNotificationResponse?.notification?.request?.trigger as any)?.payload;
		if (payload?.icm_cid) {
			setCurrentIntercomNotification({ data: payload?.icm_cid, type: "message" });
		}
		if (payload?.uri) {
			setCurrentIntercomNotification({ data: payload?.uri, type: "deeplink" });
		}
  • The function Intercom.handlePushMessage() was only working on Android. Not in iOS

Can I have some help/explanations about that ? I carefully read the repository documentation but I don't know if it's exhaustive or not

Thanks !

@uddish
Copy link
Contributor

uddish commented Aug 28, 2024

Hey @yonitou 👋
Did you face any issues with push notifications following what was there in our readme?
I don't think you need to take any extra steps for it to work.

@yonitou
Copy link

yonitou commented Aug 28, 2024

I was waiting for your answer before updating my plugin. I can try with your readme but I still don't understand how should I handle deep links ? Is it going to be managed by the handlePushMessage function ? Or is it going to be automatically handled ? (In my app, I need to wait for the authentication to finish to handle custom deep links, this is why I'm asking)

@uddish
Copy link
Contributor

uddish commented Aug 29, 2024

Hey @yonitou
You should be able to use deeplinks as described in the documentation here.
Can you please try adding the configuration as described above and let us know if you are facing any issue?

As for waiting for the authentication to finish, I don't think we have an interceptor method in our plugin yet but I would have to get back to you on this.

Thanks for being patient 😄

@yonitou
Copy link

yonitou commented Aug 29, 2024

Thx
Do you think that my previous setup could still work ?

const payload = (lastNotificationResponse?.notification?.request?.trigger as any)?.payload;
		if (payload?.icm_cid) {
			setCurrentIntercomNotification({ data: payload?.icm_cid, type: "message" });
		}
		if (payload?.uri) {
			setCurrentIntercomNotification({ data: payload?.uri, type: "deeplink" });
		}

I didn't use any interceptor but I blocked the notification with expo-notifications package, read the data inside and navigated manually instead. It was quite hacky but worked :D

@uddish
Copy link
Contributor

uddish commented Aug 29, 2024

Yes, I think it could but it would be best to test it out first 😄

@yonitou
Copy link

yonitou commented Aug 29, 2024

I just tried to install the new plugin following the readme :

  • The builds are working and the app is launching.
  • The Intercom.handlePushMessage doesn't work at all on Android.
  • On iOS, it's opening the message right away even if I'm not using "Intercom.handlePushMessage". This is the reason I used before IntercomAutoIntegratePushNotifications: "NO"
  • Deeplinks are correctly received on iOS & Android
  • However, they are working on iOS (even if the app is killed) but on Android, they are not working at all
  • I didn't test universal links yet

Any idea ?

PS : FYI, I have a working setup for deep links and universal links for Android & iOS with Expo & React Navigation for one year now so I don't think it's related to it.

@yonitou
Copy link

yonitou commented Aug 29, 2024

Here's what I need to do to handle push notifications & deep links the same way for Android & iOS with "@intercom/intercom-react-native": "^7.2.1":

  • Add IntercomAutoIntegratePushNotifications: "NO" in my iOS infoPlist
  • Delete all Intercom.handlePushMessage() occurrences
  • Add the snippet below in my navigation container
import { useLastNotificationResponse } from "expo-notifications";

const lastNotificationResponse = useLastNotificationResponse();

	useEffect(() => {
		if (
			status === Auth.LOGGED_IN &&
			appState === ApplicationState.ACTIVE &&
			currentIntercomNotification
		) {
			currentIntercomNotification?.type === "message"
				? Intercom.presentContent(
					IntercomContent.conversationWithConversationId(currentIntercomNotification?.data?.toString())
					)
				: setDeepLink(currentIntercomNotification.uri);
			setCurrentIntercomNotification(null);
		}
	}, [ status, appState, currentIntercomNotification]);

	useEffect(() => {
		const data =
			Platform.OS === "ios"
					lastNotificationResponse?.notification?.request?.trigger?.payload
				: lastNotificationResponse?.notification?.request?.content?.data;
		if (
			(Platform.OS === "ios" && !!data?.intercom_push_type) ||
			(Platform.OS === "android" && data?.receiver === "intercom_sdk")
		) {
			setCurrentIntercomNotification({
				type: data?.uri ? "deeplink" : "message",
				data: data?.uri || data?.icm_cid || data?.conversation_id
			});
		}
	}, [lastNotificationResponse]);

I tried on a real iOS device and on an Android simulator.
I'm quite disappointed tbh regarding this big update after 1 year of using the old plugin. Do you have better ideas @uddish ?

@yonitou
Copy link

yonitou commented Sep 9, 2024

Up :)

@raffiot
Copy link

raffiot commented Oct 1, 2024

Hello!
I'm having the same issues, everything works well on iOS but on Android my push notifications are not working.
Here is my project configuration:

// app.config.ts

{
  expo: {
    android: {
      googleServicesFile: './google-services.json',
      ...
    },
    plugins: [
      [
        '@intercom/intercom-react-native',
        {
          iosApiKey: process.env.EXPO_PUBLIC_INTERCOM_IOS_API_KEY,
          androidApiKey: process.env.EXPO_PUBLIC_INTERCOM_ANDROID_API_KEY,
          appId: process.env.EXPO_PUBLIC_INTERCOM_APP_ID,
          intercomRegion: 'US',
        },
      ],
    ]
  }
}
// package.json
{
  "dependencies": {
    "@intercom/intercom-react-native": "^7.2.1",
    "expo": "^51.0.0",
    "react-native": "0.74.5",
    ...
  }
}

Configuration in Intercom settings
image

Our setup was working previously with our own custom plugin.

@edwinw6
Copy link

edwinw6 commented Oct 16, 2024

We're running into the same issue as mentioned above by @raffiot. Notifications are working on iOS, but not on Android.

Reproducing this issue

  1. Create a fresh Expo app
    npx create-expo-app@latest
  2. Install additional packages
    npx expo install expo-notifications @intercom/intercom-react-native
  3. Add ./google-services.json file (download from firebase)
  4. Update app.json:
// app.json
{
  "expo": {
    "android": {
      "package": "com.push-test",  // <-- Make sure to use the same package in Firebase and Intercom!
      "googleServicesFile": "./google-services.json"
    },
    "plugins": [
      "expo-router",
      "expo-notifications",
      [
        "@intercom/intercom-react-native",
        {
          "appId": "XXX",
          "androidApiKey": "android_sdk-XXX",
          "iosApiKey": "ios_sdk-XXX",
          "intercomRegion": "US"
        }
      ]
    ]
  }
}
  1. Setup Intercom credentials in app.json and upload the service account key in the Intercom messenger settings. Make sure to use the correct app bundle id (com.push-test in this case).
  2. Add the Intercom plugin to the app
// app/_layout.tsx
useEffect(() => {
  if (loaded) {
    SplashScreen.hideAsync();
      
    // Add these two lines:
    Intercom.loginUnidentifiedUser();
    Intercom.setLauncherVisibility(Visibility.VISIBLE);
  }
}, [loaded]);
  1. Build and run the app on Android
  2. Start a new conversation, close the app to the background and reply from Intercom
  3. No push notification will be shown to the user

Cause of the problem

The cause of this, we've found, is in the payload of the notification that's being sent by Intercom. We were able to troubleshoot this by logging the incoming notifications:

import * as Notifications from "expo-notifications"

// Log incoming notifications while app is in the foreground:
Notifications.addNotificationReceivedListener((notification) => {
  console.log(notification)
})

Looking at these logs, we noticed the notification key is missing. Look at this example notification, sent by Intercom:

// Notification sent by Intercom (not working -- pruned for readability)
{
  "request": {
    "trigger": {
      "remoteMessage": {
        "notification": null,     // <-- Note that notification is null!
        "data": {
          "body": "Andrea: test!",
          "intercom_push_type": "notification",
          "receiver": "intercom_sdk",
          "message": "Andrea: test!",
          "message_data": "{\"type\":\"text\",\"message\":\"test!\"}",
          [...]
        },
      },
      "channelId": null,
      "type": "push"
    },
    [...]
    },
    "identifier": "."
  },
  "date": 1728994080388
}

We found the notification is null. Other notifications that work fine (originating from Expo), we see that the notification key is set:

// Notification sent by Expo (working -- pruned for readability)
{
  "request": {
    "trigger": {
      "remoteMessage": {
        "notification": {
          "title": "test",
          "body": "test message",   //  <-- In this case the title and body are repeated in the notification object
          [...]
        },
        "data": {
          "message": "test message",
          "title": "test",
        },
        [...]
      },
      "channelId": null,
      "type": "push"
    },
    [...]
  },
  "date": 1728993752955
}

Solution

From our investigation we found that the notifications sent from Intercom (specifically for Android) are sent as data-only notifications. These will be delivered silently. For this to work as expected, Intercom will need to make a change in their backend in order to send notification-type notifications. This can be simply done by repeating the content (body) inside of the notification object.

Pinging @Br1an-Boyle @uddish: Could you confirm this is indeed an issue? And if so, chance you can bring this up internally?

Further reading:

@raffiot
Copy link

raffiot commented Oct 21, 2024

Thanks a lot @edwinw6 for this awesome message digging into it! 🤩

I shared it with the customer support and this is their response

I’ve heard back from our team and can confirm that we’re adding this issue to our backlog.
For greater context, our product team prioritizes bugs based on the severity of the issue and how widespread of an experience it is with customers. To provide insight on expectations, issues like this may not be actioned for some weeks.
This timeline is based on the team's current existing log of issues and upcoming feature releases which is subject to change.

So I imagine we won't hear from them for some time for such an important feature as push notification... I'll let you know when I have more informations from them.

@edwinw6
Copy link

edwinw6 commented Oct 29, 2024

Great! Perhaps if we all raise this issue with their customer support, we can get this prioritised.

@yonitou
Copy link

yonitou commented Oct 29, 2024

Hey
I don't know how is that possible but with the snippets & the setup I shared above, the notifications are working on Android (I'm handling them manually though) but the notifications are showing up on the device which means they are not data-only. What kind of notifications did you send in your tests ?

@olarra
Copy link

olarra commented Jan 23, 2025

I face the same issue with push notifications on Android. The problem occurs when the app is in a quit state; the notification is not shown at all. In the background state, notifications are caught by firebase.messaging().onMessage, but when the app is closed, nothing happens.

From the adb logs, I see this error:

W ActivityManager: Background start not allowed: service Intent { cmp=xxx.xxx.app.dev/io.invertase.firebase.messaging.ReactNativeFirebaseMessagingHeadlessService (has extras) } to xxx.xxx.app.dev/io.invertase.firebase.messaging.ReactNativeFirebaseMessagingHeadlessService from pid=9775 uid=10211 pkg=xxx.xxx.app.dev startFg?=false

This seems related to Android's restrictions on starting background services. T

@olarra
Copy link

olarra commented Jan 23, 2025

Thanks a lot @edwinw6 for this awesome message digging into it! 🤩

I shared it with the customer support and this is their response

I’ve heard back from our team and can confirm that we’re adding this issue to our backlog.
For greater context, our product team prioritizes bugs based on the severity of the issue and how widespread of an experience it is with customers. To provide insight on expectations, issues like this may not be actioned for some weeks.
This timeline is based on the team's current existing log of issues and upcoming feature releases which is subject to change.

So I imagine we won't hear from them for some time for such an important feature as push notification... I'll let you know when I have more informations from them.

Hello @raffiot have you had any update about this issue since the last time?

@Splanis
Copy link

Splanis commented Feb 6, 2025

hi any updates on this?

@olarra
Copy link

olarra commented Feb 27, 2025

Hello @edwinw6,

Have you been able to find a solution to get push notifications working on Android when the app is in a quit state?

From my side, I’ve been in contact with Intercom support, but I’m not sure they understood that the issue doesn’t seem to be with the SDK for Expo itself, but rather with the content of the push notifications.

I’m also quite surprised that this issue hasn’t gained more traction—it feels rather silent. I wonder if it’s working properly for other people using Expo.

Let me know if you’ve made any progress!

Best regards,

@edwinw6
Copy link

edwinw6 commented Feb 28, 2025

Hey @olarra,

We have not been able to find a reliable workaround that also works when the app is in a quit state. I've asked Intercom support for an update on this, hoping that they'll be able to prioritise this issue.

If anyone is able to make this work on Android reliably, we'd love to hear!

@damiaanh
Copy link

For me, the package does not handle deeplinks correctly for mobile push notifications on iOS using Expo. The added deeplink is not triggered and the app is opened but does not navigate to the link.

I do receive the notifications.

I can confirm that the PN object contains the deeplink as uri in response?.notification.request.trigger?.payload?.uri with:

import * as Notifications from "expo-notifications";
const response = await Notifications.getLastNotificationResponseAsync();
console.log(response);

I have set up as described:

      LSApplicationQueriesSchemes: ["myapp"],
      IntercomUniversalLinkDomains: ["www.myapp.com"],

and have a working (deep) linking setup that I can test with npx uri-scheme.

For now, I do have a working workaround with a custom hook that listens to incoming push notifications (or gets the last one on cold boot) and opens the url:

import * as Linking from "expo-linking";
import * as Notifications from "expo-notifications";

 // Handle notifications while the app is in background/foreground
    const subscription = Notifications.addNotificationResponseReceivedListener(
      (response) => {
        const uri = response.notification.request.trigger?.payload?.uri;

        if (uri && typeof uri === "string") {
          console.log("Navigating to deep link:", uri);
          void Linking.openURL(uri);
        }
      },
    );

I would however expect that my changes in app.config.ts would be enough for the intercom-react-native package to handle deeplinks, as described.

Note also how intercom documentation mentions that push notifications are not yet supported by this package 🤷

Does anyone else experience this issue? Or did anyone had this issue but managed to fix it using the changes in app.config.ts? Curious to hear from you!

@yonitou
Copy link

yonitou commented Sep 11, 2025

@uddish do you know if the push notifications and deep links issue has been resolved for the Expo Plugin in the New architecture ?

@robwalkerco
Copy link

@yonitou and anyone else trying to get Push Notifications working well on Android with Expo - I've opened a ticket on the community support site at https://community.intercom.com/mobile-sdks-24/android-push-notification-handling-in-expo-expo-notifications-12797 👀

Rosie-Kennelly-1 added a commit that referenced this pull request Mar 5, 2026
The Expo config plugin already automated iOS push notification setup
(PR #191) but Android was left out, requiring developers to manually
create a FirebaseMessagingService and edit native files — defeating
the purpose of using Expo.

This adds the Android counterpart: a config plugin that generates a
Kotlin FirebaseMessagingService at prebuild time, registers it in the
AndroidManifest, and routes Intercom pushes to the SDK while passing
non-Intercom messages through to other handlers (e.g. expo-notifications).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.