Firebase is committed to building an easy to use and robust backend service for Unity developers. Recent changes in the build system accompanying Unity 2020.1 have caused some of the integrations that the Firebase games team built for Unity to stop functioning correctly. Our team is aware of this, and is working hard to rectify the situation. Until then, we recommend that you continue to use Unity 2019 for the best developer experience. For those of you that are on Unity 2020.1, the rest of this post details the workarounds needed to get things up and running.
The Firebase SDK for Unity includes native C++ code and Android specific logic. It also requires some build time operations for all of its products to function properly. Because of this, we have written a number of tools and custom routines that make strong assumptions about Unity’s build process. These continue to work to simplify integration back to Unity version 5, but in Unity 2020.1 the engine overhauled its build system invalidating our previous assumptions. This means that the mechanism by which AndroidX and Jetifier are integrated no longer functions as well as the mechanism by which the information in google-services.json is transmitted to your final Android game. This is required to initialize the Android side of Firebase and to properly hook it up to the Firebase backend.
google-services.json
Further, components that the Crashlytics SDK requires to function are no longer generated. In the worst case scenario, this manifests in a crash on launch.
Although we recommend sticking with the 2019 branch of Unity for the best experience, Unity’s new build system is very similar to a typical Android Java project. This simplifies the workaround we will highlight below, and will mirror some steps in the getting started with Android guide.
Note that because you are performing operations that the Firebase SDK would typically handle automatically, you may have to undo any changes when a full fix is rolled out by our team.
The first fix is to help Firebase find your google-services.json file. Normally the Firebase Unity Plugin would do this automatically, replicating the work of the Google Services plugin Android developers may be familiar with. When you add or update your google-services.json file, the plugin creates a version that Android reads as a “resource” at Assets/Plugins/Android/Firebase/res/values/google-services.xml. Typically this would get copied into your final project automatically, but we can do a little manual work to ensure it gets included!
Assets/Plugins/Android/Firebase/res/values/google-services.xml
First generate a custom mainTemplate.gradle and gradleTemplate.properties (which we’ll need in a moment) via Project Settings/Player/Publishing Settings if you haven’t already:
mainTemplate.gradle
gradleTemplate.properties
Project Settings/Player/Publishing Settings
If you’ve disabled EDM4U’s integration or you just want to be extra careful, now is a great time to also force resolve your Android dependencies from Assets/External Dependency Manager/Android Resolver/Force Resolve. This will update mainTemplate.gradle in a manner that still cuts back on most of the work we’ll have to do:
Assets/External Dependency Manager/Android Resolver/Force Resolve
Now you need to tell gradle where to find the google-services.xml file by adding this to the very bottom of your mainTemplate.gradle:
google-services.xml
android { sourceSets { main { def unityProjectPath = $/file:///**DIR_UNITYPROJECT**/$.replace("\\", "/") res.srcDirs += (unityProjectPath + '/Assets/Plugins/Android/Firebase/res/values/google-services.xml') } } }
There’s one more fix to get base functionality working in Unity, you’ll see that towards the top of mainTemplate.gradle there are some lines like:
// Android Resolver Repos Start ([rootProject] + (rootProject.subprojects as List)).each { ext { it.setProperty("android.useAndroidX", true) it.setProperty("android.enableJetifier", true) } }
This code used to go through every project in the build and enable AndroidX and Jetifier. Although we could perform a similar modification via gradle, Android developers are generally encouraged to use gradleTemplate.properties - which is supported via Unity’s new build pipeline.
So if you remembered to generate it earlier in the tutorial, add the following lines to the end of gradleTemplate.properties:
android.useAndroidX=true android.enableJetifier=true
At this point, most of Firebase should function. This includes your ability to measure your game’s performance with Google Analytics, use that to customize your player’s experience with Remote Config, and to Authenticate you user to begin your game’s connection social experience.
Crashlytics needs a little more work to get operational since it has to embed itself a little deeper into the build process. To continue, you will need the baseProjectTemplate.gradle (the “project level gradle file”). You’ll also need launcherTemplate.gradle since we need an “Application” for Crashlytics (mainTemplate.gradle is technically a “Library”):
baseProjectTemplate.gradle
launcherTemplate.gradle
There’s no need to Force Resolve dependencies again since EDM4U doesn’t know about these files yet! But you can always do it to be safe (the way I modified mainTemplate.gradle purposely avoids bits of the file that would get updated).
Now open baseProjectTemplate.gradle and look for something that looks roughly like:
allprojects { buildscript { repositories {**ARTIFACTORYREPOSITORY** google() jcenter() } dependencies {
Inside allprojects.buildscript.dependencies (the dependencies { bit in this example), add this code to tell gradle about Crashlytics:
allprojects.buildscript.dependencies
dependencies {
// Add the Crashlytics Gradle plugin. classpath 'com.google.firebase:firebase-crashlytics-gradle:2.2.0'
and this line of code to the very end of launcherTemplate.gradle to add the Crashlytics plugin to your Application:
// Apply the Crashlytics Gradle plugin apply plugin: 'com.google.firebase.crashlytics'
We are working hard to resolve these issues as soon as possible so you can go back to building games quickly, easily, and confidently, with Firebase and Unity. To those developers who did upgrade to Unity 2020.1 and encountered issues, we apologize for any confusion or difficulty that this has caused. We would like to reassure you all that there is also active work on some exciting updates that will aid in avoiding similar issues in the future and bring more transparency to this process.
If these steps don’t work for you, or a specific Firebase library isn’t working after you’ve completed these steps, feel free to join in the conversation at the Unity GitHub repository or reach out to support and we will be happy to provide further help.
For your reference, I’ve included all of my modified files here. Do not copy these files directly, but use them to verify that you’ve made the proper changes in the proper locations:
// GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN // Android Resolver Repos Start ([rootProject] + (rootProject.subprojects as List)).each { ext { it.setProperty("android.useAndroidX", true) it.setProperty("android.enableJetifier", true) } } ([rootProject] + (rootProject.subprojects as List)).each { project -> project.repositories { def unityProjectPath = $/file:///**DIR_UNITYPROJECT**/$.replace("\\", "/") maven { url "https://maven.google.com" } maven { url (unityProjectPath + "/Assets/GeneratedLocalRepo/Firebase/m2repository") // Assets/Firebase/Editor/AnalyticsDependencies.xml:18, Assets/Firebase/Editor/AppDependencies.xml:20, Assets/Firebase/Editor/CrashlyticsDependencies.xml:20, Assets/Firebase/Editor/RemoteConfigDependencies.xml:20 } mavenLocal() jcenter() mavenCentral() } } // Android Resolver Repos End apply plugin: 'com.android.library' **APPLY_PLUGINS** dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) // Android Resolver Dependencies Start implementation 'com.google.firebase:firebase-analytics:17.4.1' // Assets/Firebase/Editor/RemoteConfigDependencies.xml:15 implementation 'com.google.firebase:firebase-analytics-unity:6.15.2' // Assets/Firebase/Editor/AnalyticsDependencies.xml:18 implementation 'com.google.firebase:firebase-app-unity:6.15.2' // Assets/Firebase/Editor/AppDependencies.xml:20 implementation 'com.google.firebase:firebase-common:19.3.0' // Assets/Firebase/Editor/AppDependencies.xml:13 implementation 'com.google.firebase:firebase-config:19.1.4' // Assets/Firebase/Editor/RemoteConfigDependencies.xml:13 implementation 'com.google.firebase:firebase-config-unity:6.15.2' // Assets/Firebase/Editor/RemoteConfigDependencies.xml:20 implementation 'com.google.firebase:firebase-crashlytics:17.0.0' // Assets/Firebase/Editor/CrashlyticsDependencies.xml:13 implementation 'com.google.firebase:firebase-crashlytics-unity:6.15.2' // Assets/Firebase/Editor/CrashlyticsDependencies.xml:20 // Android Resolver Dependencies End **DEPS**} // Android Resolver Exclusions Start android { packagingOptions { exclude ('/lib/arm64-v8a/*' + '*') exclude ('/lib/armeabi/*' + '*') exclude ('/lib/mips/*' + '*') exclude ('/lib/mips64/*' + '*') exclude ('/lib/x86/*' + '*') exclude ('/lib/x86_64/*' + '*') } } // Android Resolver Exclusions End android { compileSdkVersion **APIVERSION** buildToolsVersion '**BUILDTOOLS**' compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } defaultConfig { minSdkVersion **MINSDKVERSION** targetSdkVersion **TARGETSDKVERSION** ndk { abiFilters **ABIFILTERS** } versionCode **VERSIONCODE** versionName '**VERSIONNAME**' consumerProguardFiles 'proguard-unity.txt'**USER_PROGUARD** } lintOptions { abortOnError false } aaptOptions { ignoreAssetsPattern = "!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~" }**PACKAGING_OPTIONS** }**REPOSITORIES** **IL_CPP_BUILD_SETUP** **SOURCE_BUILD_SETUP** **EXTERNAL_SOURCES** android { sourceSets { main { def unityProjectPath = $/file:///**DIR_UNITYPROJECT**/$.replace("\\", "/") res.srcDirs += (unityProjectPath + '/Assets/Plugins/Android/Firebase/res/values/google-services.xml') } } }
org.gradle.jvmargs=-Xmx**JVM_HEAP_SIZE**M org.gradle.parallel=true android.enableR8=**MINIFY_WITH_R_EIGHT** **ADDITIONAL_PROPERTIES** android.useAndroidX=true android.enableJetifier=true
// GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN allprojects { buildscript { repositories {**ARTIFACTORYREPOSITORY** google() jcenter() } dependencies { // If you are changing the Android Gradle Plugin version, make sure it is compatible with the Gradle version preinstalled with Unity // See which Gradle version is preinstalled with Unity here https://docs.unity3d.com/Manual/android-gradle-overview.html // See official Gradle and Android Gradle Plugin compatibility table here https://developer.android.com/studio/releases/gradle-plugin#updating-gradle // To specify a custom Gradle version in Unity, go do "Preferences > External Tools", uncheck "Gradle Installed with Unity (recommended)" and specify a path to a custom Gradle version classpath 'com.android.tools.build:gradle:3.6.0' **BUILD_SCRIPT_DEPS** // Add the Crashlytics Gradle plugin. classpath 'com.google.firebase:firebase-crashlytics-gradle:2.2.0' } } repositories {**ARTIFACTORYREPOSITORY** google() jcenter() flatDir { dirs "${project(':unityLibrary').projectDir}/libs" } } } task clean(type: Delete) { delete rootProject.buildDir }
// GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN apply plugin: 'com.android.application' dependencies { implementation project(':unityLibrary') } android { compileSdkVersion **APIVERSION** buildToolsVersion '**BUILDTOOLS**' compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } defaultConfig { minSdkVersion **MINSDKVERSION** targetSdkVersion **TARGETSDKVERSION** applicationId '**APPLICATIONID**' ndk { abiFilters **ABIFILTERS** } versionCode **VERSIONCODE** versionName '**VERSIONNAME**' } aaptOptions { noCompress = ['.unity3d', '.ress', '.resource', '.obb'**STREAMING_ASSETS**] ignoreAssetsPattern = "!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~" }**SIGN** lintOptions { abortOnError false } buildTypes { debug { minifyEnabled **MINIFY_DEBUG** proguardFiles getDefaultProguardFile('proguard-android.txt')**SIGNCONFIG** jniDebuggable true } release { minifyEnabled **MINIFY_RELEASE** proguardFiles getDefaultProguardFile('proguard-android.txt')**SIGNCONFIG** } }**PACKAGING_OPTIONS****SPLITS** **BUILT_APK_LOCATION** bundle { language { enableSplit = false } density { enableSplit = false } abi { enableSplit = true } } }**SPLITS_VERSION_CODE****LAUNCHER_SOURCE_BUILD_SETUP** // Apply the Crashlytics Gradle plugin apply plugin: 'com.google.firebase.crashlytics'