Repository: firebase/firebase-ios-sdk (language: cpp)

Issue:
FIAM Crashing App
### Description

Please bear with me as I'm not an "expert" bug poster. This issue started happening as soon as I upgraded from Firebase version 10.17.0 to 10.24.0. It also manifests in version 10.25.0

The issue is that my app crashes as soon as it's launched when it tries to display a modal FIAM message. I don't know if the modality has anything to do with things. From some Google searches, it looks like a similar issue may have existed before related to "bundles".

Stack trace from XCode 15.2 (from @implementation FIRIAMDefaultDisplayImpl)

```
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[2]'
*** First throw call stack:
(
	0   CoreFoundation                      0x00007ff80049b761 __exceptionPreprocess + 242
	1   libobjc.A.dylib                     0x00007ff800063904 objc_exception_throw + 48
	2   CoreFoundation                      0x00007ff80038244d -[__NSPlaceholderArray initWithObjects:count:] + 482
	3   CoreFoundation                      0x00007ff800486947 +[NSArray arrayWithObjects:count:] + 40
	4   ****My App*****                    0x000000010e4bf1e4 __49+[FIRIAMDefaultDisplayImpl getViewResourceBundle]_block_invoke + 1540
	5   libdispatch.dylib                   0x00007ff800157d3a _dispatch_client_callout + 8
	6   libdispatch.dylib                   0x00007ff8001590f3 _dispatch_once_callout + 20
	7    ****My App*****                     0x000000010e4beb13 +[FIRIAMDefaultDisplayImpl getViewResourceBundle] + 947
	8    ****My App*****                     0x000000010e4c15a6 __82+[FIRIAMDefaultDisplayImpl displayModalViewWithMessageDefinition:displayDelegate:]_block_invoke + 566
	9   libclang_rt.asan_iossim_dynamic.dyl 0x0000000114e1109c __wrap_dispatch_async_block_invoke + 204
	10  libdispatch.dylib                   0x00007ff800156a90 _dispatch_call_block_and_release + 12
	11  libdispatch.dylib                   0x00007ff800157d3a _dispatch_client_callout + 8
	12  libdispatch.dylib                   0x00007ff800166ac0 _dispatch_main_queue_drain + 1420
	13  libdispatch.dylib                   0x00007ff800166526 _dispatch_main_queue_callback_4CF + 31
	14  CoreFoundation                      0x00007ff8003f7dc4 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
	15  CoreFoundation                      0x00007ff8003f26ff __CFRunLoopRun + 2463
	16  CoreFoundation                      0x00007ff8003f197d CFRunLoopRunSpecific + 557
	17  GraphicsServices                    0x00007ff80fe9d08f GSEventRunModal + 137
	18  UIKitCore                           0x00007ff805bbb53d -[UIApplication _run] + 972
	19  UIKitCore                           0x00007ff805bbffab UIApplicationMain + 123
	20   ****My App*****                    0x000000010c07ebbf main + 63
	21  dyld                                0x0000000113d733e0 start_sim + 10
	22  ???                                 0x00000001174e9386 0x0 + 4685992838
)
```

Screenshot of code from XCode:
<img width="1753" alt="Screenshot 2024-05-01 at 6 13 22 PM" src="https://github.com/firebase/firebase-ios-sdk/assets/59775247/727218bd-ff61-4594-90be-a6e3daee15fe">




### Reproducing the issue

I can reproduce it in my app by simply triggering an in-app message. 

### Firebase SDK Version

10.24 or earlier

### Xcode Version

15.2

### Installation Method

Swift Package Manager

### Firebase Product(s)

In-App Messaging

### Targeted Platforms

iOS

### Relevant Log Output

_No response_

### If using Swift Package Manager, the project's Package.resolved

<!--- Look below for instructions on how to share your Package.resolved. --->

<details>
<summary>Expand <code>Package.resolved</code> snippet</summary>
<br>

```json

Replace this line with the contents of your Package.resolved.

```

</details>


### If using CocoaPods, the project's Podfile.lock

<!--- Look below for instructions on how to share your Podfile.lock. --->

<details>
<summary>Expand <code>Podfile.lock</code> snippet</summary>
<br>

```yml

Replace this line with the contents of your Podfile.lock!

```

</details>



Discussion / hints:
I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.
Thank you. I'll provide any information you may need. I'm sure my "approach" to getting to that FIAM trigger and how I manage views at start up are probably part of the problem. 
Thanks for reporting this, @RiverboatGambler. I was able to reproduce the same issue. With this, I'll be raising this to our engineers and see what we can do here.
Thanks for the report, @RiverboatGambler. This could be related to some recent changes in that class. 
I won't lie - I'm relieved because when it comes to stuff like this because I'm not great at triage. Thanks for all you do!
Can confirm massive uptick, i use foreground ATT-Preroll and "newer version available" nudges. I just stopped the long running campaigns, just to see if I can prevent that code path from running via server side (temporarily killing the IAM campaign). 

@rizafran @ncooke3  if you want a permalink to full trace lmk and i can email/dm, but i'm guessing you don't need if you were able to repro

> unhandled *** -[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[2]

```swift
//__49+[FIRIAMDefaultDisplayImpl getViewResourceBundle]_block_invoke (FIRIAMDefaultDisplayImpl.m:70)
#endif  // SWIFT_PACKAGE
    NSBundle *containingBundle;
    NSURL *bundleURL;
    // The containing bundle is different whether FIAM is statically or dynamically linked.
    for (containingBundle in @[
           // Statically linked.
           [NSBundle mainBundle],
           // Dynamically linked.
           [NSBundle bundleForClass:myClass],
           // Embedded static framework (zip distribution).
```
Is there any update related to this ticket?
The same issue when we updated to 10.25.0
it seems when the message gonna populate we have this crash

```
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[2]'
*** First throw call stack:
(
	0   CoreFoundation                      0x00000001804ae138 __exceptionPreprocess + 172
	1   libobjc.A.dylib                     0x0000000180087db4 objc_exception_throw + 56
	2   CoreFoundation                      0x0000000180398f70 -[__NSPlaceholderArray initWithObjects:count:] + 552
	3   CoreFoundation                      0x0000000180499148 +[NSArray arrayWithObjects:count:] + 36
	4    *** MY APP ***                     0x0000000103681494 __49+[FIRIAMDefaultDisplayImpl getViewResourceBundle]_block_invoke + 320
	5   libdispatch.dylib                   0x00000001147a173c _dispatch_client_callout + 16
	6   libdispatch.dylib                   0x00000001147a3210 _dispatch_once_callout + 84
	7    *** My APP ***                     0x000000010368132c +[FIRIAMDefaultDisplayImpl getViewResourceBundle] + 156
	8    *** My APP ***                      0x0000000103682100 __83+[FIRIAMDefaultDisplayImpl displayBannerViewWithMessageDefinition:displayDelegate:]_block_invoke + 40
	9   libdispatch.dylib                   0x000000011479fec4 _dispatch_call_block_and_release + 24
	10  libdispatch.dylib                   0x00000001147a173c _dispatch_client_callout + 16
	11  libdispatch.dylib                   0x00000001147b13f8 _dispatch_main_queue_drain + 1228
	12  libdispatch.dylib                   0x00000001147b0f1c _dispatch_main_queue_callback_4CF + 40
	13  CoreFoundation                      0x000000018040e9a0 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
	14  CoreFoundation                      0x00000001804090b8 __CFRunLoopRun + 1936
	15  CoreFoundation                      0x0000000180408514 CFRunLoopRunSpecific + 572
	16  GraphicsServices                    0x000000018ef06ae4 GSEventRunModal + 160
	17  UIKitCore                           0x00000001853e8040 -[UIApplication _run] + 868
	18  UIKitCore                           0x00000001853ebcc8 UIApplicationMain + 124
	19   *** My APP ***                      0x00000001023ad7cc main + 180
	20  dyld                                0x00000001126b1544 start_sim + 20
	21  ???                                 0x000000011282e0e0 0x0 + 4605534432
	22  ???                                 0xd652800000000000 0x0 + 15443546809695207424
)
``` 
Hi everyone, sincere apologies for the trouble. I'm working on addressing this in https://github.com/firebase/firebase-ios-sdk/issues/12882. We'll have a fix going out in the Firebase 10.27.0 release. Until then, I recommend downgrading to 10.24.0.

Fix patch:
diff --git a/FirebaseInAppMessaging/CHANGELOG.md b/FirebaseInAppMessaging/CHANGELOG.md
index 6ed3ff1c7ca..9c5a31b6fe5 100644
--- a/FirebaseInAppMessaging/CHANGELOG.md
+++ b/FirebaseInAppMessaging/CHANGELOG.md
@@ -1,3 +1,10 @@
+# Unreleased
+- [fixed] Fixed crash at app start that affected CocoaPods users using static
+  frameworks (#12882).
+
+# 10.26.0
+- [fixed] Fixed crash at app start that affected SwiftPM users (#12882).
+
 # 10.25.0
 - [changed] Removed usages of user defaults API to eliminate required reason
   impact.
diff --git a/FirebaseInAppMessaging/Sources/DefaultUI/FIRIAMDefaultDisplayImpl.m b/FirebaseInAppMessaging/Sources/DefaultUI/FIRIAMDefaultDisplayImpl.m
index ed724bfcfe3..5673e179fb8 100644
--- a/FirebaseInAppMessaging/Sources/DefaultUI/FIRIAMDefaultDisplayImpl.m
+++ b/FirebaseInAppMessaging/Sources/DefaultUI/FIRIAMDefaultDisplayImpl.m
@@ -64,19 +64,33 @@ + (NSBundle *)getViewResourceBundle {
     bundledResource = @"InAppMessagingDisplayResources";
 #endif  // SWIFT_PACKAGE
 
+    NSMutableArray *bundles = [NSMutableArray array];
+
+    // Resources may be in main bundle when statically linked.
+    NSBundle *mainBundle = [NSBundle mainBundle];
+    if (mainBundle) {
+      [bundles addObject:mainBundle];
+    }
+    // Resources may be in the bundle associated with this class when
+    // dynamically linked.
+    NSBundle *bundleForClass = [NSBundle bundleForClass:myClass];
+    if (bundleForClass) {
+      [bundles addObject:bundleForClass];
+    }
+    // When embedding static frameworks from the zip distribution, the Xcode
+    // will copy the resources into the framework's directory.
+    NSBundle *frameworkBundle = [NSBundle
+        bundleWithURL:
+            [NSBundle.mainBundle.bundleURL
+                URLByAppendingPathComponent:@"Frameworks/FirebaseInAppMessaging.framework"]];
+    if (frameworkBundle) {
+      [bundles addObject:frameworkBundle];
+    }
+
     NSBundle *containingBundle;
     NSURL *bundleURL;
     // The containing bundle is different whether FIAM is statically or dynamically linked.
-    for (containingBundle in @[
-           // Statically linked.
-           [NSBundle mainBundle],
-           // Dynamically linked.
-           [NSBundle bundleForClass:myClass],
-           // Embedded static framework (zip distribution).
-           [NSBundle bundleWithURL:[NSBundle.mainBundle.bundleURL
-                                       URLByAppendingPathComponent:
-                                           @"Frameworks/FirebaseInAppMessaging.framework"]]
-         ]) {
+    for (containingBundle in bundles) {
       bundleURL = [containingBundle URLForResource:bundledResource withExtension:@"bundle"];
       if (bundleURL != nil) break;
     }


Test patch: