Skip to content

[Bug] Remote config fetch seems to hang forever after SDK update. #1198

Closed
@pihels

Description

@pihels

[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;
     });
 }

}

remoteconfigfailure(1).txt
remoteconfigsuccess(1).txt

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions