quickstart-unity: Freeze on FirebaseRemoteConfig.ActivateFetched() Unity 2017.4.6f1 Android
When calling FirebaseRemoteConfig.ActivateFetched() at the start of the app, at first frame, the app gets stuck in launch screen image. There seem to be no apparent errors in “adb logcat” output. This normally happens with 95% chance.
Deferring the ActivateFetched call by 100ms reduces the chances of getting this launch freeze a lot. In this case, chances of freezing is around 5%.
This is how my current initialization code looks like:
Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task =>
{
var dependencyStatus = task.Result;
MainThreadDeferer.Instance.CallOnUnityThread(() =>
{
if (Debug.isDebugBuild)
Debug.LogFormat("Firebase.DependencyStatus: {0}", dependencyStatus);
if (dependencyStatus == Firebase.DependencyStatus.Available)
{
// Fetch and activate firebase remote config data.
Run.AfterRealtime(0.1f, () => // WARNING: Without this ActivateFetched gets stuck on Android sometimes.
{
Firebase.RemoteConfig.FirebaseRemoteConfig.ActivateFetched();
Firebase.RemoteConfig.FirebaseRemoteConfig.FetchAsync().ContinueWith(task2 =>
{
MainThreadDeferer.Instance.CallOnUnityThread(() =>
{
if (Debug.isDebugBuild)
Debug.LogFormat("Fetched firebase remote config");
Firebase.RemoteConfig.FirebaseRemoteConfig.ActivateFetched();
});
});
});
}
else
{
UnityEngine.Debug.LogError(System.String.Format(
"Could not resolve all Firebase dependencies: {0}", dependencyStatus));
// Firebase Unity SDK is not safe to use here.
}
});
});
MainThreadDeferer.Instance.CallOnUnityThread calls are there to defer the callbacks to main unity thread, just to make sure that task callbacks are not called in a separate thread.
Runtime I am on is Mono with .NET 2.0 Subset. Stripping level is set to “micro mscorlib”. Min API level is Android 4.1, the target is Android 8.0. Building for ARMv7 arch.
I am puzzled by what might be causing the problem of being stuck. I wish firebase unity integration code was open source, would be pretty easy to understand what is going on. I assume that call is using some async API internally and waiting for the result in a while loop, just to be able to return the “bool” value. Then again, the Java API for activateFetched is not an async call. However, maybe, to get the call to the right thread, some async operation is going on there.
Would be great to get some help with this. I spent half the day battling with the error, still no clear solution. Deferring the ActivateFetched call by a constant time reduces chances of the problem happening, but doesn’t fully solve it.
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 25 (7 by maintainers)
@stewartmiles Great! Thanks!!!
While reading the changelog, I noticed this: “Firebase now throws an exception if any Firebase libraries are initialized while CheckAndFixDependenciesAsync() is still in progress.”. This addresses my main complaint fully.
Thanks once again! ❤️
Ok, after spending 2 more days on it, I distilled our big project into a small case where I can create the freeze. It basically occurs when Firebase.FirebaseApp.CheckAndFixDependenciesAsync() called followed by a SceneManager.LoadScene() call, and then in the loaded scene, calling FirebaseRemoteConfig.GetValue(), it instantly freezes at that point. Once again, no exceptions, no logs.
Here is a sample project showing the freeze: https://drive.google.com/open?id=1-0N9M85SeUF4nNi1JJ716vhUOziyuMmn
If I move the SceneManager.LoadScene call within the ContinueWith callback of Firebase.FirebaseApp.CheckAndFixDependenciesAsync(), the freeze doesn’t occur.
As I understand, only proper solution from our side is to make an independent load scene for firebase, and initialize it before we initialize anything else, but since it is async, it will go from our launch screen image to black screen (firebase initialize scene) then the actual intro scene, where we start initializing things which may be using firebase. Or wrap the whole firebase remote config API, cache the previous results ourselves, and use the previous value results if firebase callback is not called yet. Definitely not going for this option…
We are probably not going with a workaround like this since my trust in Firebase Unity SDK got fully crushed. We will opt for not using Firebase for our Unity based projects until all these possible cases of thread lock freezes disappear. As I mentioned before, under no condition an API should just block. Especially, when it is not a threading primitive itself or an async object. Also nowhere in Firebase Unity SDK docs it is mentioned that calling Firebase functions before CheckAndFixDependenciesAsync callback returns might lead to thread freezes.
Another suggestion would be to rename the CheckAndFixDependenciesAsync function. That naming completely sounds like an operation that is just there to check the dependencies. Not something that initializes an SDK and SDK being usable only after that async op completes.