Search Unity

Bug Remote config Cache is working only the first time while disconnected

Discussion in 'Unity Remote Config' started by FranArjona, Jan 15, 2022.

  1. FranArjona

    FranArjona

    Joined:
    Oct 25, 2015
    Posts:
    17
    Hello everyone,

    I have setup a basic workflow in which as we could expect:
    1. I set data first from Default values
    2. Then a handler tries to retrieve data from Remote
    3. If no connection, Cache acts
    4. If none of them, then Default data appears
    It was working well until I saw an odd case and I cannot find anything particularly wrong in the code.

    This is the flow I follow and this part is working well so far:
    • Create a variable in remote config and code (default). Assign a different value for both
    • Load it once with the Internet ON and it works => It gets the last remote value
    • Disconnect the Internet and stop the app
    • Pay and check the variable and confirmed => It gets the last remote config value (cached)
    • Stop the editor/mobile and play again, still with the Internet OFF
    Expected:
    • The value is still retrieved from the last remote value (2 connections ago)
    Reality:
    • The value has been reset to the default value. In fact, I can check and the key and value don't exist from the 2nd connection onwards (using ConfigManager.appConfig.HasKey())

    So the flow works well in general: default values, remote values and cache. But from the second consecutive session that I try to get data while disconnected, I can see the cache has been lost, as in cache only works based on the very last session.

    I wonder if this is by design for some reason (please explain why in that case) or just a bug. In the second case, I can report it.

    I don't think the code is needed, but I'll leave it as a reference or to confirm that :
    Code (CSharp):
    1.         void Awake()
    2.         {
    3.             // Singleton before
    4.             //...
    5.  
    6.             AssignAppRemoteConfigDefaults();
    7.  
    8.             ConfigManager.FetchCompleted += ApplyRemoteSettingsHandler;
    9.  
    10.             ConfigManager.SetEnvironmentID(Settings.RemoteConfigEnvironmentId);
    11.  
    12.             ConfigManager.SetCustomUserID(AnalyticsSessionInfo.userId);
    13.  
    14.             ConfigManager.FetchConfigs<UserAttributes, AppAttributes>(new UserAttributes(), new appAttributes());
    15.         }
    16.  
    17.         private static void AssignAppRemoteConfigDefaults()
    18.         {
    19.             AppRemoteConfig.MyStaticVariable = AppRemoteConfig.DefaultMyStaticVariable;
    20.         }
    21.  
    22.         // Apply remote settings handler
    23.         private void ApplyRemoteSettingsHandler(ConfigResponse configResponse)
    24.         {
    25.             // Conditionally update settings, depending on the response's origin:
    26.             switch (configResponse.requestOrigin) {
    27.                 case ConfigOrigin.Default:
    28.                     break;
    29.                 // BTW, I have seen another potential bug here in which ConfigOrigin.Cached redirects to ConfigOrigin.Remote. It doesn't make a difference, though
    30.                 case ConfigOrigin.Cached:
    31.                 case ConfigOrigin.Remote:
    32.                     // I have also tried to remove Defaults from here as in the docs, but the same problem
    33.                     AppRemoteConfig.MyStaticVariable = ConfigManager.appConfig.GetInt("myStaticVariable", AppRemoteConfig.DefaultMyStaticVariable);
    34.                     assignmentId = ConfigManager.appConfig.assignmentId;
    35.                     break;
    36.             }
    37.         }
     
  2. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    @FranArjona You have no code for the Cached and Default switch conditions. Please share the code you are using for your test.
     
  3. FranArjona

    FranArjona

    Joined:
    Oct 25, 2015
    Posts:
    17
    Sure, my code is following the given example, so that's the reason Default and Cached don't have code: https://docs.unity3d.com/Packages/com.unity.remote-config@2.1/manual/CodeIntegration.html

    Code (CSharp):
    1.  
    2.        switch (configResponse.requestOrigin) {
    3.            case ConfigOrigin.Default:
    4.                Debug.Log ("No settings loaded this session; using default values.");
    5.                break;
    6.            case ConfigOrigin.Cached:
    7.                Debug.Log ("No settings loaded this session; using cached values from a previous session.");
    8.                break;
    9.            case ConfigOrigin.Remote:
    10.                // AppRemoteConfig.MyStaticVariable and AppRemoteConfig.DefaultMyStaticVariable are just static integers from another file
    11.                AppRemoteConfig.MyStaticVariable = ConfigManager.appConfig.GetInt("myStaticVariable", AppRemoteConfig.DefaultMyStaticVariable);
    12.                assignmentId = ConfigManager.appConfig.assignmentId;
    13.                break;
    14.        }
    15.  
    And on top of that I already checked the forum to avoid asking the same and you mention to do that:
    https://forum.unity.com/threads/offline-but-configorigin-set-to-remote.973752/#post-7401758

    I'll clarify the use cases again. Every use case is tested by stopping the application, connecting/disconnecting the Internet physically and Play in the editor again:
    - Normal testing connected to the Internet. It retrieves REMOTE config. WORKING
    - Disconnecting the Internet. It retrieves the previous REMOTE data. WORKING
    - Keep the Internet disconnected and repeating again. It retrieves the DEFAULT config instead of the LAST REMOTE data. NOT WORKING or not working as I would expect (correct me if I'm wrong)

    Again, the basic use cases are working, I just think it cache doesn't work after the second attempt, by a bug or by design. (I have the feeling the cache file is removed after being read once)
     
  4. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Sorry I don't see where you are debugging your scenarios. How are you debugging? Where are you seeing the last remote data? I would recommend Debug.Log the actual values you are receiving. You are only outputting a static string. Also, ensure to be using RC 3.0.0-pre.9
     
  5. FranArjona

    FranArjona

    Joined:
    Oct 25, 2015
    Posts:
    17
    Yes, I was debugging using Debug.Log, I just removed all the debugging code from the snippet.

    I was using it directly on the source value. I also checked the key to see if I was doing something wrong:
    Debug.Log(ConfigManager.appConfig.HasKey("interstitialAdsFrequency"));
    Debug.Log(ConfigManager.appConfig.GetInt("interstitialAdsFrequency"));

    And the results were:
    - Internet ON=> Right value (from remote), the key existed
    - Internet OFF (first attempt) => Right value (from cache), the key existed
    - Internet OFF (second consecutive attempt) => Wrong value (0), the key didn't exist

    I tried this several times to confirm it was a consistent result.
     
  6. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Please share the actual code that I would use to attempt to reproduce your issue.
     
  7. FranArjona

    FranArjona

    Joined:
    Oct 25, 2015
    Posts:
    17
    Thank you, I appreciate the support.

    I have removed extra comments/features to simplify it for your test. I have also retested it right now to confirm it keeps not working/as expected. Hopefully you are able to reproduce it (notice the only thing I cannot provide is the Settings.RemoteConfigEnvironmentId as it is a personal credential. I can share it via MP if you need to)

    Notice the default value is 60 and the Remote is 70.

    The test I just did again to confirm it displayed in Debug.Log:
    - Internet ON. Play in Editor => True, 70 (WORKING)
    - Stop. Internet OFF. Play => True, 70 (WORKING)
    - Stop. Internet remains OFF. Play => False, 0 (NOT WORKING)

    Code (csharp):
    1. using Config;
    2. using Unity.RemoteConfig;
    3. using UnityEngine;
    4. using UnityEngine.Analytics;
    5.  
    6. namespace Controllers.Global
    7. {
    8.     public class GlobalRemoteConfigProvider : MonoBehaviour
    9.     {
    10.         private static int _interstitialAdsFrequency;
    11.         private static readonly int DefaultInterstitialAdsFrequency = 60;
    12.  
    13.         private struct UserAttributes {
    14.         }
    15.         private struct AppAttributes {
    16.             public string appVersion;
    17.         }
    18.         public string assignmentId;
    19.  
    20.         void Awake()
    21.         {
    22.             // Defaults
    23.             _interstitialAdsFrequency = DefaultInterstitialAdsFrequency;
    24.             // Remote config
    25.             ConfigManager.FetchCompleted += ApplyRemoteSettingsHandler;
    26.             // THIS NEEDS TO BE REPLACED WITH YOUR ENVIRONMENT ID
    27.             ConfigManager.SetEnvironmentID(Settings.RemoteConfigEnvironmentId);
    28.             ConfigManager.SetCustomUserID(AnalyticsSessionInfo.userId);
    29.             ConfigManager.FetchConfigs<UserAttributes, AppAttributes>(new UserAttributes(), new AppAttributes());
    30.         }
    31.  
    32.         private void ApplyRemoteSettingsHandler(ConfigResponse configResponse)
    33.         {
    34.             switch (configResponse.requestOrigin) {
    35.                 case ConfigOrigin.Default:
    36.                     Debug.Log ("No settings loaded this session; using default values.");
    37.                     break;
    38.                 case ConfigOrigin.Cached:
    39.                     Debug.Log ("No settings loaded this session; using cached values from a previous session.");
    40.                     break;
    41.                 case ConfigOrigin.Remote:
    42.                     Debug.Log(ConfigManager.appConfig.HasKey("interstitialAdsFrequency").ToString());
    43.                     Debug.Log(ConfigManager.appConfig.GetInt("interstitialAdsFrequency").ToString());
    44.                     _interstitialAdsFrequency = ConfigManager.appConfig.GetInt("interstitialAdsFrequency", DefaultInterstitialAdsFrequency);
    45.                     assignmentId = ConfigManager.appConfig.assignmentId;
    46.                     break;
    47.             }
    48.         }
    49.     }
    50. }
    51.  
     
    Last edited: Jan 18, 2022
  8. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    @FranArjona Again, you are not retrieving and writing out the values in the Default or Cached switch case, only Remote.
     
  9. FranArjona

    FranArjona

    Joined:
    Oct 25, 2015
    Posts:
    17
    Yes, I already replied to that, because I'm following what is explained here:
    https://docs.unity3d.com/Packages/com.unity.remote-config@2.1/manual/CodeIntegration.html
    And also what you mention here (cache should work automatically):
    https://forum.unity.com/threads/offline-but-configorigin-set-to-remote.973752/#post-7401758

    But the key is understanding that those switch cases are even NOT ACCESSED in my tests anyway. You can see there is a log line and it's never printed out. I cannot see these messages at all in the whole flow, so it doesn't matter what I put in there:
    Debug.Log("No settings loaded this session; using default values.");
    Debug.Log("No settings loaded this session; using cached values from a previous session.");

    I can see only what I posted above. I know people come from different backgrounds and I could be mistaken or not understanding the expected behaviour, but I'd like you to try if you can, please (Unity 2021.2.8f1, btw), because this looks like a bug.

    I hope I'm explaining myself well and you are able to have the same findings. Thanks.
     
  10. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    If there is no internet and the user has not connected previously, the Default case would be executed. If there is no internet and the user has connected previously, the Cached case would be executed. This is done "automatically". And ensure to be using 3.0.0-pre.9.
     
  11. FranArjona

    FranArjona

    Joined:
    Oct 25, 2015
    Posts:
    17
    Ok, in case this is helpful for anyone
    Ok, thank you. I'm using the latest stable version 2.1.2, but, sure, I'll give it a try to the 3.0.0 pre-release version.