Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Join us on Dec 8, 2022, between 7 am & 7 pm EST, in the DOTS Dev Blitz Day 2022 - Q&A forum, Discord, and Unity3D Subreddit to learn more about DOTS directly from the Unity Developers.
    Dismiss Notice
  3. Have a look at our Games Focus blog post series which will show what Unity is doing for all game developers – now, next year, and in the future.
    Dismiss Notice

get appconfig always return null

Discussion in 'Unity Remote Config' started by IllogicalGames, Feb 2, 2020.

Thread Status:
Not open for further replies.
  1. IllogicalGames

    IllogicalGames

    Joined:
    Apr 16, 2013
    Posts:
    156
    Hi guys,
    Im stuck for 3 hours for this now. i dont know whats wrong. whatever i do, i always get null for every getstring i requested from the remote config dashboard.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5. using Unity.RemoteConfig;
    6. using UnityEngine.SceneManagement;
    7. namespace TanksMP
    8. {
    9.     public class VersionControl : MonoBehaviour
    10.     {
    11.         public Text message;
    12.         public GameObject okButton;
    13.         public FeatureRandomizer feature;
    14.         void Start()
    15.         {
    16.             ConfigManager.FetchCompleted += ApplyRemoteSettings;
    17.             okButton.SetActive(false);
    18.         }
    19.         public void RestartGame()
    20.         {
    21.             SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
    22.         }
    23.         void ApplyRemoteSettings(ConfigResponse configResponse)
    24.         {
    25.             switch (configResponse.requestOrigin)
    26.             {
    27.                 case ConfigOrigin.Default:
    28.                     Debug.Log("No settings loaded this session; using default values.");
    29.                     string[] defaultStoreItems = { "6", "4", "7", "12", "16", "18", "3", "5", "2", "13", "5", "9", "20" };
    30.                     feature.readList(defaultStoreItems);
    31.                     gameObject.SetActive(false);
    32.                     break;
    33.                 case ConfigOrigin.Cached:
    34.                     Debug.Log("No settings loaded this session; using cached values from a previous session.");
    35.                     break;
    36.                 case ConfigOrigin.Remote:
    37.                     Debug.Log("New settings loaded this session; update values accordingly.");
    38.  
    39.                     bool outdated = true;
    40.                     string[] str = ConfigManager.appConfig.GetString("live_version").Split(';');
    41.                     for (int a = 0; a < str.Length; a++)
    42.                     {
    43.                         if (str[a] == Application.version.ToString()) outdated = false;
    44.                     }
    45.                     if (outdated)
    46.                     {
    47.                         message.text = "<size=22>Version Outdated</size>\nUpdate to the latest version to play the game.";
    48.                         okButton.SetActive(false);
    49.                     }
    50.  
    51.                     string[] storeItems = ConfigManager.appConfig.GetString("store_item").Split(';');
    52.                     feature.readList(storeItems);
    53.  
    54.                     message.text = ConfigManager.appConfig.GetString("message");
    55.                     if (message.text == "") gameObject.SetActive(false);
    56.                     okButton.SetActive(true);
    57.  
    58.                     break;
    59.             }
    60.         }
    61.     }
    62. }
    and here is my dashboard

    upload_2020-2-2_17-12-23.png
     
  2. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    Those are your local settings, have you Pushed them to the online Dashboard? Can you click the View in Dashboard button to confirm?
     
    vd_unity likes this.
  3. IllogicalGames

    IllogicalGames

    Joined:
    Apr 16, 2013
    Posts:
    156
    it is pushed. i got the script working now.

    but i sometimes i get "incomplete" strings. for example, i use the remote config for item rotation. i would store all the items in a string and split them into array. when i get the array, it sometimes only get the first string. for example

    storeItem[0] = itemA
    storeItem[1]-[13] = null

    at first i thought theres error in my script. but when i test it again, it worked. it only happen sometime.
     
  4. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    Can you share the full script that you are using, and the corresponding dashboard settings? Are you receiving the full string, but the parsing fails? I doubt that we would return only the first x number of characters from a string, but we can check.
     
  5. IllogicalGames

    IllogicalGames

    Joined:
    Apr 16, 2013
    Posts:
    156
    Code (CSharp):
    1.  
    2. {
    3.     public class VersionControl : MonoBehaviour
    4.     {
    5.         public Text title;
    6.         public Text message;
    7.         public GameObject okButton;
    8.         public GameObject restartButton;
    9.         public FeatureRandomizer feature;
    10.         public struct userAttributes
    11.         {
    12.             // Optionally declare variables for any custom user attributes; if none keep an empty struct:
    13.         }
    14.  
    15.         public struct appAttributes
    16.         {
    17.             // Optionally declare variables for any custom app attributes; if none keep an empty struct:
    18.         }
    19.         void Start()
    20.         {
    21.             StartCoroutine(queuedVersionCheck());
    22.         }
    23.         IEnumerator queuedVersionCheck()
    24.         {
    25.             yield return new WaitForSeconds(1);
    26.             ConfigManager.FetchCompleted += ApplyRemoteSettings;
    27.             ConfigManager.FetchConfigs<userAttributes, appAttributes>(new userAttributes(), new appAttributes());
    28.             yield return new WaitForSeconds(10);
    29.         }
    30.         void ApplyRemoteSettings(ConfigResponse configResponse)
    31.         {
    32.             string[] storeItems = { "6", "4", "7", "12", "16", "18", "3", "5", "2", "13", "5", "9", "20" };
    33.             string[] str= {""};
    34.             switch (configResponse.requestOrigin)
    35.             {
    36.                 case ConfigOrigin.Default:
    37.                     Debug.Log("No settings loaded this session; using default values.");
    38.                     gameObject.SetActive(false);
    39.                     break;
    40.                 case ConfigOrigin.Cached:
    41.                     Debug.Log("No settings loaded this session; using cached values from a previous session.");
    42.  
    43.                     storeItems = ConfigManager.appConfig.GetString("store_item").Split(';');
    44.                     str = ConfigManager.appConfig.GetString("live_version").Split(';');
    45.                     break;
    46.                 case ConfigOrigin.Remote:
    47.                     Debug.Log("New settings loaded this session; update values accordingly.");
    48.                    
    49.                     storeItems = ConfigManager.appConfig.GetString("store_item").Split(';');
    50.                     str = ConfigManager.appConfig.GetString("live_version").Split(';');                  
    51.                     break;
    52.             }
    53.             bool outdated = true;
    54.             for (int a = 0; a < str.Length; a++)
    55.             {
    56.                 if (str[a] == Application.version.ToString()) outdated = false;
    57.             }
    58.             if (outdated)
    59.             {
    60.                 title.text = "Version Outdated";
    61.                 message.text = "Update to the latest version to play the game.";
    62.                 restartButton.SetActive(true);
    63.             }
    64.             else
    65.             {
    66.                 StopAllCoroutines();
    67.                 okButton.SetActive(true);
    68.                 title.text = ConfigManager.appConfig.GetString("title");
    69.                 message.text = ConfigManager.appConfig.GetString("message");
    70.                 if (message.text == "") gameObject.SetActive(false);
    71.             }
    72.             ConfigManager.FetchCompleted -= ApplyRemoteSettings;
    73.             if (storeItems.Length < 13) RestartGame();
    74.             else StartCoroutine(feature.readList(storeItems));
    75.         }        
    76.     }
    77. }
    as you can see i wrote an if statement if fetches less than 13, restart the game. it still happen.
     
  6. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    Can you show a screenshot of your value for store_item in the Dashboard? Also, please Debug.Log the full value of the local store_item variable, prior to the Split. And your default value for storeItems is not a single string, it's an array of strings, and may be why you are only seeing the first value.
     
    Last edited: Feb 4, 2020
  7. IllogicalGames

    IllogicalGames

    Joined:
    Apr 16, 2013
    Posts:
    156
    how can the parsing sometimes fail and sometimes it succeed? the parsing works fine IF it gets the full string from the appconfig. it only returns error if it fetches incomplete appconfig.

    here is the new version of the script
    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3. using UnityEngine.UI;
    4. using Unity.RemoteConfig;
    5. using UnityEngine.SceneManagement;
    6.  
    7.     public class VersionControl : MonoBehaviour
    8.     {
    9.         public Text title;
    10.         public Text message;
    11.         public GameObject okButton;
    12.         public GameObject restartButton;
    13.         public FeatureRandomizer feature;
    14.         public Text version;
    15.         public struct userAttributes
    16.         {
    17.             // Optionally declare variables for any custom user attributes; if none keep an empty struct:
    18.         }
    19.  
    20.         public struct appAttributes
    21.         {
    22.             // Optionally declare variables for any custom app attributes; if none keep an empty struct:
    23.         }
    24.         void Start()
    25.         {
    26.             version.text = Application.version.ToString();
    27.             restartButton.SetActive(false);
    28.             okButton.SetActive(false);
    29.             StartCoroutine(queuedVersionCheck());
    30.         }
    31.         public void RestartGame()
    32.         {
    33.             SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
    34.             ConfigManager.FetchCompleted -= ApplyRemoteSettings;
    35.         }
    36.         IEnumerator queuedVersionCheck()
    37.         {
    38.             yield return new WaitForSeconds(1);
    39.             ConfigManager.FetchCompleted += ApplyRemoteSettings;
    40.             ConfigManager.FetchConfigs<userAttributes, appAttributes>(new userAttributes(), new appAttributes());
    41.             yield return new WaitForSeconds(10);
    42.             restartButton.SetActive(true);
    43.         }
    44.         void ApplyRemoteSettings(ConfigResponse configResponse)
    45.         {
    46.             string[] storeItems = { "6", "4", "7", "12", "16", "18", "3", "5", "2", "13", "5", "9", "20" };
    47.             string[] str= {""};
    48.             switch (configResponse.requestOrigin)
    49.             {
    50.                 case ConfigOrigin.Default:
    51.                     Debug.Log("No settings loaded this session; using default values.");
    52.                     gameObject.SetActive(false);
    53.                     break;
    54.                 case ConfigOrigin.Cached:
    55.                     Debug.Log("No settings loaded this session; using cached values from a previous session.");
    56.  
    57.                     storeItems = ConfigManager.appConfig.GetString("store_item").Split(';');
    58.                     str = ConfigManager.appConfig.GetString("live_version").Split(';');
    59.                     break;
    60.                 case ConfigOrigin.Remote:
    61.                     Debug.Log("New settings loaded this session; update values accordingly.");
    62.                    
    63.                     storeItems = ConfigManager.appConfig.GetString("store_item").Split(';');
    64.                     str = ConfigManager.appConfig.GetString("live_version").Split(';');                  
    65.                     break;
    66.             }
    67.             bool outdated = true;
    68.             for (int a = 0; a < str.Length; a++)
    69.             {
    70.                 if (str[a] == Application.version.ToString()) outdated = false;
    71.             }
    72.             if (outdated)
    73.             {
    74.                 title.text = "Version Outdated";
    75.                 message.text = "Update to the latest version to play the game.";
    76.                 restartButton.SetActive(true);
    77.             }
    78.             else
    79.             {
    80.                 StopAllCoroutines();
    81.                 okButton.SetActive(true);
    82.                 title.text = ConfigManager.appConfig.GetString("title");
    83.                 message.text = ConfigManager.appConfig.GetString("message");
    84.                 if (message.text == "") gameObject.SetActive(false);
    85.             }
    86.             ConfigManager.FetchCompleted -= ApplyRemoteSettings;
    87.             if (storeItems.Length < 13) RestartGame();
    88.             else StartCoroutine(feature.readList(storeItems));
    89.         }        
    90.    
    91. }
    then the storeItem is sent to featurerandomizer below. as you can see, the game restarts when storeitem.length is less than 13.

    when i run it, yes, the game restarts. that means it fetches incomplete strings.


    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5. using System;
    6.  
    7.     public class FeatureRandomizer : MonoBehaviour
    8.     {
    9.         public IAPProduct[] FeatureCards;
    10.         public IAPProduct[] InventoryCards;
    11.  
    12.         public IEnumerator readList(string[] storeList)
    13.         {
    14.             for (int a = 0; a < FeatureCards.Length; a++)
    15.             {
    16.                 populate(System.Convert.ToInt32(storeList[a]), a);
    17.                 yield return null;
    18.             }
    19.         }
    20.         void populate(int rand, int index)
    21.         {
    22.             FeatureCards[index].id = InventoryCards[rand].id;
    23.             FeatureCards[index].partCategory = InventoryCards[rand].partCategory;
    24.             FeatureCards[index].value = InventoryCards[rand].value;
    25.             FeatureCards[index].transform.GetChild(0).GetComponent<Image>().color = InventoryCards[rand].transform.GetChild(0).GetComponent<Image>().color;
    26.             FeatureCards[index].transform.GetChild(0).GetChild(0).GetComponent<Image>().sprite = InventoryCards[rand].transform.GetChild(0).GetChild(0).GetComponent<Image>().sprite;
    27.             FeatureCards[index].transform.GetChild(0).GetChild(1).GetComponent<Text>().text = InventoryCards[rand].transform.GetChild(0).GetChild(1).GetComponent<Text>().text;
    28.             FeatureCards[index].transform.GetChild(0).GetChild(2).GetChild(0).GetComponent<Text>().text = "BUY FOR " +UnityIAPManager.productHandler.products.WithID(InventoryCards[rand].id).metadata.localizedPriceString;
    29.  
    30.             InventoryCards[rand].pairFeatureSoldButton = FeatureCards[index].transform.GetChild(0).GetChild(3).gameObject;
    31.             InventoryCards[rand].pairFeatureBuyButton = FeatureCards[index].transform.GetChild(0).GetChild(2).gameObject;
    32.             if (PlayerPrefs.HasKey(Encryptor.Encrypt(FeatureCards[index].id)))
    33.                 FeatureCards[index].Purchased();
    34.         }
    35.     }
    36.  
    37.  
     
  8. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    Because you are using the default string if you execute the ConfigOrigin.Default switch condition, which is an array of strings and Split only finds the first one. If you receive data from the server, it looks like you may be using a single string with a semicolon separator, and Split works as expected. Please share the value of the variables as set on your Dashboard and the Debug.Log values at runtime, as requested. Debug.Log statements will show in the logs, you can also use breakpoint debugging from Visual Studio. Let's see what the full string is, prior to your split attempt. Correct, we would not be sending only the first N characters of a variable.
     
    Last edited: Feb 5, 2020
  9. IllogicalGames

    IllogicalGames

    Joined:
    Apr 16, 2013
    Posts:
    156
    im pretty sure the string doesnt have spaces in them. and furthermore it only happens sometimes. why does it only happens sometimes?

    if its because of there is spaces in them, dont you think the result will be consistent everytime?
     
  10. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    Sorry no, because in one case, you are using the local array, and in the other switch condition, you are not and using the remote value. So it would behave differently in each case. As requested, please provide the output of your Debug.Log statement as mentioned. You are Splitting on a semicolon, and there are none in your local string array. I suspect there are, in your remote variable value. Debug.Log statements will show in the device logs, or you can use breakpoint debugging in Visual Studio to confirm https://forum.unity.com/threads/how-to-capturing-device-logs-on-android.528680/ This post may help also https://forum.unity.com/threads/tips-for-new-unity-users.701864/#post-5057741
     
  11. IllogicalGames

    IllogicalGames

    Joined:
    Apr 16, 2013
    Posts:
    156
    Here it is.
    upload_2020-2-6_3-35-33.png
     
  12. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    As I suspected, a single string separated by semicolons. Your local/default array of strings does not. A Switch statement is the same as a series of IF statements, and the behavior of the app in your case will be different depending on which path through your Switch statement is taken, and is why you see different behavior. I would encourage you to use Debug.Log as I mentioned, I believe it will be become clear.
     
  13. IllogicalGames

    IllogicalGames

    Joined:
    Apr 16, 2013
    Posts:
    156
    no the switch is not the case. the switch always debugged "New settings loaded this session; update values accordingly."

    also there is nothing wrong with my local string as

    Code (CSharp):
    1. void ApplyRemoteSettings(ConfigResponse configResponse)
    2.         {
    3. ////here is my local string. as you can see it doenst have semicolon because its an array. see next comment
    4.             string[] storeItems = { "6", "4", "7", "12", "16", "18", "3", "5", "2", "13", "5", "9", "20" };
    5.             string[] str= {""};
    6.             switch (configResponse.requestOrigin)
    7.             {
    8. ///doesnt need to do anything, just load the local string
    9.                 case ConfigOrigin.Default:
    10.                     Debug.Log("No settings loaded this session; using default values.");
    11.                     gameObject.SetActive(false);
    12.                     break;
    13.                 case ConfigOrigin.Cached:
    14. ////load the cached appconfig string
    15.                     Debug.Log("No settings loaded this session; using cached values from a previous session.");
    16. ///then we convert the appconfig string into an array and store it in storeitems
    17.                     storeItems = ConfigManager.appConfig.GetString("store_item").Split(';');
    18.                     str = ConfigManager.appConfig.GetString("live_version").Split(';');
    19.                     break;
    20.                 case ConfigOrigin.Remote:
    21. ///load the new value from the appconfig
    22.                     Debug.Log("New settings loaded this session; update values accordingly.");
    23. ///and then we convert the appconfig string into an array and store it in storeitems
    24.                     storeItems = ConfigManager.appConfig.GetString("store_item").Split(';');
    25.                     str = ConfigManager.appConfig.GetString("live_version").Split(';');                
    26.                     break;
    27.             }
    the parse only happen inside the switch and at the end of the switch, the string is converted into array and stored in storeitems.
     
  14. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    Please be aware of Release vs Development. The Editor’s Play mode always uses the Development environment settings. Your screenshot was Release. Are you testing on an Android device or in the Editor?

    https://docs.unity3d.com/Packages/com.unity.remote-config@0.3/manual/ConfiguringYourProject.html

    Also, please output variable values in your Debug.Log statements, prior to the Split.

    storeItems = ConfigManager.appConfig.GetString("store_item");
    Debug.Log ("In ConfigOrigin.Remote, storeItems = " + storeItems);
     
    Last edited: Feb 6, 2020
  15. Ianaa

    Ianaa

    Joined:
    Jul 15, 2018
    Posts:
    41
    It simply doesn't work. It returns blank. Who is responsible for making this feature?
     
  16. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    Please make a back up, then remove your Library directory. Zip up the project, and send it to me via a private message.
     
  17. tataygames

    tataygames

    Joined:
    Aug 4, 2016
    Posts:
    53
    Hi, I have just updated my Unity RemoteConfig because Unity RemoteSettings will be depriciated next year May.
    And guess what, its not working again as-usual as this Unity keeps buggier and buggier.

    I just followed this tutorial from your youtube channel:


    I tried to get int and doesn't get my original values.

    print( "REMOTE CONFIG:" + ConfigManager.appConfig.GetInt("androidServerBuildVersion") );


    Any idea? you guys have no idea how buggy Unity is. or your aware, I installed unity 10 times all failed just for installation on this new unity 2019 i took me 3 days. then building ilc2pp using your ndk too is buggy. it does not download the required ndk as it promises.


    Hope this new remote config has a solution cause like the struggles I have before. at default IT DOES NOT WORK.
     
    Last edited: Dec 17, 2020
  18. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
  19. PisaCa

    PisaCa

    Joined:
    Jun 19, 2019
    Posts:
    7
    I have followed the latest code but is it still not working? below is my code and setup image. please help!
     

    Attached Files:

  20. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
Thread Status:
Not open for further replies.