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

FirebaseRemoteConfig.fetch() не запускает OnCompleteListener каждый раз

Я пытаюсь реализовать Firebase Remote Config:

override fun onCreate(savedInstanceState: Bundle?) {

    val configSettings = FirebaseRemoteConfigSettings.Builder().setDeveloperModeEnabled(BuildConfig.DEBUG).build()

    mFirebaseRemoteConfig = FirebaseRemoteConfig.getInstance()
    mFirebaseRemoteConfig.setConfigSettings(configSettings)
    mFirebaseRemoteConfig.setDefaults(R.xml.remote_config_defaults)
    fetchRemoteConfig()
}

private fun fetchRemoteConfig() {
    var cacheExpiration = 3600L
    if (mFirebaseRemoteConfig.info.configSettings.isDeveloperModeEnabled) {
        cacheExpiration = 0L
    }

    mFirebaseRemoteConfig.fetch(cacheExpiration)
        .addOnCompleteListener { task ->
                if (task.isSuccessful) {
                    Log.d(TAG, "Remote config fetch succeeded")
                    mFirebaseRemoteConfig.activateFetched()
                } else {
                    Log.d(TAG, "Remote config fetch failed - ${task.exception?.message}")
                }

                setupView()
            }
}

private fun setupView() {
    val text = mFirebaseRemoteConfig.getString("my_text")
    //...
}

Моя проблема в том, что OnCompleteListener не всегда вызывается. Если я закрываю/открываю свое приложение несколько раз, setupView() не всегда запускается.

Всегда нужно называть OnCompleteListener правильно? Даже если я нахожусь в кеше?

EDIT: Даже если я отключу режим разработки, поведение будет одинаковым. Иногда срабатывает обратный вызов, иногда нет.

4b9b3361

Ответ 1

Я столкнулся с той же проблемой и связался с поддержкой firebase. Они ответили:

В настоящее время существует ошибка, о которой сообщалось, когда прослушиватели onComplete, onSuccess и onFailure не вызываются, если fetch() вызывается слишком рано. [...] В настоящее время существует работа, в которой вы можете поместить fetch() в postResume. Вы можете попробовать использовать это в то же время, прежде чем решение будет выпущено.

Я применил обходное решение

protected void onPostResume() {
    super.onPostResume();

    mFirebaseRemoteConfig.fetch(cacheExpiration)
            .addOnSuccessListener(new OnSuccessListener<Void>() {
                @Override
                public void onSuccess(Void aVoid) {
                    Log.d(TAG, "Fetch Succeeded");
                    // Once the config is successfully fetched it must be activated before newly fetched values are returned.
                    mFirebaseRemoteConfig.activateFetched();
                    // Do whatever should be done on success
                }
            })
            .addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception exception) {
                    Log.d(TAG, "Fetch failed");
                    // Do whatever should be done on failure
                }
            });
}

До сих пор, похоже, их предлагаемое решение обанкротило проблему.

UPDATE:

Я только получил уведомление от поддержки firebase. По их словам, проблема устранена с последними обновлениями Google Play Services.

Исправление удаленной конфигурации, не вызывающее слушателей после извлечения, было выпущено в новейшем обновлении сервисов Google. Я сейчас закрываю это дело. Однако, если вы все еще испытываете проблемы, не стесняйтесь связаться со мной и сообщить мне.

Ответ 2

Для тех из вас, кто не может сделать это, просто вызвав fetch() onPostResume (и действительно желая сделать эту работу лучше), вы можете попробовать вызвать метод извлечения внутри Handler.postDelayed(), чтобы задержать время выборки. Для нашей команды это повысило вероятность правильной работы метода выборки. Конечно, это решение работает не так надежно, как вызов fetch onPostResume, хотя.

@Override
public void onPostResume() {
   new Handler().postDelayed(new Runnable() {
      @Override
      public void run() {
         mFirebaseRemoteConfig.fetch(cacheExpiration)...
         ...
      }
   }, 500L);
}

Ответ 3

Если на вашем устройстве установлена ​​старая Служба Google Play и несовместимая версия, вы должны увидеть в журналах:

GooglePlayServicesUtil: службы Google Play устарели. Требуется 11020000, но найдено 10930470

Одним из решений является обновление устройства Google Play, но если вы этого не сделаете, вы также можете просто понизить версию firebase в соответствии с ожидаемой версией (здесь измените 11.0.2 на 10.9.3). Не идеально, но все-таки решение, если вы не можете обновить свое устройство (например, симулятор работает с 10.9.3 на сегодняшний день):

compile 'com.google.firebase:firebase-core:10.2.6'
compile 'com.google.firebase:firebase-messaging:10.2.6'
compile 'com.google.firebase:firebase-config:10.2.6'

Ответ 4

UPDATE версия 9.2.0 из firebase работает, как и следовало ожидать, и этот хак больше не нужен.

Я получил эту "рабочую" надежно... но вам может не понравиться мое решение. Чтобы получить конфигурационную выборку, когда Firebase готов, я должен был сделать это:

FirebaseAuth.getInstance()
   // I don't actually want to or need to sign in..(and this actually throws an error for us.. but we ignore it)
  .signInAnonymously()
  // when it completes (error or no error) we can do our business
  .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
      @Override
      public void onComplete(@NonNull Task<AuthResult> task) {
        // do the remote config fetch you were doing before
        remoteConfig.fetch(...).addOnComplete(...);
      }
  });

Это гарантирует, что внутренние компоненты firebase готовы выполнить эту начальную настройку конфигурации... при первом открытии приложения это, по-видимому, занимает около 6-10 секунд на моем дерьмовом тестовом устройстве (вся вещь, включая auth и config fetch). При последующем открытии вся вещь занимает 2-5 секунд. Очевидно, что все произвольные в зависимости от устройства/сети и YMMV.

Мне бы очень хотелось знать, почему это требуется.. Кажется, что удаленный config должен иметь возможность управлять этим внутри, а не раскрывать это нам.

p.s. вам понадобится эта зависимость в дополнение к firebase-config

compile 'com.google.firebase:firebase-auth:9.0.1'