55import static io .invertase .firebase .messaging .ReactNativeFirebaseMessagingSerializer .remoteMessageFromReadableMap ;
66import static io .invertase .firebase .messaging .ReactNativeFirebaseMessagingSerializer .remoteMessageToWritableMap ;
77
8+ import android .content .Context ;
9+ import android .content .pm .ApplicationInfo ;
10+ import android .content .pm .PackageManager ;
811import com .facebook .react .bridge .ReadableMap ;
912import com .facebook .react .bridge .WritableMap ;
1013import com .google .firebase .messaging .RemoteMessage ;
1720
1821public class ReactNativeFirebaseMessagingStoreImpl implements ReactNativeFirebaseMessagingStore {
1922
23+ private static final String KEY_MAX_STORED_NOTIFICATIONS = "rn_firebase_messaging_max_stored_notifications" ;
2024 private static final String S_KEY_ALL_NOTIFICATION_IDS = "all_notification_ids" ;
21- private static final int MAX_SIZE_NOTIFICATIONS = 100 ;
2225 private final String DELIMITER = "," ;
26+ private static final int DEFAULT_MAX_SIZE_NOTIFICATIONS = 100 ;
27+ private static int MAX_SIZE_NOTIFICATIONS = DEFAULT_MAX_SIZE_NOTIFICATIONS ;
28+ private static boolean isInitialized = false ;
29+
30+ private int getMaxNotificationSize () {
31+ if (isInitialized ) return MAX_SIZE_NOTIFICATIONS ;
32+
33+ int maxSize = DEFAULT_MAX_SIZE_NOTIFICATIONS ;
34+ ReactNativeFirebaseJSON json = ReactNativeFirebaseJSON .getSharedInstance ();
35+ ReactNativeFirebaseMeta meta = ReactNativeFirebaseMeta .getSharedInstance ();
36+ ReactNativeFirebasePreferences prefs = ReactNativeFirebasePreferences .getSharedInstance ();
37+
38+ try {
39+ // Priority: SharedPreferences -> firebase.json -> AndroidManifest
40+ // Note: ReactNativeFirebaseMeta doesn't have getIntValue, so we check meta.contains
41+ // and read from AndroidManifest directly if needed
42+ if (prefs .contains (KEY_MAX_STORED_NOTIFICATIONS )) {
43+ maxSize = prefs .getIntValue (KEY_MAX_STORED_NOTIFICATIONS , DEFAULT_MAX_SIZE_NOTIFICATIONS );
44+ } else if (json .contains (KEY_MAX_STORED_NOTIFICATIONS )) {
45+ maxSize = json .getIntValue (KEY_MAX_STORED_NOTIFICATIONS , DEFAULT_MAX_SIZE_NOTIFICATIONS );
46+ } else if (meta .contains (KEY_MAX_STORED_NOTIFICATIONS )) {
47+ // ReactNativeFirebaseMeta uses rnfirebase_ prefix, but we want to read the raw key
48+ // So we read directly from AndroidManifest using the key as-is
49+ try {
50+ Context context = io .invertase .firebase .app .ReactNativeFirebaseApp .getApplicationContext ();
51+ ApplicationInfo appInfo = context .getPackageManager ()
52+ .getApplicationInfo (context .getPackageName (), PackageManager .GET_META_DATA );
53+ if (appInfo != null && appInfo .metaData != null ) {
54+ maxSize = appInfo .metaData .getInt (KEY_MAX_STORED_NOTIFICATIONS , DEFAULT_MAX_SIZE_NOTIFICATIONS );
55+ }
56+ } catch (Exception e ) {
57+ // Ignore and use default
58+ }
59+ }
60+
61+ // Safety cap: prevent values > 100 to avoid re-introducing OOM risk
62+ MAX_SIZE_NOTIFICATIONS = Math .min (maxSize , DEFAULT_MAX_SIZE_NOTIFICATIONS );
63+ } catch (Exception e ) {
64+ // Ignore and use default
65+ MAX_SIZE_NOTIFICATIONS = DEFAULT_MAX_SIZE_NOTIFICATIONS ;
66+ }
67+
68+ isInitialized = true ;
69+ return MAX_SIZE_NOTIFICATIONS ;
70+ }
2371
2472 @ Override
2573 public void storeFirebaseMessage (RemoteMessage remoteMessage ) {
@@ -32,7 +80,7 @@ public void storeFirebaseMessage(RemoteMessage remoteMessage) {
3280 // remove old notifications message before store to free space as needed
3381 String notificationIds = preferences .getStringValue (S_KEY_ALL_NOTIFICATION_IDS , "" );
3482 List <String > allNotificationList = convertToArray (notificationIds );
35- while (allNotificationList .size () > MAX_SIZE_NOTIFICATIONS - 1 ) {
83+ while (allNotificationList .size () > getMaxNotificationSize () - 1 ) {
3684 clearFirebaseMessage (allNotificationList .get (0 ));
3785 allNotificationList .remove (0 );
3886 }
0 commit comments