Fix Firebase Crashlytics Not Reporting Crashes on iOS

Crashlytics installed but no crashes showing in the console? Work through the real causes, missing dSYMs, an absent upload build phase, and an unforced first crash, in order of likelihood.

How Crashlytics Reporting Actually Works

To diagnose why crashes are not showing, it helps to know the pipeline. When your app crashes, the Crashlytics SDK writes a report to disk. That report is not sent during the crash itself; it is uploaded the next time the app launches successfully. Separately, to turn raw memory addresses into readable function names and line numbers, Crashlytics needs your app's debug symbol files, called dSYMs, which must be uploaded to Firebase for each build. So a working setup has three moving parts: the SDK is initialized, a build phase (or the SDK) uploads dSYMs, and the app is relaunched after crashing so the pending report can send. If any one of these is missing, the console stays empty or shows crashes without symbolication. Understanding this explains the two most common confusions: developers who force a crash and immediately look for it without relaunching, and developers who see crashes listed but with unreadable stack traces because dSYMs never arrived. The fixes below address each part of this pipeline in the order problems most often occur, so start at the top and work down rather than jumping straight to the most complex explanation.

Fix 1: Force a Crash and Relaunch

The single most frequent reason a first-time user sees nothing in Crashlytics is that no crash report has actually been uploaded yet. Reports upload on the next launch, not at the moment of the crash, and a debugger attached to the process can interfere with capture. Do this: add a deliberate test crash to your code, for example a button that calls fatalError() or the Crashlytics test method that triggers a crash. Then run the app from Xcode, stop the debugger, and launch the app directly by tapping its icon on the device or simulator, not from Xcode. Trigger the crash so the app terminates. Now launch the app one more time, which is when the SDK uploads the stored report. Wait a few minutes and refresh the Crashlytics dashboard. Crucially, the very first crash for a new app sometimes takes longer to appear as Firebase initializes the app's Crashlytics data. If you skip the relaunch step, the report never sends, which looks exactly like Crashlytics being broken when it is working fine. Make this relaunch-and-wait sequence your standard test ritual, because most reports of Crashlytics not working are really reports of a missing relaunch.

Fix 2: Verify SDK Setup and Initialization

Confirm Crashlytics is actually installed and running. You need the FirebaseCrashlytics product added to your package, and FirebaseApp.configure() must be called at launch, since Crashlytics initializes as part of Firebase startup. Check that you followed the current setup: in older integrations you had to call an explicit start, but the modern SDK initializes automatically once Firebase is configured and the library is linked. Look at the Xcode console on a normal launch for Crashlytics log lines indicating it initialized; you can also set the debug logging flag to get more verbose output while troubleshooting. Make sure you are not disabling collection: Crashlytics has a flag to enable or disable automatic data collection, and if your app or Info.plist sets it off (for example gating on user consent) you must re-enable it, or manually call the API to set collection enabled, before crashes will send. Also verify the device has network access after the relaunch, since a report cannot upload offline. Confirming the SDK is present and collection is enabled rules out the base-configuration causes. If you gate collection on a privacy consent prompt, double-check that granting consent actually calls setCrashlyticsCollectionEnabled(true), or reports will silently never leave the device.

Fix 3: Add the dSYM Upload Build Phase

If crashes appear but the stack traces are unreadable, or the console warns about missing dSYMs, the debug symbols are not reaching Firebase. Crashlytics needs a build phase that uploads dSYMs. In Xcode, select your target, open Build Phases, and add a New Run Script Phase that runs the Crashlytics upload-symbols/run script from the Firebase SDK, with your GoogleService-Info.plist path passed as input. The exact script invocation is documented in Firebase's Crashlytics setup guide and differs slightly between SPM and CocoaPods installs, so copy it from the official docs for your integration method. Just as important, add your build's output paths and the location of the dSYMs and Info.plist as Input Files to the run script phase, because without the correct input files Xcode's build system may skip or mis-run the phase. Place this phase after the compile and Copy Bundle Resources phases. Once configured, every build automatically uploads its dSYMs, so future crashes symbolicate correctly. This phase is the piece most often missing when crashes show up but are not human-readable. After adding it, do a clean build so the phase runs against a fresh archive and confirm in the build log that the upload script actually executed.

Fix 4: Handle Missing dSYMs from Bitcode or App Store Builds

For builds distributed through TestFlight or the App Store, dSYMs can be a special headache, historically because of Bitcode, where Apple recompiled your app on their servers and generated new dSYMs that your local build phase never saw. Although Bitcode is deprecated and no longer used for new iOS App Store submissions, existing projects and older configurations can still hit this. If Crashlytics reports missing dSYMs for a release build, download the dSYMs from App Store Connect: open your app, go to the build under TestFlight or the relevant version, and download the dSYM package, or retrieve them from the Xcode Organizer by selecting the archive and choosing Download Debug Symbols. Then upload them to Firebase manually using the upload-symbols script from the Crashlytics SDK, pointing it at your GoogleService-Info.plist and the folder of downloaded dSYMs. This resolves the gap for builds where Apple, rather than your machine, produced the final binary. For new projects, leaving Bitcode off (now the default) and keeping the automatic upload build phase avoids most of this, but knowing the manual upload path is essential for release-build symbolication issues. Keep the upload-symbols script handy in your project notes, since you will reach for it whenever a store build surfaces a missing-dSYM warning.

Fix 5: Debugger Interference and Build Configuration

A few environmental factors quietly block reports. Running attached to the Xcode debugger can prevent Crashlytics from capturing a crash, because the debugger intercepts the signal; always test by launching the app independently after installing it, as described earlier. Build configuration matters too: make sure you are testing a build where the SDK and upload phase are active, and be aware that if your Debug configuration strips or omits dSYMs, symbolication will suffer, so confirm the Debug Information Format build setting is set to DWARF with dSYM File for the configurations you rely on. If you use multiple schemes or a custom configuration, verify the run script phase is not excluded from it. Also check that the app's bundle ID matches the Firebase app, since a mismatch sends data to the wrong or a nonexistent Crashlytics app, appearing as no crashes. Finally, corporate networks or VPNs can block the upload endpoints. Eliminating debugger interference and confirming the dSYM build setting removes the last common reasons crashes fail to appear or fail to symbolicate. When several factors overlap, change one variable at a time and re-run your force-crash-and-relaunch test after each, so you know exactly which setting was responsible.

Verifying Reporting End to End

Once you have applied the relevant fixes, run a clean end-to-end verification. Build and install the app, launch it independently of Xcode, trigger a deliberate test crash, then relaunch the app so the report uploads, and give the console a few minutes to process, remembering the first crash for a new app can lag. A healthy result is the crash appearing in the Crashlytics dashboard with a fully symbolicated stack trace pointing at your source line, which confirms both the SDK and the dSYM upload are working. To keep it healthy in production, ensure the upload-symbols build phase runs on every release build, upload dSYMs from App Store Connect if you ever see a missing-dSYM warning on a store build, and consider adding custom keys and non-fatal error logging with Crashlytics APIs so you get richer context on real user crashes. Verifying the full loop once, from crash to symbolicated report, gives you confidence that when real users hit a crash, you will actually see it, which is the entire point of installing Crashlytics. Re-run this same verification after any major Firebase or Xcode upgrade, since toolchain changes are exactly when a previously working dSYM pipeline can quietly break.

Frequently Asked Questions

Why don't I see my crash in Crashlytics right after it happens?

Crashlytics uploads the crash report on the next successful app launch, not during the crash itself. After triggering a crash, relaunch the app so the stored report sends, then wait a few minutes. The very first crash for a new app can also take longer to appear while Firebase initializes.

Why are my crash stack traces unreadable?

Your dSYM debug symbols are not reaching Firebase. Add the Crashlytics upload-symbols run script build phase with the correct input files, so every build uploads its dSYMs. For TestFlight or App Store builds, you may need to download dSYMs from App Store Connect or the Xcode Organizer and upload them manually with the upload-symbols script.

Does running from the Xcode debugger affect Crashlytics?

Yes. An attached debugger can intercept the crash signal and prevent Crashlytics from capturing it. Always test by installing the app and launching it directly from the device or simulator home screen, not from Xcode, then relaunch after the crash so the report uploads.

Do I need to call a start method for Crashlytics?

With the modern SDK, no explicit start call is needed; Crashlytics initializes automatically once you link the FirebaseCrashlytics library and call FirebaseApp.configure() at launch. Just make sure automatic data collection is not disabled by a flag in your code or Info.plist, which would prevent crashes from sending.

How do I fix missing dSYMs for an App Store or TestFlight build?

Download the dSYM package from App Store Connect under the specific build, or from the Xcode Organizer via Download Debug Symbols on the archive. Then run the Crashlytics upload-symbols script pointing at your GoogleService-Info.plist and the downloaded dSYM folder to upload them to Firebase for symbolication.

Could a bundle ID mismatch cause no crashes to show?

Yes. If your app's bundle ID does not match the Firebase app it is configured for, reports go to the wrong or a nonexistent Crashlytics app and appear as nothing showing up. Confirm the bundle ID in Xcode matches the registered iOS app and its GoogleService-Info.plist.