Подтвердить что ты не робот

Firebase Remote Config: Невозможно прочитать какие-либо значения, но выборка выполнена успешно

Я пытаюсь иметь параметр удаленной конфигурации, используя новую функцию Remote Config Firebase, и у меня возникла проблема.

Здесь моя консоль Remote Config: удаленная консоль конфигурации

Я делаю выборку и обновление в своем приложении onCreate():

final FirebaseRemoteConfig remoteConfig = FirebaseRemoteConfig.getInstance();
remoteConfig.fetch().addOnCompleteListener(new OnCompleteListener<Void>() {
    @Override
    public void onComplete(@NonNull Task<Void> task) {
        if (task.isSuccessful()) {
            remoteConfig.activateFetched();
        }
    }
});

И вот как я его читаю:

FirebaseRemoteConfig remoteConfig = FirebaseRemoteConfig.getInstance();
String value = remoteConfig.getString("active_subscriptions");

Значение возвращает null.

Если я вызываю remoteConfig.getInfo().getLastFetchStatus(), он возвращает LAST_FETCH_STATUS_SUCCESS, поэтому кажется, что выборка прошла успешно.

Любая идея, почему мое значение пустое?

4b9b3361

Ответ 1

Нашел проблему.

После добавления некоторого ведения журнала я обнаружил, что задание на выборку onComplete() никогда не вызывалось. Я переместил извлечение из моего приложения onCreate в фрагмент, и теперь он работает правильно!

(Ian Barber, это может быть что-то для изучения или уточнения, поскольку в журналах указано, что Firebase была инициализирована без проблем, когда она была в Приложении, и выборки были молчаливыми сбоями.)

Ответ 2

Обходное решение найдено! См. Ниже

Я сталкиваюсь с "молчаливым завершением" - я называю "выборка", но onComplete, onSuccess или onFailure никогда не запускаются. Я попытался переместить его в действие onCreate, и все равно ничего не произошло, поэтому элементы конфигурации никогда не загружаются с сервера. У меня включен режим разработчика, и я вызываю fetch с кешем в 0.

Я смог (однажды) поставить точку останова на строку "public void onComplete (задача @NonNull Task) {", которая попала, а затем я смог пройти и запустить onComplete. Тогда я не смог воспроизвести этот же результат любым другим способом, в том числе сделать то же самое (я думаю) во второй раз.

Похоже на вопрос о сроках или concurrency, но это мало смысла, учитывая, что это асинхронный вызов.

Обход

Если вы выберете из Activity # onResume (или, я полагаю, Activity # onStart), он отлично работает. Вызов fetch из Activity # onCreate или Application # onCreate приводит к вызову, который, казалось бы, никогда не обрабатывается, и, по сути, производительность приложения заметно ухудшается после начала выборки, поэтому я думаю, что там работает петлитель или что-то в этом роде. *

Обходной путь №2

Если вы действительно хотите, чтобы это выполнялось из Application # onCreate (что я и делаю), это также работает:

new Handler().postDelayed(new Runnable() {
    @Override
    public void run() {
        // Run mFirebaseRemoteConfig.fetch(timeout) here, and it works
    }
}, 0);

Ответ 3

Вероятно, вы попадаете в caching в Remote Config. Способ, которым он работает, заключается в том, что Config будет кэшировать входящие элементы локально и возвращать их. Таким образом, ваш последний (кэшированный) статус выборки был, вероятно, до того, как значение было определено, и мы получим кэшированное пустое значение.

Вы можете контролировать срок действия кеша, но если вы слишком часто выбираете, вы рискуете получить дросселирование.

Поскольку это общая проблема разработки, есть режим разработчика, который позволяет быстрее запрашивать (для небольших групп пользователей):

FirebaseRemoteConfigSettings configSettings = 
    new FirebaseRemoteConfigSettings.Builder()
        .setDeveloperModeEnabled(BuildConfig.DEBUG)
        .build();
FirebaseRemoteConfig.getInstance().setConfigSettings(configSettings);

Когда вы вызываете fetch, вы можете передать короткое время истечения кеша

long cacheExpiration = 3600;
FirebaseRemoteConfig mFirebaseRemoteConfig = FirebaseRemoteConfig.getInstance();
if (mFirebaseRemoteConfig.getInfo().getConfigSettings().isDeveloperModeEnabled()) {
     cacheExpiration = 0;
}
mFirebaseRemoteConfig.fetch(cacheExpiration)
     .addOnCompleteListener(new OnCompleteListener<Void>() {
     // ...
});

Как это сделать в quickstart sample, если вы хотите получить полную ссылку.

Ответ 4

У меня была такая же проблема, и никакие обходные пути не помогли в моем случае. Проблема была в тестирующем устройстве. Я использовал эмулятор без установки Google Mobile Services, потому что это событие не было запущено. Я попробовал свой телефон с GMS, и все отлично поработало. Удачи.

Ответ 5

Первое, что в таком случае, это проверить, есть ли у вас правильная конфигурация firebase и вы подключены к firebase. Если у вас есть Android 2.2, доступ к Tools- > Firebase- > RemoteConfig - подключиться к Firebase и посмотреть, получаете ли вы уведомление говорящий connected.Once Connected сделать следующее в вашем коде:    mFirebaseRemoteConfig = FirebaseRemoteConfig.getInstance();

    /** NOTE: At this point, your app can use in-app default parameter values.To use in-app
     *        default values,skip the next section. You can deploy your app without setting
     *        parameter values on the server,and then later set values on the server to
     *        override the default behavior and appearance of your app.
     */

    mFirebaseRemoteConfig.setDefaults(R.xml.remote_config_defaults);
    FirebaseRemoteConfigSettings configSettings = new FirebaseRemoteConfigSettings.Builder()
            .setDeveloperModeEnabled(true)
            .build();
    mFirebaseRemoteConfig.setConfigSettings(configSettings);

А затем для настройки конфигурации выполните следующие    long cacheExpiration = 2000;//Может увеличить это обычно 12 часов - это то, что рекомендуется

    /** If in developer mode cacheExpiration is set to 0 so each fetch will retrieve values from
     * the server.*/

    if (mFirebaseRemoteConfig.getInfo().getConfigSettings().isDeveloperModeEnabled()) {
        cacheExpiration = 0;
    }

   /**  cacheExpirationSeconds is set to cacheExpiration here, indicating that any previously
    * fetched and cached config would be considered expired because it would have been fetched
    * more than cacheExpiration seconds ago. Thus the next fetch would go to the server unless
    * throttling is in progress. The default expiration duration is 43200 (12 hours).
    */

    mFirebaseRemoteConfig.fetch(cacheExpiration)//TODO Bring this from a config file
            .addOnCompleteListener(new OnCompleteListener<Void>() {
                @Override
                public void onComplete(@NonNull Task<Void> task) {
                    if (task.isSuccessful()) {
                        Log.d(TAG, "Firebase Remote config Fetch Succeeded");
                        // Once the config is successfully fetched it must be activated before newly fetched
                        // values are returned.
                        mFirebaseRemoteConfig.activateFetched();
                    } else {
                        Log.d(TAG, "Firebase Remote config Fetch failed");
                    }
                    showRemoteConfig();
                }
            });

Запустите приложение и проверьте журналы "Firebase Remote config Fetch Succeeded". Если вы видите, что ваши удаленные конфигурации загружены и активированы.

Ответ 6

Я использовал такой же код, как @Ian Barber (копия):

FirebaseRemoteConfigSettings configSettings = 
    new FirebaseRemoteConfigSettings.Builder()
        .setDeveloperModeEnabled(BuildConfig.DEBUG)
        .build();
FirebaseRemoteConfig.getInstance().setConfigSettings(configSettings);

Моя проблема была "BuildConfig.DEBUG" , она возвращает false. Таким образом, оно берет значение 1h в кеше, пока оно не будет извлечено снова!

Ответ 7

Я также столкнулся с этой проблемой. Оказывается, я не видел кнопку "Опубликовать" в консоли Firebase. : Facepalm:

Ответ 8

У меня была проблема, что Firebase Remote Config не запускал OnCompleteListener с fetch(0), а с fetch() делал.

Глядя на FirebaseRemoteConfig.fetch() не запускает OnCompleteListener каждый раз, я обнаружил, что первый ответ работал иногда даже с fetch(0). Затем я снова установил 3600 секунд для интервала, поскольку ошибки продолжали появляться:

override fun onPostResume() {
    super.onPostResume()

    // Initialize FirebaseRemoteConfig here.
    ...

    firebaseRemoteConfig.fetch(3600).addOnCompleteListener { task ->
        if (task.isSuccessful) {
            firebaseRemoteConfig.activateFetched()
            //calling function to check if new version is available or not
            checkForUpdate(currentVersionCode, firebaseRemoteConfig.getString(VERSION_CODE_KEY))
        } else
            Toast.makeText([email protected], "Someting went wrong please try again",
                Toast.LENGTH_SHORT).show()
    }

}

Ответ 9

В моем случае, я могу получить управление в addOnCompleteListener для метода выборки, но я получил значения firebaseRemoteConfig сразу после того, как я вызвал firebaseRemoteConfig.activate(), поэтому, когда я попытался получить значения из firebaseRemoteConfig, он возвращает меня ранее сохраненные значения, потому что firebaseRemoteConfig.activate() работает асинхронно, а новые значения не сохранялись до того, как я получил их от firebaseRemoteConfig, поэтому я также добавил полный прослушиватель для метода activate(), здесь:

firebaseRemoteConfig.fetch()
            .addOnCompleteListener(activity, OnCompleteListener {
                if (it.isSuccessful)
                {
                    Log.d("task","success")
                    firebaseRemoteConfig.activate().addOnCompleteListener {  // here I have added a listener
                        val base_url=firebaseRemoteConfig.getString("base_url")
                        Log.d("base url",base_url)
                        Toast.makeText(activity, "Base url: $base_url",Toast.LENGTH_SHORT).show()
                    }
                }
                else
                {
                    Log.d("task","failure")
                }

            })

Ответ 10

Я работаю над большим проектом, и проблема была похоронена в неожиданном месте. Короче говоря: идентификатор приложения Firebase (обычно устанавливается через google-services.json) был изменен с помощью кода:

FirebaseOptions.Builder builder = new FirebaseOptions.Builder();
builder.setApplicationId(applicationId);
builder.setApiKey(apiKey);
FirebaseOptions options = builder.build();
FirebaseApp.initializeApp(context, options);

Решением было удалить этот код и позволить firebase использовать информацию из "google-services.json".