Description
[REQUIRED] Please fill in the following fields:
- Unity editor version: 2021.1.24f1
- Firebase Unity SDK version: 8.5.0, 8.1.0, 7.2.0
- Source you installed the SDK: Added .tgz archives to Packages folder and manifest.json
- Problematic Firebase Component: Remote Config (Auth, Database, etc.)
- Other Firebase Components in use: Auth, Analytics, Firestore, Messaging, Crashlytics
- Additional SDKs you are using: Google Sign-In
- Platform you are using the Unity editor on: Mac
- Platform you are targeting: iOS
- Scripting Runtime: IL2CPP
[REQUIRED] Please describe the issue here:
After updating Firebase Unity libraries from 6.15.2 (everything works fine here) to 8.1.0 fetching the remote config values does not complete. There are no errors in console that I noticed.
The issue seems to happen when I start the fetch task:
System.Threading.Tasks.Task fetchTask = Firebase.RemoteConfig.FirebaseRemoteConfig.DefaultInstance.FetchAsync (new TimeSpan (12, 0, 0));
Seems like this fetch hangs indefinitely, doesn't give an error and doesn't complete successfully. When I tried to do another fetch a few seconds later, I got the error about duplicate fetches (can't recall the exact error).
Steps to reproduce:
The issue seems to happen randomly (works half the time, doesn't work the other half) on all our iOS test devices (my device has iOS 14). Everything works on Android.
I attached device logs for the successful and unsuccessful fetches. For the success you can see "Fetching firebase remote config data successful." logged in the end.
Relevant Code:
Below is the code I use for Firebase setup and fetching. I noticed that with the new libraries I have to use FirebaseRemoteConfig.DefaultInstance. So maybe I am missing some crucial step about setting the DefaultInstance? I looked through the tutorials and quickstart examples and can't see anything missing.
Firebase initialization script:
using Firebase;
using UnityEngine;
using UnityEngine.Events;
public class FirebaseInitializer : MonoBehaviour {
public UnityEvent onInitialized = new UnityEvent ();
public FirebaseApp app;
void Start () {
UnityEngine.Debug.Log ("Trying to initialize firebase...");
Firebase.FirebaseApp.CheckAndFixDependenciesAsync ().ContinueWith (task => {
var dependencyStatus = task.Result;
if (dependencyStatus == Firebase.DependencyStatus.Available) {
// Create and hold a reference to your FirebaseApp,
// where app is a Firebase.FirebaseApp property of your application class.
app = FirebaseApp.DefaultInstance;
// Set a flag here to indicate whether Firebase is ready to use by your app.
// Analytics
Firebase.Analytics.FirebaseAnalytics.SetAnalyticsCollectionEnabled (true);
Firebase.Analytics.FirebaseAnalytics.LogEvent (Firebase.Analytics.FirebaseAnalytics.EventAppOpen);
// Messaging (Push Notifications)
Firebase.Messaging.FirebaseMessaging.TokenReceived += OnTokenReceived;
Firebase.Messaging.FirebaseMessaging.MessageReceived += OnMessageReceived;
UnityEngine.Debug.Log ("Firebase initialized!");
onInitialized.Invoke ();
} else {
UnityEngine.Debug.LogError (System.String.Format (
"Could not resolve all Firebase dependencies: {0}", dependencyStatus));
}
});
}
}
Remote config script
public class FirebaseRemoteConfigManager : MonoBehaviour {
public UnityEvent onConfigLoaded = new UnityEvent ();
public UnityEvent onConfigInitialized = new UnityEvent ();
public bool AreValuesLoaded { get; private set; }
public FirebaseInitializer firebaseInitializer;
void Start () {
firebaseInitializer.onInitialized.RemoveListener (InitializeRemoteConfig);
firebaseInitializer.onInitialized.AddListener (InitializeRemoteConfig);
Debug.Log (LOGGER_PREFIX + "Waiting for firebase initialization...");
}
private void InitializeRemoteConfig () {
Debug.Log (LOGGER_PREFIX + "Initializing firebase remote config...");
Dictionary<string, object> defaults = new Dictionary<string, object> ();
// These are the values that are used if we haven't fetched data from the
// server yet, or if we ask for values that the server doesn't have:
defaults.Add ("test_key", false);
Firebase.RemoteConfig.FirebaseRemoteConfig.DefaultInstance.SetDefaultsAsync (defaults).ContinueWithOnMainThread (task => {
Debug.Log (LOGGER_PREFIX + LOGGER_PREFIX + "Fetching firebase remote config data...");
onConfigInitialized.Invoke ();
FetchRemoteConfigAsync ();
});
}
// Start a fetch request.
// FetchAsync only fetches new data if the current data is older than the provided
// timespan. Otherwise it assumes the data is "recent enough", and does nothing.
// By default the timespan is 12 hours, and for production apps, this is a good
// number. For this example though, it's set to a timespan of zero, so that
// changes in the console will always show up immediately.
public void FetchRemoteConfigAsync () {
System.Threading.Tasks.Task fetchTask = Firebase.RemoteConfig.FirebaseRemoteConfig.DefaultInstance.FetchAsync (new TimeSpan (12, 0, 0)); //change to TimeSpan.Zero only for dev testing purposes
fetchTask.ContinueWith (task => {
if (task.Exception != null) {
Debug.LogError (LOGGER_PREFIX + "Fetching firebase remote config data failed. " + task.Exception.Message);
return;
}
if (task.IsCanceled) {
Debug.LogError (LOGGER_PREFIX + "Fetching firebase remote config data canceled.");
return;
}
var info = Firebase.RemoteConfig.FirebaseRemoteConfig.DefaultInstance.Info;
Debug.Log (LOGGER_PREFIX + "Info last fetch status " + info.LastFetchStatus);
System.Threading.Tasks.Task activateTask = Firebase.RemoteConfig.FirebaseRemoteConfig.DefaultInstance.ActivateAsync ();
activateTask.ContinueWith (task => {
Debug.Log (LOGGER_PREFIX + "Fetching firebase remote config data successful. Activated " + activateTask.Status.ToString ());
OnFetchComplete ();
});
});
}
private void OnFetchComplete () {
UnityMainThread.wkr.AddJob (() => {
onConfigLoaded.Invoke ();
AreValuesLoaded = true;
});
}
}