[π] Duplicate FCM messages delivered after app process restart on Android
Issue
I'm experiencing an issue where FCM messages get duplicated after my Android app process gets killed and restarted. When using data-only FCM messages, I'm seeing all previously processed messages getting re-delivered along with new ones.
Expected: Each FCM message should only be delivered once to setBackgroundMessageHandler.
What's happening: After the app process restarts, I get all previous messages again plus the new message that triggered the restart. Even though my handler returns Promise.resolve() properly.
How to reproduce:
- Set up
setBackgroundMessageHandlerwith data-only FCM messages - Receive a few messages normally (this works fine)
- Kill the app process (either manually or let Android do it)
- Send another FCM message
- Watch all the old messages come back along with the new one
What I can see in the logs:
- Same message IDs getting delivered again
- All messages hit my handler within the same millisecond
- Takes about 100ms for ExpoModulesCore to initialize after process start
- This only happens when the process actually dies, not just backgrounding
// Basic setup in index.js
import messaging from '@react-native-firebase/messaging';
messaging().setBackgroundMessageHandler(async remoteMessage => {
console.log('π± Background message received:', remoteMessage?.messageId);
if (!remoteMessage.notification && remoteMessage.data) {
try {
// Handle data-only message with Notifee
console.log('β
Message processed successfully');
return Promise.resolve();
} catch (error) {
console.error('β Error handling message:', error);
return Promise.reject(error);
}
}
return Promise.resolve();
});
Project Files
Javascript
Click To Expand
package.json:
{
"dependencies": {
"@react-native-firebase/app": "22.2.0",
"@react-native-firebase/messaging": "22.2.0",
"@notifee/react-native": "9.1.8",
"expo": "~53.0.0",
"react-native": "0.77.x"
}
}
firebase.json for react-native-firebase v6:
# Using v22.2.0
iOS
Click To Expand
ios/Podfile:
- [ ] I'm not using Pods
- [x] I'm using Pods and my Podfile looks like:
# Standard Expo managed workflow setup
AppDelegate.m:
// Standard Expo managed workflow setup
Android
Click To Expand
Have you converted to AndroidX?
- [x] my application is an AndroidX application?
- [x] I am using
android/gradle.propertiesjetifier=truefor Android compatibility? - [ ] I am using the NPM package
jetifierfor react-native compatibility?
android/build.gradle:
// Standard Expo managed workflow setup
android/app/build.gradle:
// Standard Expo managed workflow setup
android/settings.gradle:
// Standard Expo managed workflow setup
MainApplication.java:
// Standard Expo managed workflow setup
AndroidManifest.xml:
<!-- Standard Expo managed workflow setup with FCM permissions -->
Environment
Click To Expand
react-native info output:
React Native Environment Info:
System:
OS: macOS 14.x
CPU: (x) arm64
Binaries:
Node: 18.x.x
Yarn: 1.x.x
npm: 9.x.x
Watchman: 2023.x.x
SDKs:
iOS SDK:
Platforms: iOS 17.x, DriverKit 23.x, macOS 14.x, tvOS 17.x, watchOS 10.x
Android SDK:
API Levels: 28, 29, 30, 31, 32, 33, 34
Build Tools: 30.0.3, 31.0.0, 33.0.0, 34.0.0
System Images: android-31 | Google APIs ARM 64 v8a, android-34 | Google APIs ARM 64 v8a
IDEs:
Android Studio: 2024.x.x
Xcode: 15.x.x
Languages:
Java: 17.x.x
Ruby: 2.x.x
-
Platform that you're experiencing the issue on:
- [ ] iOS
- [ ] Android
- [ ] iOS but have not tested behavior on Android
- [x] Android but have not tested behavior on iOS
- [ ] Both
-
react-native-firebaseversion you're using that has this issue:-
22.2.0
-
-
Firebasemodule(s) you're using that has the issue:-
@react-native-firebase/messaging
-
-
Are you using
TypeScript?-
Y&5.x
-
Detailed log evidence from adb logcat:
# Process 14848 - Normal message processing over time
948|19:39:37.318 14848 14885 I ReactNativeJS: 'π± Background/Kill Message received (index.js):', '0:1755859176456941%c8c2fb28f9fd7ecd'
951|19:39:47.246 14848 14885 I ReactNativeJS: 'π± Background/Kill Message received (index.js):', '0:1755859186737605%c8c2fb28f9fd7ecd'
954|19:39:49.483 14848 14885 I ReactNativeJS: 'π± Background/Kill Message received (index.js):', '0:1755859189022312%c8c2fb28f9fd7ecd'
961|19:40:01.939 14848 14885 I ReactNativeJS: 'π± Background/Kill Message received (index.js):', '0:1755859201550987%c8c2fb28f9fd7ecd'
963|19:40:03.637 14848 14885 I ReactNativeJS: 'π± Background/Kill Message received (index.js):', '0:1755859203272299%c8c2fb28f9fd7ecd'
965|19:40:03.890 14848 14885 I ReactNativeJS: 'π± Background/Kill Message received (index.js):', '0:1755859203539048%c8c2fb28f9fd7ecd'
967|19:40:04.185 14848 14885 I ReactNativeJS: 'π± Background/Kill Message received (index.js):', '0:1755859203854927%c8c2fb28f9fd7ecd'
# Process killed (14848) β New process started (15260)
969|19:40:12.863 15260 15292 I ExpoModulesCore: β
AppContext was initialized
970|19:40:13.060 15260 15293 I ExpoModulesCore: β
JSI interop was installed
971|19:40:13.062 15260 15293 I ExpoModulesCore: β
Constants were exported
# ALL previous messages re-delivered simultaneously!
972|19:40:13.160 15260 15293 I ReactNativeJS: 'π± Background/Kill Message received (index.js):', '0:1755859176456941%c8c2fb28f9fd7ecd'
973|19:40:13.161 15260 15293 I ReactNativeJS: 'π± Background/Kill Message received (index.js):', '0:1755859186737605%c8c2fb28f9fd7ecd'
974|19:40:13.161 15260 15293 I ReactNativeJS: 'π± Background/Kill Message received (index.js):', '0:1755859189022312%c8c2fb28f9fd7ecd'
975|19:40:13.161 15260 15293 I ReactNativeJS: 'π± Background/Kill Message received (index.js):', '0:1755859201550987%c8c2fb28f9fd7ecd'
976|19:40:13.162 15260 15293 I ReactNativeJS: 'π± Background/Kill Message received (index.js):', '0:1755859203272299%c8c2fb28f9fd7ecd'
977|19:40:13.162 15260 15293 I ReactNativeJS: 'π± Background/Kill Message received (index.js):', '0:1755859203539048%c8c2fb28f9fd7ecd'
978|19:40:13.162 15260 15293 I ReactNativeJS: 'π± Background/Kill Message received (index.js):', '0:1755859203854927%c8c2fb28f9fd7ecd'
# Multiple duplicate processing (all within same millisecond)
979|19:40:13.183 15260 15293 I ReactNativeJS: β
Message processed successfully
980|19:40:13.185 15260 15293 I ReactNativeJS: β
Message processed successfully
982|19:40:13.188 15260 15293 I ReactNativeJS: β
Message processed successfully
986|19:40:13.194 15260 15293 I ReactNativeJS: β
Message processed successfully
987|19:40:13.195 15260 15293 I ReactNativeJS: β
Message processed successfully
988|19:40:13.195 15260 15293 I ReactNativeJS: β
Message processed successfully
989|19:40:13.195 15260 15293 I ReactNativeJS: β
Message processed successfully
What seems to be happening:
From what I can see in the logs, it looks like:
- Android kills my app process
- New FCM message comes in and wakes up the app
- JavaScript takes ~100ms to initialize (ExpoModulesCore setup, JSI bridge, etc.)
- Once JS is ready, FCM dumps all the old messages plus the new one
- My handler processes the same message IDs multiple times
Some observations:
- Only happens when the process actually dies (not normal backgrounding)
- Same message IDs show up again, so definitely duplicates
- Foreground messaging works fine, no duplicates there
- All the re-delivered messages come in at exactly the same time
- JS engine needs about 100ms to get ready after process start
Questions:
- Is this a known issue with React Native Firebase messaging?
- Any way to register the background handler earlier at the native level?
- What's the recommended approach for handling this?
- π Check out
React Native FirebaseandInvertaseon Twitter for updates on the library.
Hi there, please use the modular API and setBackgroundMessageHandler like this:
setBackgroundMessageHandler(messaging, async remoteMessage => {
console.log('π© Background FCM Message:', remoteMessage);
});
Does the issue persist after doing it like so?
@MichaelVerdon Iβm experiencing the same issue. I also tried using the modular API with setBackgroundMessageHandler exactly as you suggested, but the problem persists β old notifications are still being delivered after the app is restarted.
I'm also seeing the same issue with "@react-native-firebase/app": "^23.1.2", "@react-native-firebase/messaging": "^23.1.2",
I'm getting the same message in the background messages for multiple times. ( when the app is open/background or in restart )
Here's my code:
import { registerRootComponent } from "expo";
import { NativeModules, Platform } from "react-native";
import {
getMessaging,
setBackgroundMessageHandler,
} from "@react-native-firebase/messaging";
import type { FirebaseMessagingTypes } from "@react-native-firebase/messaging";
import App from "./App";
// Background message handler for Firebase (when app is killed or backgrounded)
// This must be set at module level, outside of any component
if (Platform.OS == "android") {
console.log("π§ Setting up Firebase background message handler...");
try {
const messagingInstance = getMessaging();
setBackgroundMessageHandler(
messagingInstance,
async (remoteMessage: FirebaseMessagingTypes.RemoteMessage) => {
console.log("π± FCM background message received:", remoteMessage);
// Handle high priority data messages for calls
if (!remoteMessage.data) {
console.log("π± Background: No data in message, ignoring");
return;
}
const isCallMessage = remoteMessage.data?.type === "incoming_call";
if (!isCallMessage) {
console.log("π± Background: Non-call message, ignoring");
return;
}
const messageId = remoteMessage.messageId;
console.log(
`π± Background: Received call message with messageId ${messageId}`
);
}
);
console.log("β
Firebase messaging background handler set up successfully");
//
} catch (error) {
console.warn(
"β οΈ Firebase not initialized yet, background handler will be set up later:",
error
);
}
}
// registerRootComponent calls AppRegistry.registerComponent('YourAppName', () => App);
// It also ensures that whether you load the app in Expo Go or in a standalone app,
// the environment is set up appropriately
registerRootComponent(App);
@MichaelVerdon Thanks for the suggestion. I switched to the modular API and registered setBackgroundMessageHandler at the global entry, but the issue still persists. Any additional steps or workarounds I could try?
Hi there, using my expo test project I have not been able to reproduce this. when I restart the application I do not receive my notifications again. It seems to work as expected for me. Would you be able to send a repo I could clone and try out?
Hello π, to help manage issues we automatically close stale issues.
This issue has been automatically marked as stale because it has not had activity for quite some time.Has this issue been fixed, or does it still require attention?
This issue will be closed in 15 days if no further activity occurs.
Thank you for your contributions.
Hey, i'm experiencing exactly the same issue as OP here, with Expo 54, RN 0.81.4 and Firebase 23.4. When process gets started by new notification from killed state, background handler receives previous, already handled, notifications. I'm using modular API.
EDIT: Seems like the issue is only happening with New Architecture enabled. Can't reproduce it with Old Architecture.
Same here with Expo 54, RN 0.81.4 and Firebase 23.4, with high priority data messages when received background messages and opening the app later (even killing it with adb).
I've been doing several tests adding logs for the life cycle of the ReactNativeFirebaseMessagingHeadlessService.java and I see that service is not finished when resolving the promise of the function passed to setBackgroundMessageHandler (I don't know if this is the normal behaviour). Could it be a react-native bug not finishing the headless task when the promise is resolved?
We are using the following versions and facing the same issue. Most of the messages received before are calling callback repeatedly.
- "react-native": "0.79.4"
- "@react-native-firebase/messaging": "^22.2.0"
- "expo": "53.0.13"
I'm having the same issue
"react-native": "0.80.2",
"@react-native-firebase/messaging": "^23.1.0",
Android: 13
Hello π, to help manage issues we automatically close stale issues.
This issue has been automatically marked as stale because it has not had activity for quite some time.Has this issue been fixed, or does it still require attention?
This issue will be closed in 15 days if no further activity occurs.
Thank you for your contributions.
Hello @MichaelVerdon ,
Iβm experiencing the same issue and have prepared a sample app along with a recording for reference.
https://github.com/user-attachments/assets/b9f4958d-0419-4070-a1a3-ebe2fcde879d
Environment Details The sample app uses the latest versions of react-native-firebase with the modular API and new architecture enabled:
"dependencies": {
"react": "19.2.0",
"react-native": "0.83.0",
"@react-native/new-app-screen": "0.83.0",
"react-native-safe-area-context": "^5.5.2",
"@notifee/react-native": "^9.1.8",
"@react-native-firebase/app": "^23.7.0",
"@react-native-firebase/messaging": "^23.7.0"
}
Steps to Reproduce
- Set up setBackgroundMessageHandler with data-only FCM messages.
- Receive a few messages normally (works fine).
- Kill the app process (either manually or let Android do it).
- Send another FCM message.
- Observe that all old messages come back along with the new one i.e setBackgroundMessageHandler is called with the previous notification delivered.
Observed Behaviour
- Same message IDs are delivered again.
- All messages hit the handler within the same millisecond.
- This only occurs when the process actually dies, not just when backgrounded.
Testing Details
Created a sample Firebase project in my personal account. Sent data messages directly from the Firebase Console.
The sample app:
- Uses the latest Firebase libraries with new architecture enabled.
- Implements modular API (no warning logs in console or app logs).
- Leverages Notifee for local notifications when the app is in background, foreground, or closed.
Recording & Source Code
- Attached recording demonstrating the issue.
- Attached sample app source code for your review.
Recording highlights:
- When the app is closed, and a notification is sent, setBackgroundMessageHandler is triggered with older notifications, resulting in multiple notifications appearing in the notification bar.
- Console logs show setBackgroundMessageHandler called multiple times for each notification.
- When the app is opened from a notification β then closed again, all notifications are cleared, confirming the issue.
Please review the sample code and let us know if thereβs anything incorrect in our implementation that could be causing this issue.
Iβm happy to provide additional details or logs if needed.
Thanks for your time and support! π