【问题标题】:FirebaseRemoteConfig.fetch() does not trigger OnCompleteListener every timeFirebaseRemoteConfig.fetch() 不会每次都触发 OnCompleteListener
【发布时间】:2016-05-28 16:00:57
【问题描述】:

我正在尝试实现 Firebase 远程配置:

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 对吗?即使我正在访问缓存?

编辑:即使我禁用开发模式,行为也是一样的。有时会触发回调,有时不会。

【问题讨论】:

  • 我也有同样的问题..但是当然调试不能进去看看发生了什么,我不知道如何打开日志记录。
  • 对于它的价值.. 似乎在您看到此日志消息“FirebaseInstanceId:主题同步成功”之前不会调用 oncomplete,然后对 fetch 的后续调用将起作用。
  • @danb 你在哪里触发了 fetch() ?在 onCreate()、onResume()、其他地方?因为我将 fetch() 移到了 onResume() 中,现在它似乎可以工作了。顺便说一句,我像您这样的解决方法正在工作,因为它们延迟了触发 fetch() 的那一刻。如果我们提前调用 fetch() 可能无法检索远程配置。
  • 在 onCreate.. 我们的配置在由我们的 DI 框架创建的单例中管理,发生在 Application onCreate

标签: android firebase firebase-remote-config


【解决方案1】:

我遇到了同样的问题并联系了 Firebase 支持。他们回复如下:

目前已经报告了一个错误,即如果过早调用 fetch(),则不会调用 onComplete、onSuccess 和 onFailure 侦听器。 [...] 目前有一种解决方法,您可以将 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
                }
            });
}

到目前为止,他们提出的解决方法似乎已经解决了这个问题。

更新:

我刚刚收到了 Firebase 支持的通知。据他们说,最新的 Google Play 服务更新解决了这个问题。

在最新的 Google Play 服务更新中发布了远程配置在获取后不调用侦听器的修复。 我将暂时关闭此案。但是,如果您仍然遇到问题,请随时联系并告诉我。

【讨论】:

  • 谢谢,麦克斯!他们是否提供了该错误的链接以跟踪此问题?
  • 不,很遗憾没有。但是,Firebase 支持人员表示,当有更多要发布的错误修复时,他们会及时通知我。我会告诉你的。
  • 不幸的是,在 postResume 上调用 fetch() 对我来说似乎也不可靠。
  • @Max 请在他们回复您时更新此 SO。谢谢!
  • @Max 你能提供那个问题的链接吗?这个错误在哪个 google playservices 上修复了?
【解决方案2】:

如果您的设备运行的是旧的 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'

【讨论】:

    【解决方案3】:

    对于那些无法通过简单地调用 fetch() onPostResume 来实现的人(并且真的愿意让这个工作更好),你可以尝试在Handler.postDelayed() 中调用 fetch 方法来延迟你的获取时间。对于我们的团队来说,它增加了 fetch 方法正常工作的机会。当然,这个解决方案并不能像调用 fetch onPostResume 一样可靠地工作。

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

    【讨论】:

      【解决方案4】:

      UPDATE 9.2.0 版的 firebase 可以正常工作,不再需要这种 hack。

      我得到了这个可靠的“工作”......但你可能不喜欢我的解决方案。为了在 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 秒(整个事情包括身份验证和配置提取)。在随后的打开中,整个过程大约需要 2-5 秒。显然,这完全取决于设备/网络和 YMMV。

      我很想知道为什么需要这样做.. 似乎远程配置应该能够在内部管理它而不向我们公开它。

      附言除了 firebase-config 之外,您还需要此依赖项

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

      【讨论】:

      • 确实我不太喜欢这种解决方法。我向 Firebase 支持团队发送了一封电子邮件,以了解更多详细信息,或者至少表明这种奇怪的行为。在切换到 Firebase 之前,我可能仍会使用我的个人远程配置。不过还是谢谢:)
      • 听起来不错!如果您收到回复,请更新此问题!
      猜你喜欢
      • 2017-02-13
      • 2016-06-29
      • 1970-01-01
      • 1970-01-01
      • 2020-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-12
      相关资源
      最近更新 更多