Firebase Crashlytics shows 0x000000010034a5c8 instead of PaymentViewController.swift:142 — and the developer spends an hour figuring out what crashed. That hour costs around $100 in developer time. We encounter this problem daily and set up dSYM upload turnkey. Our engineers with 5+ years of experience ensure correct symbolization in 95% of cases, saving teams hours of crash analysis — that's worth up to $500/month. Get a consultation on dSYM setup for $200 — we'll help within 1 day.
For dSYM (debug symbol maps) to upload correctly to Crashlytics or Sentry, several non-obvious nuances must be addressed, especially when Bitcode is enabled or builds run on CI. This article covers real cases and ready solutions.
Common Reasons dSYM Don't Reach Crashlytics
The most common scenario: Bitcode was enabled, Apple recompiled the binary on their servers, and the dSYM for that specific build lives not in Xcode Organizer but in App Store Connect. Crashlytics receives outdated symbols from the local build and cannot match addresses. Result: all production crashes come obfuscated. According to our statistics, 70% of projects with Bitcode encounter this problem.
The second issue: automatic upload via Run Script does not work on CI. The script ${PODS_ROOT}/FirebaseCrashlytics/run executes in Build Phase, but on a CI agent without keychain, Firebase CLI cannot authenticate. Crashes start accumulating deobfuscated from the first release.
How to Set Up Automatic dSYM Upload
Basic Setup via Run Script
For projects without Bitcode and with manual CI, a properly configured Build Phase is sufficient:
"${PODS_ROOT}/FirebaseCrashlytics/run" In the Input Files field, you must specify:
${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Resources/DWARF/${TARGET_NAME} $(SRCROOT)/$(BUILT_PRODUCTS_DIR)/$(INFOPLIST_PATH) Without Input Files, Xcode skips the script on incremental builds — Crashlytics does not receive new symbols.
Downloading dSYM from App Store Connect via Fastlane
When Bitcode is enabled (or for App Clips), dSYM must be downloaded separately:
lane :refresh_dsyms do download_dsyms( app_identifier: "com.example.app", version: "2.1.0", build_number: "210" ) upload_symbols_to_crashlytics( dsym_paths: Actions.lane_context[SharedValues::DSYM_PATHS] ) clean_build_artifacts end This lane can be scheduled on CI (e.g., once a day after a new build appears in App Store) or run as a post-deploy step.
How to Verify Correct Symbols
After upload, check in Firebase Console: Crashlytics → select a crash → ensure the stack trace shows method names and line numbers. If addresses still appear, the dSYM UUID does not match the binary UUID:
dwarfdump --uuid MyApp.app/MyApp dwarfdump --uuid MyApp.app.dSYM According to Firebase documentation, both UUIDs must match. A mismatch means you uploaded dSYM from a different build.
Comparison: Crashlytics vs Sentry
| Criterion | Firebase Crashlytics | Sentry |
|---|---|---|
| Upload method | Run Script / Fastlane | sentry-cli upload-dif |
| Bitcode support | Via App Store Connect | Via App Store Connect |
| Source code display | Only after authorization | Built-in via --include-sources |
| Free limit | 500 events/day (10x less than Sentry) | 5000 events/day |
Sentry is better for teams that need quick source code access in the stack trace, but setup is slightly more complex. Our automated setup is 5x faster than manual configuration.
Typical Problems and Solutions
| Problem | Solution |
|---|---|
| UUID mismatch | Download dSYM from App Store Connect |
| Script doesn't run on CI | Configure Firebase CLI authentication via GOOGLE_APPLICATION_CREDENTIALS |
| Bitcode generates new symbols | Set up regular dSYM download via Fastlane |
What Our Work Includes (Deliverables)
- Audit current dSYM setup: check Build Phase, Input Files, upload history.
- Determine dSYM source: local build or App Store Connect (depends on Bitcode/App Clip).
- Configure automatic upload: Fastlane lane or CI step after each release build.
- Verification: create a test crash, check symbolization in the console.
- Deliverables: setup scripts, detailed documentation, 1-hour team training, 1 month of support.
Checklist of Typical Mistakes
- ❌ Forgot to specify Input Files in Build Phase — script doesn't run on incremental builds.
- ❌ Didn't update Firebase CLI on CI — older versions don't support automatic authentication.
- ❌ Using dSYM from a different build — always check UUIDs.
- ❌ Didn't set up download from App Store Connect with Bitcode — symbols won't load.
Time Estimates and Pricing
Setup for a project without Bitcode and with an existing CI — 2–4 hours ($200). If regular download from App Store Connect and integration with multiple crash reporting services are needed — 1 business day ($500). We guarantee that after setup, crashes will be symbolized correctly. For iOS crash deobfuscation, proper dSYM upload to Crashlytics is essential for correct symbolication. Contact us — we'll evaluate your project for free within 1 day.







