quickstart-unity: Android app crash caused by using Remote Config with other SDK and EDM4U resolution conflict

[REQUIRED] Please fill in the following fields:

  • Unity editor version: 2019.4.12f1_____
  • Firebase Unity SDK version: 6.16.1_____
  • Source you installed the SDK: Unity Package Manager_____ (.unitypackage or Unity Package Manager)
  • Problematic Firebase Component: remoteConfig_____ (Auth, Database, etc.)
  • Other Firebase Components in use: could messaging, crashlytics, dynamic links. remote config, analytics_____ (Auth, Database, etc.)
  • Additional SDKs you are using: Facebook, IronSource (with a lot of adnetwork adapters[admob…]), EDMU 1.1.161, google play games_____ (Facebook, AdMob, etc.)
  • Platform you are using the Unity editor on: Mac _____ (Mac, Windows, or Linux)
  • Platform you are targeting:Android _____ (iOS, Android, and/or desktop)
  • Scripting Runtime: IL2CPP _____ (Mono, and/or IL2CPP)

[REQUIRED] Please describe the issue here:

(Please list the full steps to reproduce the issue. Include device logs, Unity logs, and stack traces if available.) I’m getting an exception: E/firebase: Unable to find Method com/google/firebase/remoteconfig/FirebaseRemoteConfig.activateFetched (signature '()Z', instance). Please verify the AAR which contains the com/google/firebase/remoteconfig/FirebaseRemoteConfig class is included in your app. things seemed to be working with firebase version 6.16.1 before today but today things stopped working and I think it’s related to new firebase arr files that are being used:

new files:

    <file>Assets/Plugins/Android/com.google.firebase.firebase-abt-20.0.0.aar</file>
    <file>Assets/Plugins/Android/com.google.firebase.firebase-analytics-18.0.0.aar</file>
    <file>Assets/Plugins/Android/com.google.firebase.firebase-auth-20.0.0.aar</file>
    <file>Assets/Plugins/Android/com.google.firebase.firebase-config-20.0.0.aar</file>
    <file>Assets/Plugins/Android/com.google.firebase.firebase-iid-21.0.0.aar</file>
    <file>Assets/Plugins/Android/com.google.firebase.firebase-messaging-21.0.0.aar</file>


old files: ``` <file>Assets/Plugins/Android/com.google.firebase.firebase-abt-19.1.0.aar</file> <file>Assets/Plugins/Android/com.google.firebase.firebase-analytics-17.6.0.aar</file> <file>Assets/Plugins/Android/com.google.firebase.firebase-auth-19.4.0.aar</file> <file>Assets/Plugins/Android/com.google.firebase.firebase-config-19.2.0.aar</file> <file>Assets/Plugins/Android/com.google.firebase.firebase-iid-20.3.0.aar</file> <file>Assets/Plugins/Android/com.google.firebase.firebase-messaging-20.3.0.aar</file>


This seems similar to the issue with crashlytics: https://github.com/firebase/quickstart-unity/issues/758
Why does it use a higher version of the arr file than the one that is supported by the unity sdk?

About this issue

  • Original URL
  • State: open
  • Created 4 years ago
  • Comments: 20 (2 by maintainers)

Most upvoted comments

@cszhongit @lfg-ryan Putting this file in a folder called Editor should solve the problem for now. Feel free to share improvements to the code and make it more generic:

#if UNITY_ANDROID

using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Linq;

using UnityEditor;
using UnityEditor.Build;
#if UNITY_2018_1_OR_NEWER
using UnityEditor.Build.Reporting;
#endif
using UnityEngine;

using System;
using UnityEditor.PackageManager;
//using System.Threading.Tasks;

#if UNITY_2018_1_OR_NEWER
public class PackageCacheDependencyProcessor : IPreprocessBuildWithReport
#else
public class PackageCacheDependencyProcessor : IPreprocessBuild
#endif
{

    private const string FIREBASE_UNITY_VERSION = "6.16.1";

    public int callbackOrder { get { return 0; } }

#if UNITY_2018_1_OR_NEWER
    public void OnPreprocessBuild(BuildReport report)
#else
    public void OnPreprocessBuild(BuildTarget target, string path)
#endif
    {
        string packageCacheFolder = Path.GetFullPath(Path.Combine(Application.dataPath, "../Library/PackageCache"));

        Dictionary<string, string> androidPackageToWantedVersion = new Dictionary<string, string>();
        Dictionary<string, string> androidPackageToDeppendencyFileName = new Dictionary<string, string>();
        Dictionary<string, string> androidPackageNameIdToDeppendencySpecPrefix = new Dictionary<string, string>();

        string packageNameID = "com.google.firebase.remote-config";
        string deppendencySpecPrefix = "com.google.firebase:firebase-config";
        androidPackageNameIdToDeppendencySpecPrefix[packageNameID] = deppendencySpecPrefix;
        androidPackageToWantedVersion[packageNameID] = "19.2.0";
        androidPackageToDeppendencyFileName[packageNameID] = "remoteConfigDependencies.xml";


        foreach (var packageNameIDKey in androidPackageToWantedVersion.Keys)
        {            
            var package = UnityEditor.PackageManager.Client.Search(packageNameID, true);
            //if (package == null || package.Result == null || package.Result.Count() == 0)
            //{
            //    StopBuildWithMessage(packageNameID + " package is missing. check installed packages or that name matches package.");
            //}
            for (var i = 0; i < 100; ++i)
            {

                if (package.Status != StatusCode.InProgress) break;

                System.Threading.Thread.Sleep(100);

            }
            if (package.Status != StatusCode.Success)
            {
                StopBuildWithMessage(packageNameID + " package is missing. check installed packages or that name matches package. " + $"{package.Status}/{package.Error?.message}");
            }
            if (package.Result.Count() == 0)
            {
                StopBuildWithMessage(packageNameID + " package is missing. check installed packages or that name matches package.");
            }

            var result = package.Result.First();
            if (result.version != FIREBASE_UNITY_VERSION)
            {
                StopBuildWithMessage(packageNameIDKey + " used version " + result.version + " doesnt match version defined in PackageCacheDependencyProcessor " + FIREBASE_UNITY_VERSION + " - adjust dictionary in code.");

            }
            //result.resolvedPath
            string firebaseFolder = result.resolvedPath; // string.Format("{0}@{1}", packageNameIDKey, FIREBASE_UNITY_VERSION); // "com.google.firebase.remote-config@6.16.1";            
            if (!androidPackageToDeppendencyFileName.ContainsKey(packageNameIDKey))
            {
                StopBuildWithMessage(packageNameIDKey + " is missing deppendency file name. Add to dictionary in code.");
            }
            string dependencyFileName = androidPackageToDeppendencyFileName[packageNameIDKey]; // "remoteConfigDependencies.xml";
            string dependenciesXmlPath = Path.Combine(packageCacheFolder, firebaseFolder,"Firebase","Editor", dependencyFileName);
            
            XDocument dependencies = null;
            try
            {
                dependencies = XDocument.Load(dependenciesXmlPath);
            }
    #pragma warning disable 0168
            catch (IOException e)
    #pragma warning restore 0168
            {
                StopBuildWithMessage(dependencyFileName + " is missing. Try re-importing the plugin.");
            }

            XElement elemDependencies = dependencies.Element("dependencies");
            if (elemDependencies == null)
            {
                StopBuildWithMessage(dependencyFileName + " is not valid. Try re-importing the plugin.");
            }

            XElement elemAndroidPackages = elemDependencies.Element("androidPackages");
            if (elemAndroidPackages == null)
            {
                StopBuildWithMessage(dependencyFileName + " is not valid. Try re-importing the plugin.");
            }

            IEnumerable<XElement> androidPackages = elemAndroidPackages.Descendants()
                    .Where(elem => elem.Name.LocalName.Equals("androidPackage"));
            string androidPackageNamePrefix = packageNameIDKey + ":"; // "com.google.firebase:firebase-config:"
            if (androidPackageNameIdToDeppendencySpecPrefix.ContainsKey(packageNameID))
            {
                androidPackageNamePrefix = androidPackageNameIdToDeppendencySpecPrefix[packageNameID] + ":";
            }
            var androidPackageElement = GetAndroidPackageElement(androidPackages, androidPackageNamePrefix);
            if (androidPackageElement != null)
            {
                string newspec = string.Format("{0}[{1}]",androidPackageNamePrefix, androidPackageToWantedVersion[packageNameIDKey]);
                androidPackageElement.SetAttributeValue("spec", newspec); // androidPackageElement.SetAttributeValue("spec", "com.google.firebase:firebase-config:[19.2.0]");
            }
            else
            {
                Debug.LogWarning("couldnt find spec " + androidPackageNamePrefix+  " in " + dependencyFileName);
            }
            elemDependencies.Save(dependenciesXmlPath);
        }

       

    }
    private XElement GetAndroidPackageElement(IEnumerable<XElement> androidPackages, string SpecNamePre)
    {
        foreach (XElement elem in androidPackages)
        {
            IEnumerable<XAttribute> attrs = elem.Attributes();
            foreach (XAttribute attr in attrs)
            {
                if (attr.Name.LocalName.Equals("spec") && attr.Value.StartsWith(SpecNamePre))
                {
                    return elem;
                }
            }
        }
        return null;
    }

    private void StopBuildWithMessage(string message)
    {
        string prefix = "[PackageCacheDependencyProcessor] ";
#if UNITY_2017_1_OR_NEWER
        throw new BuildPlayerWindow.BuildMethodException(prefix + message);
#else
        // Unity 5.6 or lower does not support BuildMethodException.
        // Log an error log instead.
        Debug.LogError(prefix + message);
#endif
    }
}

#endif

@cszhongit @lfg-ryan Putting this file in a folder called Editor should solve the problem for now. Feel free to share improvements to the code and make it more generic:

#if UNITY_ANDROID

using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Linq;

using UnityEditor;
using UnityEditor.Build;
#if UNITY_2018_1_OR_NEWER
using UnityEditor.Build.Reporting;
#endif
using UnityEngine;

using System;
using UnityEditor.PackageManager;
//using System.Threading.Tasks;

#if UNITY_2018_1_OR_NEWER
public class PackageCacheDependencyProcessor : IPreprocessBuildWithReport
#else
public class PackageCacheDependencyProcessor : IPreprocessBuild
#endif
{

    private const string FIREBASE_UNITY_VERSION = "6.16.1";

    public int callbackOrder { get { return 0; } }

#if UNITY_2018_1_OR_NEWER
    public void OnPreprocessBuild(BuildReport report)
#else
    public void OnPreprocessBuild(BuildTarget target, string path)
#endif
    {
        string packageCacheFolder = Path.GetFullPath(Path.Combine(Application.dataPath, "../Library/PackageCache"));

        Dictionary<string, string> androidPackageToWantedVersion = new Dictionary<string, string>();
        Dictionary<string, string> androidPackageToDeppendencyFileName = new Dictionary<string, string>();
        Dictionary<string, string> androidPackageNameIdToDeppendencySpecPrefix = new Dictionary<string, string>();

        string packageNameID = "com.google.firebase.remote-config";
        string deppendencySpecPrefix = "com.google.firebase:firebase-config";
        androidPackageNameIdToDeppendencySpecPrefix[packageNameID] = deppendencySpecPrefix;
        androidPackageToWantedVersion[packageNameID] = "19.2.0";
        androidPackageToDeppendencyFileName[packageNameID] = "remoteConfigDependencies.xml";


        foreach (var packageNameIDKey in androidPackageToWantedVersion.Keys)
        {            
            var package = UnityEditor.PackageManager.Client.Search(packageNameID, true);
            //if (package == null || package.Result == null || package.Result.Count() == 0)
            //{
            //    StopBuildWithMessage(packageNameID + " package is missing. check installed packages or that name matches package.");
            //}
            for (var i = 0; i < 100; ++i)
            {

                if (package.Status != StatusCode.InProgress) break;

                System.Threading.Thread.Sleep(100);

            }
            if (package.Status != StatusCode.Success)
            {
                StopBuildWithMessage(packageNameID + " package is missing. check installed packages or that name matches package. " + $"{package.Status}/{package.Error?.message}");
            }
            if (package.Result.Count() == 0)
            {
                StopBuildWithMessage(packageNameID + " package is missing. check installed packages or that name matches package.");
            }

            var result = package.Result.First();
            if (result.version != FIREBASE_UNITY_VERSION)
            {
                StopBuildWithMessage(packageNameIDKey + " used version " + result.version + " doesnt match version defined in PackageCacheDependencyProcessor " + FIREBASE_UNITY_VERSION + " - adjust dictionary in code.");

            }
            //result.resolvedPath
            string firebaseFolder = result.resolvedPath; // string.Format("{0}@{1}", packageNameIDKey, FIREBASE_UNITY_VERSION); // "com.google.firebase.remote-config@6.16.1";            
            if (!androidPackageToDeppendencyFileName.ContainsKey(packageNameIDKey))
            {
                StopBuildWithMessage(packageNameIDKey + " is missing deppendency file name. Add to dictionary in code.");
            }
            string dependencyFileName = androidPackageToDeppendencyFileName[packageNameIDKey]; // "remoteConfigDependencies.xml";
            string dependenciesXmlPath = Path.Combine(packageCacheFolder, firebaseFolder,"Firebase","Editor", dependencyFileName);
            
            XDocument dependencies = null;
            try
            {
                dependencies = XDocument.Load(dependenciesXmlPath);
            }
    #pragma warning disable 0168
            catch (IOException e)
    #pragma warning restore 0168
            {
                StopBuildWithMessage(dependencyFileName + " is missing. Try re-importing the plugin.");
            }

            XElement elemDependencies = dependencies.Element("dependencies");
            if (elemDependencies == null)
            {
                StopBuildWithMessage(dependencyFileName + " is not valid. Try re-importing the plugin.");
            }

            XElement elemAndroidPackages = elemDependencies.Element("androidPackages");
            if (elemAndroidPackages == null)
            {
                StopBuildWithMessage(dependencyFileName + " is not valid. Try re-importing the plugin.");
            }

            IEnumerable<XElement> androidPackages = elemAndroidPackages.Descendants()
                    .Where(elem => elem.Name.LocalName.Equals("androidPackage"));
            string androidPackageNamePrefix = packageNameIDKey + ":"; // "com.google.firebase:firebase-config:"
            if (androidPackageNameIdToDeppendencySpecPrefix.ContainsKey(packageNameID))
            {
                androidPackageNamePrefix = androidPackageNameIdToDeppendencySpecPrefix[packageNameID];
            }
            var androidPackageElement = GetAndroidPackageElement(androidPackages, androidPackageNamePrefix);
            if (androidPackageElement != null)
            {
                string newspec = string.Format("{0}[{1}]",androidPackageNamePrefix, androidPackageToWantedVersion[packageNameIDKey]);
                androidPackageElement.SetAttributeValue("spec", newspec); // androidPackageElement.SetAttributeValue("spec", "com.google.firebase:firebase-config:[19.2.0]");
            }
            else
            {
                Debug.LogWarning("couldnt find spec " + androidPackageNamePrefix+  " in " + dependencyFileName);
            }
            elemDependencies.Save(dependenciesXmlPath);
        }

       

    }
    private XElement GetAndroidPackageElement(IEnumerable<XElement> androidPackages, string SpecNamePre)
    {
        foreach (XElement elem in androidPackages)
        {
            IEnumerable<XAttribute> attrs = elem.Attributes();
            foreach (XAttribute attr in attrs)
            {
                if (attr.Name.LocalName.Equals("spec") && attr.Value.StartsWith(SpecNamePre))
                {
                    return elem;
                }
            }
        }
        return null;
    }

    private void StopBuildWithMessage(string message)
    {
        string prefix = "[PackageCacheDependencyProcessor] ";
#if UNITY_2017_1_OR_NEWER
        throw new BuildPlayerWindow.BuildMethodException(prefix + message);
#else
        // Unity 5.6 or lower does not support BuildMethodException.
        // Log an error log instead.
        Debug.LogError(prefix + message);
#endif
    }
}

#endif

this is a great answer ,it’s useful for me .Thank you!