This page provides troubleshooting help and answers to frequently-asked questions about using Crashlytics. If you can't find what you're looking for or need additional help, contact Firebase support.
On this page, you can find information about the following types of topics:
General troubleshooting, including questions about display of data or working with data in the Firebase console and questions about regressed issues.
Platform-specific support, including questions specific to Apple platforms, Android, and Unity.
Integrations support, including questions about BigQuery.
General troubleshooting/FAQ
You might notice two different formats for issues listed in your Issues table in the Firebase console. And you might also notice a feature called "variants" within some of your issues. Here's why!
In early 2023, we rolled out an improved analysis engine for grouping events as well as an updated design and some advanced features for new issues (like variants!). Check out our recent blog post for all the details, but you can read below for the highlights.
Crashlytics analyzes all the events from your app (like crashes, non-fatals, and ANRs) and creates groups of events called issues — all events in an issue have a common point of failure.
To group events into these issues, the improved analysis engine now looks at many aspects of the event, including the frames in the stack trace, the exception message, the error code, and other platform or error type characteristics.
However, within this group of events, the stack traces leading to the failure might be different. A different stack trace could mean a different root cause. To represent this possible difference within an issue, we now create variants within issues - each variant is a sub-group of events in an issue that have the same failure point and a similar stack trace. With variants, you can debug the most common stack traces within an issue and determine if different root causes are leading to the failure.
Here's what you'll experience with these improvements:
Revamped metadata displayed within the issue row
It's now easier to understand and triage issues in your app.Fewer duplicate issues
A line number change doesn't result in a new issue.Easier debugging of complex issues with various root causes
Use variants to debug the most common stack traces within an issue.More meaningful alerts and signals
A new issue actually represents a new bug.More powerful search
Each issue contains more searchable metadata, like exception type and package name.
Here's how these improvements are rolling out:
When we get new events from your app, we'll check if they match to an existing issue.
If there's no match, we'll automatically apply our smarter event-grouping algorithm to the event and create a new issue with the revamped metadata design.
This is the first big update that we're making to our event grouping. If you have feedback or encounter any issues, let us know by filing a report.
If you're not seeing breadcrumb logs (iOS+ | Android | Flutter | Unity), we recommend checking your app's configuration for Google Analytics. Make sure you meet the following requirements:
You've enabled Google Analytics in your Firebase project.
You've enabled Data sharing for Google Analytics. Learn more about this setting in Manage your Analytics data sharing settings
You've added to your app the Firebase SDK for Google Analytics: iOS+ | Android | Flutter | Unity.
This SDK must be added in addition to the Crashlytics SDK.You're using the latest Firebase SDK versions for all the products that you use in your app (iOS+ | Android | Flutter | Unity).
For Apple platforms and Android apps, especially check that you're using at minimum the following version of the Firebase SDK for Google Analytics:
iOS+ — v6.3.1+ (v8.9.0+ for macOS and tvOS) |Android — v17.2.3+ (BoM v24.7.1+) .
If you're not seeing velocity alerts, make sure that you're using the
If you're not seeing crash-free metrics (like crash-free users and sessions) or seeing unreliable metrics, check the following:
Make sure that you're using the
Make sure that your data collection settings aren't impacting the quality of your crash-free metrics:
If you enable opt-in reporting by disabling automatic crash reporting, crash information can only be sent to Crashlytics from users who have explicitly opted into data collection. Thus, the accuracy of crash-free metrics will be affected since Crashlytics only has crash information from these opted-in users (rather than all your users). This means that your crash-free metrics may be less reliable and less reflective of the overall stability of your app.
If you have automatic data collection disabled, you can use
sendUnsentReportsto send on-device cached reports to Crashlytics. Using this method will send crash data to Crashlytics, but not sessions data which causes the console charts to show low or zero values for crash-free metrics.
See Understand crash-free metrics.
Notes allow project members to comment on specific issues with questions, status updates, etc.
When a project member posts a note, it's labeled with the email of their Google Account. This email address is visible, along with the note, to all project members with access to view the note.
The following describes the access required to view, write, and delete notes:
Project members with any of the following roles can view and delete existing notes and write new notes on an issue.
- Project Owner or Editor, Firebase Admin, Quality Admin, or Crashlytics Admin
Project members with any of the following roles can view the notes posted on an issue, but they cannot delete or write a note.
- Project Viewer, Firebase Viewer, Quality Viewer, or Crashlytics Viewer
An issue has had a regression when you've previously closed the issue but Crashlytics gets a new report that the issue has re-occurred. Crashlytics automatically re-opens these regressed issues so that you can address them as appropriate for your app.
Here's an example scenario that explains how Crashlytics categorizes an issue as a regression:
- For the first time ever, Crashlytics gets a crash report about Crash "A". Crashlytics opens a corresponding issue for that crash (Issue "A").
- You fix this bug quickly, close Issue "A", and then release a new version of your app.
- Crashlytics gets another report about Issue "A" after you've closed the issue.
- If the report is from an app version that Crashlytics knew about when you closed the issue (meaning that the version had sent a crash report for any crash at all), then Crashlytics won't consider the issue as regressed. The issue will remain closed.
- If the report is from an app version that Crashlytics did not know about when you closed the issue (meaning that the version had never sent any crash report for any crash at all), then Crashlytics considers the issue regressed and will re-open the issue.
When an issue regresses, we send a regression detection alert and add a regression signal to the issue to let you know that Crashlytics has re-opened the issue. If you don't want an issue to re-open due to our regression algorithm, "mute" the issue instead of closing it.
If a report is from an old app version that had never sent any crash reports at all when you closed the issue, then Crashlytics considers the issue regressed and will re-open the issue.
This situation can happen in the following situation: You've fixed a bug and released a new version of your app, but you still have users on earlier versions without the bug fix. If, by chance, one of those earlier versions had never sent any crash reports at all when you closed the issue, and those users start encountering the bug, then those crash reports would trigger a regressed issue.
If you don't want an issue to re-open due to our regression algorithm, "mute" the issue instead of closing it.
Platform-specific support
The following sections provide support for platform-specific troubleshooting and FAQ: iOS+ | Android | Unity.
Apple platforms support
To upload your project's dSYMs and get verbose output, check the following:
Make sure your project's build phase contains the Crashlytics run script, which allows Xcode to upload your project's dSYMs at build time (read Initializing Crashlytics for instructions on adding the script). After updating your project, force a crash and confirm that the crash appears in the Crashlytics dashboard.
If you see a "Missing dSYM" alert in the Firebase console, check Xcode to make sure it's properly producing dSYMs for the build.
If Xcode is properly producing dSYMs, and you're still seeing missing dSYMs, it's likely the run script tool is getting stuck while uploading the dSYMs. In this case, try each of the following:
Make sure you're using the latest version of Crashlytics.
Upload the missing dSYM files manually:
- Option 1: Use the console-based "Drag and Drop" option in the dSYMs tab to upload a zip archive containing the missing dSYM files.
- Option 2: Use the
upload-symbolsscript to upload the missing dSYM files, for the provided UUIDs in the dSYMs tab.
If you continue to see missing dSYMs, or uploads are still unsuccessful, contact Firebase Support and be sure to include your logs.
If your stack traces seem to be poorly symbolicated, check the following:
If frames from your app's library lack references to your app's code, make sure that
is not set as a compilation flag.-fomit-frame-pointerIf you see several
(Missing)frames for your app's library, check if there are optional dSYMs listed as missing (for the affected app version) in the Crashlytics dSYMs tab of the Firebase console. If so, follow the "Missing dSYM alert" troubleshooting step in the dSYMs are missing/not uploading FAQ on this page. Note that uploading these dSYMs won't symbolicate crashes that have already occurred, but this will help ensure symbolication for future crashes.
Yes, you can implement Crashlytics in macOS and tvOS projects. Make sure to include v8.9.0+ of the Firebase SDK for Google Analytics so that crashes will have access to metrics collected by Google Analytics (crash-free users, latest release, velocity alerts, and breadcrumb logs).
You can now report crashes for multiple apps in a single Firebase project, even when the apps are built for different Apple platforms (for example, iOS, tvOS, and Mac Catalyst). Previously, you needed to separate the apps into individual Firebase projects if they contained the same bundle ID.
Android support
Crashlytics supports ANR reporting for Android apps from devices that run Android 11 and higher. The underlying API that we use to collect ANRs (getHistoricalProcessExitReasons) is more reliable than SIGQUIT or watchdog-based approaches. This API is available only on Android 11+ devices.
If some of your ANRs are missing their BuildIds, troubleshoot as follows:
Make sure that you're using an up-to-date Crashlytics Android SDK and Crashlytics Gradle plugin version.
If you're missing
BuildIds for Android 11 and some Android 12 ANRs, then it's likely that you're using an out-of-date SDK, Gradle plugin, or both. To properly collectBuildIds for these ANRs, you need to use the following versions:- Crashlytics Android SDK v18.3.5+ (Firebase BoM v31.2.2+)
- Crashlytics Gradle plugin v2.9.4+
Check if you're using a non-standard location for your shared libraries.
If you're only missing
BuildIds for your app’s shared libraries, it's likely that you're not using the standard, default location for shared libraries. If this is the case, then Crashlytics might not be able to locate the associatedBuildIds. We recommend that you consider using the standard location for shared libraries.Make sure that you're not stripping
BuildIds during the build process.Note that the following troubleshooting tips apply to both ANRs and native crashes.
Check if the
BuildIds exist by runningreadelf -non your binaries. If theBuildIds are absent, then add-Wl,--build-idto the flags for your build system.Check that you're not unintentionally stripping the
BuildIds in an effort to reduce your APK size.If you keep stripped and unstripped versions of a library, make sure to point to the correct version in your code.
There can be a mismatch between the count of ANRs between Google Play and Crashlytics. This is expected due to the difference in the mechanism of collecting and reporting ANR data. Crashlytics reports ANRs when the app next starts up, whereas Android Vitals sends ANR data after the ANR occurs.
Additionally, Crashlytics only displays ANRs that occur on devices running Android 11+, compared to Google Play which displays ANRs from devices with Google Play services and data collection consent accepted.
When an app uses an obfuscator that doesn't expose the file extension, Crashlytics generates each issue with a .java file extension by default.
So that Crashlytics can generate issues with the correct file extension, make sure your app uses the following setup:
- Uses Android Gradle 4.2.0 or higher
- Uses R8 with obfuscation turned on. To update your app to R8, follow this documentation.
Note that after updating to the setup described above, you might start seeing new .kt issues that are duplicates of existing .java issues. See the FAQ to learn more about that circumstance.
Starting in mid-December 2021, Crashlytics improved support for applications that use Kotlin.
Until recently, the available obfuscators did not expose the file extension, so Crashlytics generated each issue with a .java file extension by default. However, as of Android Gradle 4.2.0, R8 supports file extensions.
With this update, Crashlytics can now determine if each class used within the app is written in Kotlin and include the correct filename in the issue signature. Crashes are now correctly attributed to .kt files (as appropriate) if your app has the following setup:
- Your app uses Android Gradle 4.2.0 or higher.
- Your app uses R8 with obfuscation turned on.
Since new crashes now include the correct file extension in their issue signatures, you might see new .kt issues that are actually just duplicates of existing .java-labeled issues. In the Firebase console, we try to identify and communicate to you if a new .kt issue is a possible duplicate of an existing .java-labeled issue.
If you see the following exception, it's likely you're using a version of DexGuard that's incompatible with the Firebase Crashlytics SDK:
java.lang.IllegalArgumentException: Transport backend 'cct' is not registered
This exception does not crash your app but prevents it from sending crash reports. To fix this:
Make sure you're using the latest DexGuard 8.x release. The latest version contains rules that are required by the Firebase Crashlytics SDK.
If you don't want to change your DexGuard version, try adding the following line to your obfuscation rules (in your DexGuard config file):
-keepresourcexmlelements manifest/application/service/meta-data@value=cct
The latest release of the Crashlytics Gradle plugin is a major version (v3.0.0) and modernizes the SDK by dropping support for lower versions of Gradle and the Android Gradle plugin. Additionally, the changes in this release resolve issues with AGP v8.1+ and improve support for native apps and customized builds.
Minimum requirements
The Crashlytics Gradle plugin v3 has the following minimum requirements:
Android Gradle plugin 8.1+
Upgrade this plugin using the Android Gradle plugin Upgrade Assistant on the latest version of Android Studio.Firebase's
google-servicesGradle plugin 4.4.1+
Upgrade this plugin by specifying the latest version in your project's Gradle build file, like so:
Kotlin
plugins { id("com.android.application") version "8.1.4" apply false id("com.google.gms.google-services") version "4.4.4" apply false ... }
Groovy
plugins { id 'com.android.application' version '8.1.4' apply false id 'com.google.gms.google-services' version '4.4.4' apply false ... }
Changes to the Crashlytics extension
With v3 of the Crashlytics Gradle plugin, the Crashlytics extension has the following breaking changes:
Removed the extension from the
defaultConfigandroid block. Instead, you should configure each variant.Removed the deprecated field
mappingFile. Instead, the merged mapping file is now provided automatically.Removed the deprecated field
strippedNativeLibsDir. Instead, you should useunstrippedNativeLibsDirfor all native libs.Changed the field
unstrippedNativeLibsDirto be cumulative.Replaced the closure field
symbolGeneratorwith two new top level fields:symbolGeneratorType, a String of either"breakpad"(default) or"csym".breakpadBinary, a File of a localdump_symsbinary override.
Example for how to upgrade the extension
Kotlin
| Before | buildTypes { release { configure<CrashlyticsExtension> { // ... symbolGenerator( closureOf<SymbolGenerator> { symbolGeneratorType = "breakpad" breakpadBinary = file("/PATH/TO/BREAKPAD/DUMP_SYMS") } ) } } } |
| Now in v3 | buildTypes { release { configure<CrashlyticsExtension> { // ... symbolGeneratorType = "breakpad" breakpadBinary = file("/PATH/TO/BREAKPAD/DUMP_SYMS") } } } |
Groovy
| Before | buildTypes { release { firebaseCrashlytics { // ... symbolGenerator { breakpad { binary file("/PATH/TO/BREAKPAD/DUMP_SYMS") } } } } } |
| Now in v3 | buildTypes { release { firebaseCrashlytics { // ... symbolGeneratorType "breakpad" breakpadBinary file("/PATH/TO/BREAKPAD/DUMP_SYMS") } } } |
Android-NDK specific support
LLVM and GNU toolchains have distinct defaults and treatments for the read-only segment of your app's binaries, which may generate inconsistent stack traces in the Firebase console. To mitigate this, add the following linker flags to your build process:
If you're using the
lldlinker from the LLVM toolchain, add:-Wl,--no-rosegmentIf you're using the
ld.goldlinker from the GNU toolchain, add:-Wl,--rosegment
If you're still seeing stack trace inconsistencies (or if neither flag is pertinent to your toolchain), try adding the following to your build process instead:
-fno-omit-frame-pointer
The Crashlytics plugin bundles a customized Breakpad symbol file generator. If you prefer to use your own binary for generating Breakpad symbol files (for example, if you prefer to build all native executables in your build chain from source), use the optional symbolGeneratorBinary extension property to specify the path to the executable.
You can specify the path to the Breakpad symbol file generator binary in one of two ways:
Option 1: Specify the path via the
firebaseCrashlyticsextension in yourbuild.gradlefileAdd the following to your app-level
build.gradle.ktsfile:Gradle plugin v3.0.0+
android { buildTypes { release { configure<CrashlyticsExtension> { nativeSymbolUploadEnabled = true // Add these optional fields to specify the path to the executable symbolGeneratorType = "breakpad" breakpadBinary = file("/PATH/TO/BREAKPAD/DUMP_SYMS") } } } }
lower plugin versions
android { // ... buildTypes { // ... release { // ... firebaseCrashlytics { // existing; required for either symbol file generator nativeSymbolUploadEnabled true // Add this optional new block to specify the path to the executable symbolGenerator { breakpad { binary file("/PATH/TO/BREAKPAD/DUMP_SYMS") } } } } }
Option 2: Specify the path via a property line in your Gradle properties file
You can use the
com.google.firebase.crashlytics.breakpadBinaryproperty to specify the path to the executable.You can manually update your Gradle properties file or update the file via the command line. For example, to specify the path via the command line, use a command like the following:
./gradlew -Pcom.google.firebase.crashlytics.symbolGenerator=breakpad \ -Pcom.google.firebase.crashlytics.breakpadBinary=/PATH/TO/BREAKPAD/DUMP_SYMS \ app:assembleRelease app:uploadCrashlyticsSymbolFileRelease
The Firebase Crashlytics NDK does not support ARMv5 (armeabi). Support for this ABI was removed as of NDK r17.
Unity support
If you're using Unity IL2CPP and you're seeing unsymbolicated stack traces, then try the following:
Make sure that you're using v8.6.1 or higher of the Crashlytics Unity SDK.
Make sure that you're set up for and running the Firebase CLI
crashlytics:symbols:uploadcommand to generate and upload your symbol file.You need to run this CLI command each time that you create a release build or any build for which you want to see symbolicated stack traces in the Firebase console. Learn more in Get readable crash reports.
Yes, Crashlytics can display symbolicated stack traces for your apps that use IL2CPP. This capability is available for apps released on either Android or Apple platforms. Here's what you need to do:
Make sure that you're using v8.6.0 or higher of the Crashlytics Unity SDK.
Complete the necessary tasks for your platform:
For Apple platform apps: No special actions are needed. For Apple platform apps, the Firebase Unity Editor plugin automatically configures your Xcode project to upload symbols.
For Android apps: Make sure that you're set up for and running the Firebase CLI
crashlytics:symbols:uploadcommand to generate and upload your symbol file.You need to run this CLI command each time that you create a release build or any build for which you want to see symbolicated stack traces in the Firebase console. Learn more in Get readable crash reports.
Reporting uncaught exceptions as fatals
Crashlytics can report uncaught exceptions as fatals (starting with v10.4.0 of the Unity SDK). The following FAQs help to explain the rationale and best practices for using this feature.
By reporting uncaught exceptions as fatals, you get a more realistic indication of what exceptions may result in the game being unplayable – even if the app continues to run.
Note that if you start reporting fatals, your crash-free users (CFU) percentage will likely decrease, but the CFU metric will be more representative of the end-users' experiences with your app.
In order for Crashlytics to report an uncaught exception as fatal, both of the following two conditions must be met:
During initialization in your app, the
ReportUncaughtExceptionsAsFatalproperty must be set totrue.Your app (or an included library) throws an exception that isn't caught. An exception that's created, but not thrown, is not considered uncaught.
When you start getting reports of your uncaught exceptions as fatals, here are some options for handling these uncaught exceptions:
- Consider how you can start catching and handling these uncaught exceptions.
- Consider different options for logging exceptions to the Unity debug console and to Crashlytics.
Catch and handle thrown exceptions
Exceptions are created and thrown to reflect unexpected or exceptional states. Resolving the issues reflected by a thrown exception involves returning the program to a known state (a process known as exception handling).
It's best practice to catch and handle all foreseen exceptions unless the program cannot be returned to a known state.
To control which sorts of exceptions are caught and handled by what code, wrap code that might generate an exception in a try-catch block. Make sure that the conditions in the catch statements are as narrow as possible to handle the specific exceptions appropriately.
Log exceptions in Unity or Crashlytics
There are multiple ways to record exceptions in Unity or Crashlytics to help debug the issue.
When using Crashlytics, here are the two most common and recommended options:
Option 1: Print in the Unity console, but don't report to Crashlytics, during development or troubleshooting
- Print to the Unity console using
Debug.Log(exception),Debug.LogWarning(exception), andDebug.LogError(exception)which print the contents of the exception to the Unity console and don't re-throw the exception.
- Print to the Unity console using
Option 2: Upload to Crashlytics for consolidated reporting in the Crashlytics dashboard for the following situations:
- If an exception is worth logging to debug a possible subsequent Crashlytics event, then use
Crashlytics.Log(exception.ToString()). - If an exception should still be reported to Crashlytics despite being caught and handled, then use
Crashlytics.LogException(exception)to log it as a nonfatal event.
- If an exception is worth logging to debug a possible subsequent Crashlytics event, then use
However, if you want to manually report a fatal event to Unity Cloud Diagnostics, you can use Debug.LogException. This option prints the exception to the Unity console like Option 1, but it also throws the exception (whether or not it has been thrown or caught yet). It throws the error nonlocally. This means that even a surrounding Debug.LogException(exception) with try-catch blocks still results in an uncaught exception.
Therefore, call Debug.LogException if and only if you want to do all of the following:
- To print the exception to the Unity console.
- To upload the exception to Crashlytics as a fatal event.
- To throw the exception, have it be treated as an uncaught exception, and have it be reported to Unity Cloud Diagnostics.
Note that if you want to print a caught exception to the Unity console and upload to Crashlytics as a nonfatal event, do the following instead:
try { methodThatThrowsMyCustomExceptionType(); } catch(MyCustomExceptionType exception) { // Print the exception to the Unity console at the error level. Debug.LogError(exception); // Upload the exception to Crashlytics as a non-fatal event. Crashlytics.LogException(exception); // not Debug.LogException // // Code that handles the exception // } Integrations support
If your project uses Crashlytics alongside the Google Mobile Ads SDK, it's likely that the crash reporters are interfering when registering exception handlers. To fix the issue, turn off crash reporting in the Mobile Ads SDK by calling disableSDKCrashReporting.
Firebase exports data to the dataset location you selected when you set up data export to BigQuery.
This location applies to both the Crashlytics dataset and the Firebase sessions dataset (if sessions data is enabled for export).
This location is only applicable for the data exported into BigQuery, and it does not impact the location of data stored for use in the Crashlytics dashboard of the Firebase console or in Android Studio.
After a dataset is created, its location can't be changed, but you can copy the dataset to a different location or manually move (recreate) the dataset in a different location. To learn more, see Change the location for existing exports.
In mid-October 2024, Crashlytics launched a new infrastructure for batch export of Crashlytics data into BigQuery.
If you enabled batch export after October 2024, then your Firebase project is automatically using the new export infrastructure. No action is needed.
If you enabled batch export before or during October 2024, review the information in this FAQ to determine if you need to take any action.
All Firebase projects will be automatically upgraded to the new batch export infrastructure as early as January 9, 2026. You can upgrade before this date, but make sure that your BigQuery batch tables meet the prerequisites for upgrading.
You can upgrade to the new infrastructure, but make sure that your BigQuery batch tables meet the prerequisites for upgrading.
Determine if you're on the new infrastructure
If you enabled batch export in mid-October 2024 or later, then your Firebase project is automatically using the new export infrastructure.
You can check which infrastructure your project is using: Go to the Google Cloud console, and if your "data transfer config" is labeled Firebase Crashlytics with Multi-Region Support, then your project is using the new export infrastructure.
Important differences between the old export infrastructure and the new export infrastructure
The new infrastructure supports Crashlytics dataset locations outside the United States.
Export enabled before mid-October 2024 and upgraded to the new export infrastructure — You can now optionally change the location for data export.
Export enabled in mid-October 2024 or later — You were prompted during setup to select a location for data export.
The new infrastructure doesn't support backfills of data from before you enabled export.
The old infrastructure supported backfill up to 30 days prior to the date when you enabled export.
The new infrastructure supports backfills up to the past 30 days or for the most recent date when you enabled export to BigQuery (whichever is most recent).
The new infrastructure names BigQuery batch tables using the identifiers set for your Firebase Apps in your Firebase project.
The old infrastructure wrote data to batch tables with names based on the bundle IDs or package names in your app's binary.
The new infrastructure writes data to batch tables with names based on the bundle IDs or package names set for your registered Firebase Apps in your Firebase project.
Step 1: Prerequisite for upgrading
Check that your existing BigQuery batch tables use matching identifiers to the bundle IDs or package names set for your registered Firebase Apps in your Firebase project. If they don't match, then you might experience disruptions to your exported batch data. Most projects will be in a proper and compatible state, but it's important to check before upgrading.
You can find all the Firebase Apps registered in your Firebase project in the Firebase console: Go to your Project settings, then scroll to the Your apps card to see all your Firebase Apps and their information.
You can find all your BigQuery batch tables in the BigQuery page of the Google Cloud console.
For example, here are ideal states where you won't have any issues upgrading:
You have a batch table named
com_yourcompany_yourproject_IOSand a Firebase iOS+ App with the bundle IDcom.yourcompany.yourprojectregistered in your Firebase project.You have a batch table named
com_yourcompany_yourproject_ANDROIDand a Firebase Android App with the package namecom.yourcompany.yourprojectregistered in your Firebase project.
If you have batch table names that do not match the identifiers set for your registered Firebase Apps, then follow the instructions later on this page before manually upgrading or before January 9, 2026 to avoid disruption to your batch export.
Step 2: Manually upgrade to the new infrastructure
If you enabled batch export before mid-October 2024, then you can manually upgrade to the new infrastructure simply by toggling Crashlytics data export off and then on again in the Firebase console.
Here are the detailed steps:
In the Firebase console, go to the Integrations page.
In the BigQuery card, click Manage.
Toggle off the Crashlytics slider to disable export. When prompted, confirm that you want data export to stop.
Immediately toggle on again the Crashlytics slider to re-enable export. When prompted, confirm that you want to export data.
Your Crashlytics data export to BigQuery is now using the new export infrastructure.
Your existing batch table name doesn't match your Firebase App identifier
If you have existing BigQuery batch tables in this state, then it means that they're not compatible with Firebase's new batch export-to-BigQuery infrastructure. Note that all Firebase projects will be automatically migrated to the new export infrastructure as early as January 9, 2026.
Follow the guidance in this section before manually upgrading or before January 9, 2026 to avoid disruption to the batch export of your Crashlytics data to BigQuery.
Jump to instructions for options to avoid disruptions
Understand how the export infrastructure uses identifiers to write data to BigQuery tables
Here's how the two export infrastructures write Crashlytics data to BigQuery batch tables:
Legacy export infrastructure: Writes data to a table with a name that's based on the bundle ID or package name in your app's binary.
New export infrastructure: Writes data to a table with a name that's based on the bundle ID or package name set for your registered Firebase App in your Firebase project.
Unfortunately, sometimes the bundle ID or package name in your app's binary doesn't match the bundle ID or package name set for your registered Firebase App in your Firebase project. This usually happens if someone didn't enter the actual identifier during app registration.
What happens if this isn't fixed before upgrading?
If the identifiers in these two locations don't match, then the following happens after upgrading to the new export infrastructure:
Your Crashlytics data will start writing to a new BigQuery batch table — that is, a new table with a name based on the bundle ID or package name set for your registered Firebase App in your Firebase project.
Any existing "legacy" table with a name based on the identifier in your app's binary will no longer have data written to it.
Example scenarios of mismatched identifiers
Note that BigQuery batch table names are automatically appended with _IOS or _ANDROID to indicate the platform of the app.
| Identifier(s) in your app's binary | Identifier(s) set for your Firebase App(s) | Legacy behavior | Behavior after upgrade to new export infrastructure | Solution |
|---|---|---|---|---|
foo | bar | Writes to a single table named after the identifier in app's binary (foo) | Creates then writes to a single table named after the identifier set for Firebase App (bar) | Implement either Option 1 or 2 described below. |
foo | bar, qux, etc. | Writes to a single table named after the identifier in app's binary (foo) | Creates* then writes to multiple tables named after the identifiers set for Firebase Apps (bar, qux, etc.) | Implement Option 2 described below. |
foo, baz, etc. | bar | Writes to multiple tables named after the multiple identifiers in app's binary (foo, baz, etc.) | Creates** then writes every app's data to a single table named after the identifier set for Firebase App (bar) | None of the options can be implemented. You can still differentiate data from each app within the single table by using the app's |
* If the identifier in your app's binary matched one of the identifiers set for a Firebase App, then the new export infrastructure won't create a new table for that identifier. Instead, it will continue writing data for that specific app to it. All other apps will be written to new tables.
** If one of the identifiers in your app's binary matched the identifier set for the Firebase App, then the new export infrastructure won't create a new table. Instead, it will maintain that table and start writing data for all apps to it.
Options to avoid disruption
To avoid any disruptions, follow the instructions for one of the options described below before you manually upgrade or before January 9, 2026.
OPTION 1:
Use the new table created by the new export infrastructure. You'll copy data from your existing table to the new table.In the Firebase console, upgrade to the new export infrastructure by turning export off and then on again for the linked app.
This action creates a new batch table with a name that's based on the bundle ID or package name set for your registered Firebase App in your Firebase project.
In the Google Cloud console, copy all the data from your legacy table to the new table that was just created.
If you have any downstream dependencies that depend on your batch table, change them to use the new table.
OPTION 2:
Continue writing to your existing table. You'll override some defaults in a BigQuery config to achieve this.In the Firebase console, find and take note of the Firebase App ID (for example,
1:1234567890:ios:321abc456def7890) of the app with the mismatched batch table name and identifier:
Go to your Project settings, then go the Your apps card to see all your Firebase Apps and their information.In the Firebase console, upgrade to the new export infrastructure by turning export off and then on again for the linked app.
This action does two things:
Creates a new batch table with a name that's based on the bundle ID or package name set for your registered Firebase App in your Firebase project. (You'll eventually delete this table, but do not delete it yet.)
Creates a BigQuery "data transfer config" with the source
Firebase Crashlytics with Multi-Region Support.
In the Google Cloud console, change the new "data transfer config" so that data will continue to write to your existing table:
Go to BigQuery > Data transfers to view your "data transfer config".
Select the config that has the source
Firebase Crashlytics with Multi-Region Support.Click Edit in the top-right corner.
In the Data source details section, find a list for gmp_app_id and a list for client_namespace.
In BigQuery, the Firebase App ID is called the
gmp_app_id. By default, theclient_namespacevalue in BigQuery is the corresponding unique bundle ID / package name of the app, but you'll be overriding this default configuration.BigQuery uses the
client_namespacevalue for the name of the batch table that each linked Firebase App writes to.Find the gmp_app_id of the Firebase App for which you want to override default settings. Change its client_namespace value to the name of the table you want the Firebase App to write to instead (usually this is the name of the legacy table the app was writing to with the legacy export infrastructure).
Save the config change.
Schedule a backfill for the days that your existing table is missing data.
Once the backfill is done, delete the new table that was automatically created by the new export infrastructure.