get appconfig always return null

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.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Unity.RemoteConfig;
using UnityEngine.SceneManagement;
namespace TanksMP
{
    public class VersionControl : MonoBehaviour
    {
        public Text message;
        public GameObject okButton;
        public FeatureRandomizer feature;
        void Start()
        {
            ConfigManager.FetchCompleted += ApplyRemoteSettings;
            okButton.SetActive(false);
        }
        public void RestartGame()
        {
            SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
        }
        void ApplyRemoteSettings(ConfigResponse configResponse)
        {
            switch (configResponse.requestOrigin)
            {
                case ConfigOrigin.Default:
                    Debug.Log("No settings loaded this session; using default values.");
                    string[] defaultStoreItems = { "6", "4", "7", "12", "16", "18", "3", "5", "2", "13", "5", "9", "20" };
                    feature.readList(defaultStoreItems);
                    gameObject.SetActive(false);
                    break;
                case ConfigOrigin.Cached:
                    Debug.Log("No settings loaded this session; using cached values from a previous session.");
                    break;
                case ConfigOrigin.Remote:
                    Debug.Log("New settings loaded this session; update values accordingly.");

                    bool outdated = true;
                    string[] str = ConfigManager.appConfig.GetString("live_version").Split(';');
                    for (int a = 0; a < str.Length; a++)
                    {
                        if (str[a] == Application.version.ToString()) outdated = false;
                    }
                    if (outdated)
                    {
                        message.text = "<size=22>Version Outdated</size>\nUpdate to the latest version to play the game.";
                        okButton.SetActive(false);
                    }

                    string[] storeItems = ConfigManager.appConfig.GetString("store_item").Split(';');
                    feature.readList(storeItems);

                    message.text = ConfigManager.appConfig.GetString("message");
                    if (message.text == "") gameObject.SetActive(false);
                    okButton.SetActive(true);

                    break;
            }
        }
    }
}

and here is my dashboard

Those are your local settings, have you Pushed them to the online Dashboard? Can you click the View in Dashboard button to confirm?

1 Like

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.

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.

{
    public class VersionControl : MonoBehaviour
    {
        public Text title;
        public Text message;
        public GameObject okButton;
        public GameObject restartButton;
        public FeatureRandomizer feature;
        public struct userAttributes
        {
            // Optionally declare variables for any custom user attributes; if none keep an empty struct:
        }

        public struct appAttributes
        {
            // Optionally declare variables for any custom app attributes; if none keep an empty struct:
        }
        void Start()
        {
            StartCoroutine(queuedVersionCheck());
        }
        IEnumerator queuedVersionCheck()
        {
            yield return new WaitForSeconds(1);
            ConfigManager.FetchCompleted += ApplyRemoteSettings;
            ConfigManager.FetchConfigs<userAttributes, appAttributes>(new userAttributes(), new appAttributes());
            yield return new WaitForSeconds(10);
        }
        void ApplyRemoteSettings(ConfigResponse configResponse)
        {
            string[] storeItems = { "6", "4", "7", "12", "16", "18", "3", "5", "2", "13", "5", "9", "20" };
            string[] str= {""};
            switch (configResponse.requestOrigin)
            {
                case ConfigOrigin.Default:
                    Debug.Log("No settings loaded this session; using default values.");
                    gameObject.SetActive(false);
                    break;
                case ConfigOrigin.Cached:
                    Debug.Log("No settings loaded this session; using cached values from a previous session.");

                    storeItems = ConfigManager.appConfig.GetString("store_item").Split(';');
                    str = ConfigManager.appConfig.GetString("live_version").Split(';');
                    break;
                case ConfigOrigin.Remote:
                    Debug.Log("New settings loaded this session; update values accordingly.");
                   
                    storeItems = ConfigManager.appConfig.GetString("store_item").Split(';');
                    str = ConfigManager.appConfig.GetString("live_version").Split(';');                   
                    break;
            }
            bool outdated = true;
            for (int a = 0; a < str.Length; a++)
            {
                if (str[a] == Application.version.ToString()) outdated = false;
            }
            if (outdated)
            {
                title.text = "Version Outdated";
                message.text = "Update to the latest version to play the game.";
                restartButton.SetActive(true);
            }
            else
            {
                StopAllCoroutines();
                okButton.SetActive(true);
                title.text = ConfigManager.appConfig.GetString("title");
                message.text = ConfigManager.appConfig.GetString("message");
                if (message.text == "") gameObject.SetActive(false);
            }
            ConfigManager.FetchCompleted -= ApplyRemoteSettings;
            if (storeItems.Length < 13) RestartGame();
            else StartCoroutine(feature.readList(storeItems));
        }        
    }
}

as you can see i wrote an if statement if fetches less than 13, restart the game. it still happen.

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.

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

using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using Unity.RemoteConfig;
using UnityEngine.SceneManagement;

    public class VersionControl : MonoBehaviour
    {
        public Text title;
        public Text message;
        public GameObject okButton;
        public GameObject restartButton;
        public FeatureRandomizer feature;
        public Text version;
        public struct userAttributes
        {
            // Optionally declare variables for any custom user attributes; if none keep an empty struct:
        }

        public struct appAttributes
        {
            // Optionally declare variables for any custom app attributes; if none keep an empty struct:
        }
        void Start()
        {
            version.text = Application.version.ToString();
            restartButton.SetActive(false);
            okButton.SetActive(false);
            StartCoroutine(queuedVersionCheck());
        }
        public void RestartGame()
        {
            SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
            ConfigManager.FetchCompleted -= ApplyRemoteSettings;
        }
        IEnumerator queuedVersionCheck()
        {
            yield return new WaitForSeconds(1);
            ConfigManager.FetchCompleted += ApplyRemoteSettings;
            ConfigManager.FetchConfigs<userAttributes, appAttributes>(new userAttributes(), new appAttributes());
            yield return new WaitForSeconds(10);
            restartButton.SetActive(true);
        }
        void ApplyRemoteSettings(ConfigResponse configResponse)
        {
            string[] storeItems = { "6", "4", "7", "12", "16", "18", "3", "5", "2", "13", "5", "9", "20" };
            string[] str= {""};
            switch (configResponse.requestOrigin)
            {
                case ConfigOrigin.Default:
                    Debug.Log("No settings loaded this session; using default values.");
                    gameObject.SetActive(false);
                    break;
                case ConfigOrigin.Cached:
                    Debug.Log("No settings loaded this session; using cached values from a previous session.");

                    storeItems = ConfigManager.appConfig.GetString("store_item").Split(';');
                    str = ConfigManager.appConfig.GetString("live_version").Split(';');
                    break;
                case ConfigOrigin.Remote:
                    Debug.Log("New settings loaded this session; update values accordingly.");
                   
                    storeItems = ConfigManager.appConfig.GetString("store_item").Split(';');
                    str = ConfigManager.appConfig.GetString("live_version").Split(';');                   
                    break;
            }
            bool outdated = true;
            for (int a = 0; a < str.Length; a++)
            {
                if (str[a] == Application.version.ToString()) outdated = false;
            }
            if (outdated)
            {
                title.text = "Version Outdated";
                message.text = "Update to the latest version to play the game.";
                restartButton.SetActive(true);
            }
            else
            {
                StopAllCoroutines();
                okButton.SetActive(true);
                title.text = ConfigManager.appConfig.GetString("title");
                message.text = ConfigManager.appConfig.GetString("message");
                if (message.text == "") gameObject.SetActive(false);
            }
            ConfigManager.FetchCompleted -= ApplyRemoteSettings;
            if (storeItems.Length < 13) RestartGame();
            else StartCoroutine(feature.readList(storeItems));
        }        
    
}

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.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System;

    public class FeatureRandomizer : MonoBehaviour
    {
        public IAPProduct[] FeatureCards;
        public IAPProduct[] InventoryCards;

        public IEnumerator readList(string[] storeList)
        {
            for (int a = 0; a < FeatureCards.Length; a++)
            {
                populate(System.Convert.ToInt32(storeList[a]), a);
                yield return null;
            }
        }
        void populate(int rand, int index)
        {
            FeatureCards[index].id = InventoryCards[rand].id;
            FeatureCards[index].partCategory = InventoryCards[rand].partCategory;
            FeatureCards[index].value = InventoryCards[rand].value;
            FeatureCards[index].transform.GetChild(0).GetComponent<Image>().color = InventoryCards[rand].transform.GetChild(0).GetComponent<Image>().color;
            FeatureCards[index].transform.GetChild(0).GetChild(0).GetComponent<Image>().sprite = InventoryCards[rand].transform.GetChild(0).GetChild(0).GetComponent<Image>().sprite;
            FeatureCards[index].transform.GetChild(0).GetChild(1).GetComponent<Text>().text = InventoryCards[rand].transform.GetChild(0).GetChild(1).GetComponent<Text>().text;
            FeatureCards[index].transform.GetChild(0).GetChild(2).GetChild(0).GetComponent<Text>().text = "BUY FOR " +UnityIAPManager.productHandler.products.WithID(InventoryCards[rand].id).metadata.localizedPriceString;

            InventoryCards[rand].pairFeatureSoldButton = FeatureCards[index].transform.GetChild(0).GetChild(3).gameObject;
            InventoryCards[rand].pairFeatureBuyButton = FeatureCards[index].transform.GetChild(0).GetChild(2).gameObject;
            if (PlayerPrefs.HasKey(Encryptor.Encrypt(FeatureCards[index].id)))
                FeatureCards[index].Purchased();
        }
    }

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.

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?

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://discussions.unity.com/t/699654 This post may help also https://discussions.unity.com/t/748729/14

Here it is.

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.

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

void ApplyRemoteSettings(ConfigResponse configResponse)
        {
////here is my local string. as you can see it doenst have semicolon because its an array. see next comment
            string[] storeItems = { "6", "4", "7", "12", "16", "18", "3", "5", "2", "13", "5", "9", "20" };
            string[] str= {""};
            switch (configResponse.requestOrigin)
            {
///doesnt need to do anything, just load the local string
                case ConfigOrigin.Default:
                    Debug.Log("No settings loaded this session; using default values.");
                    gameObject.SetActive(false);
                    break;
                case ConfigOrigin.Cached:
////load the cached appconfig string
                    Debug.Log("No settings loaded this session; using cached values from a previous session.");
///then we convert the appconfig string into an array and store it in storeitems
                    storeItems = ConfigManager.appConfig.GetString("store_item").Split(';');
                    str = ConfigManager.appConfig.GetString("live_version").Split(';');
                    break;
                case ConfigOrigin.Remote:
///load the new value from the appconfig
                    Debug.Log("New settings loaded this session; update values accordingly.");
///and then we convert the appconfig string into an array and store it in storeitems
                    storeItems = ConfigManager.appConfig.GetString("store_item").Split(';');
                    str = ConfigManager.appConfig.GetString("live_version").Split(';');                 
                    break;
            }

the parse only happen inside the switch and at the end of the switch, the string is converted into array and stored in storeitems.

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

It simply doesn’t work. It returns blank. Who is responsible for making this feature?

Please make a back up, then remove your Library directory. Zip up the project, and send it to me via a private message.

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.

Please use the updated code here, be sure to set the environmentID. That is an older video, and we’ve since updated the API Code integration | Remote Config | 2.0.2-exp.1

I have followed the latest code but is it still not working? below is my code and setup image. please help!

6636028–757039–RemoteConfigMgr.cs (2.05 KB)


Please don’t multipost, I answered in your other post https://discussions.unity.com/t/821104