So you decided to set up Firebase Crashlytics on your iOS app to be able to track any crashes that may occur, either while testing or in production. You followed the Firebase documentation step by step and did everything correctly. You forced a crash and it appeared on the Firebase console? Great.
You uploaded the app on TestFlight and told your testers to start testing. After some time, you open the Firebase console and notice that there were no crashes recorded and you see a big red sign telling you that you have to upload dSYM files to be able to process those crashes.
But how are you going to do that?
Let’s first explain what a dSYM file is.
Firstly, when Xcode compiles source code to machine code it generates a list of symbols (class names, global variables, method, and function names). That symbol and the information about the file name and the line number where the symbol is declared constitute a debug symbol. Those debug symbols are used both by the Xcode debugger and for generating the crash reports. When you create a debug build these debug symbols are contained inside the compiled binary file.
Archiving an app
When you create a release build (when you archive an app) debug symbols are placed in a dSYM (Debug Symbol) file to reduce the size of the app. Each binary file (main app executable, frameworks, and app extensions) in an app contains its dSYM file. The binary file and its corresponding dSYM file are tied together by a build UUID. This build UUID is unique, even when the same source code gets compiled with a different Xcode version or build settings, a different UUID will get generated. dSYM files are not the only symbol files. When you archive an app with bitcode, the symbols in the dSYM files are replaced by obfuscated symbols to provide privacy for symbol names. A new symbol file bcsymbolmap (bitcode symbol map) gets created and its purpose is to translate these hidden symbol names back to the original symbol names.
Uploading app to the app store
When you upload an app to the app store it is uploaded as a bitcode. Bitcode is an intermediate representation of how the code looks. That bitcode is later converted to an app binary by Apple. Those new binaries now have different UUIDs than dSYMs that were uploaded to Firebase during build time. So new dSYM files get created and we have to manually upload them to Firebase.
How to fix
1. Open Firebase Console and see for what build should you upload the dSYM files
2. Open that build on App Store Connect
3. Open build metadata, under General Information find the Includes Symbols tab and click on Download dSYM
4. Unzip the downloaded file
5. Write down the paths for the Pods folder of your application, GoogleService-Info.plst file, and the downloaded dSYMs folder
6. Open the terminal and execute the following command
/path/to/pods/directory/FirebaseCrashlytics/upload-symbols-gsp /path/to/GoogleService-Info.plist -p ios /path/to/dSYMs
7. If you’ve written the command correctly there should be no warnings and errors and the console should output UUIDs of all the dSYM files that have been uploaded. You can check if they match with the ones in your Firebase console.
8. Wait a couple of minutes for Firebase to process the files
And voila, all the crashes should be displayed on the console.
These are the sources I used in the making of this tutorial, hope you found it useful:
Until the next read, stay well and safe.