Issue
🔥 [Android] OOM Crash due to excessive notification storage in SharedPreferences (ReactNativeFirebaseMessagingStoreImpl)
We are encountering java.lang.OutOfMemoryError on Android devices.
The root cause is that ReactNativeFirebaseMessagingStoreImpl stores up to 100 notifications in SharedPreferences by default.
When the app receives many notifications with large payloads, the SharedPreferences file becomes too large. Since SharedPreferences loads the entire file into memory, this leads to OOM crashes, especially on devices with limited heap memory.
Stack Trace:
java.lang.OutOfMemoryError: Failed to allocate a 24 byte allocation with 425280 free bytes and 415KB until OOM...
at java.util.HashMap.newNode(HashMap.java:1907)
at java.util.HashMap.putVal(HashMap.java:636)
at java.util.HashMap.putMapEntries(HashMap.java:521)
at java.util.HashMap.<init>(HashMap.java:491)
at android.app.SharedPreferencesImpl$EditorImpl.commitToMemory(SharedPreferencesImpl.java:539)
at android.app.SharedPreferencesImpl$EditorImpl.apply(SharedPreferencesImpl.java:486)
at io.invertase.firebase.common.UniversalFirebasePreferences.setStringValue(UniversalFirebasePreferences.java:66)
at io.invertase.firebase.messaging.ReactNativeFirebaseMessagingStoreImpl.storeFirebaseMessage(ReactNativeFirebaseMessagingStoreImpl.java:43)
Analysis:
The ReactNativeFirebaseMessagingStoreImpl.java has a constant MAX_SIZE_NOTIFICATIONS = 100.
Every time a notification is received (whether in foreground or background), it is stored in SharedPreferences.
If the notification data is large, storing 100 entries can easily exceed the available heap size during the SharedPreferences load/commit process.
Proposed Solution & Fix:
We have successfully patched the library locally with the following changes:
- Reduce the default limit: 100 seems excessive. We reduced it to 20.
- Make it configurable: Added support for
rn_firebase_messaging_max_stored_notifications in AndroidManifest.xml.
- Safety Cap: Even if configured higher, we capped the limit at 100 to prevent OOM.
- Improve cleanup logic: Changed
if to while loop to aggressively clean up excess notifications.
Example Patch Code:
// In ReactNativeFirebaseMessagingStoreImpl.java
private static int MAX_SIZE_NOTIFICATIONS = 20; // Default reduced to 20
private static boolean isInitialized = false;
private int getMaxNotificationSize() {
if (isInitialized) return MAX_SIZE_NOTIFICATIONS;
try {
Context context = ReactNativeFirebaseApp.getApplicationContext();
ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
if (appInfo.metaData != null) {
int configValue = appInfo.metaData.getInt("rn_firebase_messaging_max_stored_notifications", 20);
// Safety cap: never exceed 100 to prevent OOM
MAX_SIZE_NOTIFICATIONS = Math.min(configValue, 100);
}
} catch (Exception e) {
// Ignore
}
isInitialized = true;
return MAX_SIZE_NOTIFICATIONS;
}
@Override
public void storeFirebaseMessage(RemoteMessage remoteMessage) {
// ...
// check and remove old notifications message
List<String> allNotificationList = convertToArray(notifications);
// Changed 'if' to 'while' for aggressive cleanup
while (allNotificationList.size() > getMaxNotificationSize()) {
String firstRemoteMessageId = allNotificationList.get(0);
preferences.remove(firstRemoteMessageId);
notifications = removeRemoteMessage(firstRemoteMessageId, notifications);
allNotificationList.remove(0);
}
// ...
}
Project Files
Javascript
Click To Expand
package.json:
{
"dependencies": {
"react-native": "0.81.5",
"@react-native-firebase/app": "21.7.1",
"@react-native-firebase/messaging": "21.7.1"
}
}
firebase.json for react-native-firebase v6:
iOS
Click To Expand
ios/Podfile:
AppDelegate.m:
Android
Click To Expand
Have you converted to AndroidX?
android/build.gradle:
android/app/build.gradle:
android/settings.gradle:
MainApplication.java:
AndroidManifest.xml:
<!-- We added this configuration to solve the issue -->
<meta-data
android:name="rn_firebase_messaging_max_stored_notifications"
android:value="20" />
Environment
Click To Expand
react-native info output:
System:
OS: macOS
Binaries:
Node: 20.x
Yarn: N/A
npm: 10.x
Watchman: Yes
SDKs:
iOS SDK:
Platforms: iOS
Android SDK:
API Levels: 34
IDEs:
Android Studio: Yes
Xcode: Yes
Languages:
Java: 17
Python: N/A
npmPackages:
@react-native-community/cli: Not Found
react: 18.3.1
react-native: 0.81.5
- Platform that you're experiencing the issue on:
react-native-firebase version you're using that has this issue:
Firebase module(s) you're using that has the issue:
- Are you using
TypeScript?
Issue
🔥 [Android] OOM Crash due to excessive notification storage in SharedPreferences (ReactNativeFirebaseMessagingStoreImpl)
We are encountering
java.lang.OutOfMemoryErroron Android devices.The root cause is that
ReactNativeFirebaseMessagingStoreImplstores up to 100 notifications inSharedPreferencesby default.When the app receives many notifications with large payloads, the
SharedPreferencesfile becomes too large. SinceSharedPreferencesloads the entire file into memory, this leads to OOM crashes, especially on devices with limited heap memory.Stack Trace:
Analysis:
The
ReactNativeFirebaseMessagingStoreImpl.javahas a constantMAX_SIZE_NOTIFICATIONS = 100.Every time a notification is received (whether in foreground or background), it is stored in SharedPreferences.
If the notification data is large, storing 100 entries can easily exceed the available heap size during the
SharedPreferencesload/commit process.Proposed Solution & Fix:
We have successfully patched the library locally with the following changes:
rn_firebase_messaging_max_stored_notificationsinAndroidManifest.xml.iftowhileloop to aggressively clean up excess notifications.Example Patch Code:
Project Files
Javascript
Click To Expand
package.json:{ "dependencies": { "react-native": "0.81.5", "@react-native-firebase/app": "21.7.1", "@react-native-firebase/messaging": "21.7.1" } }firebase.jsonfor react-native-firebase v6:# N/AiOS
Click To Expand
ios/Podfile:# N/AAppDelegate.m:// N/AAndroid
Click To Expand
Have you converted to AndroidX?
android/gradle.settingsjetifier=truefor Android compatibility?jetifierfor react-native compatibility?android/build.gradle:// N/Aandroid/app/build.gradle:// N/Aandroid/settings.gradle:// N/AMainApplication.java:// N/AAndroidManifest.xml:Environment
Click To Expand
react-native infooutput:react-native-firebaseversion you're using that has this issue:21.7.1Firebasemodule(s) you're using that has the issue:MessagingTypeScript?Y