我尝试使用Firebase的新远程配置功能来设置远程配置参数,并且我遇到了问题。
我正在我的应用程序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
,所以看来抓取是否成功。
知道为什么我的价值是空白的吗?
答案 0 :(得分:18)
找到解决方法!见下文
我正在遇到“无声完成”的事情 - 我称之为“fetch”,但onComplete,onSuccess或onFailure监听器从不会触发。我尝试将它移动到onCreate上的活动,但仍然没有发生任何事情,因此配置项永远不会从服务器加载。我启用了Developer Mode,并且调用fetch时缓存值为0。
我能够(曾经)在“public void onComplete(@NonNull Task task){”这一行上设置一个断点,然后我就可以逐步完成并触发onComplete。然后我无法以任何其他方式重现同样的结果,包括第二次做同样的事情(我想)。
看起来像是时间或并发问题,但这没什么意义,因为这是一个异步调用。
解决方法强>
如果你从Activity#onResume(或者我认为是Activity#onStart)中获取它,它的效果非常好。从Activity#onCreate或Application#onCreate调用fetch导致一个看似永远不会被处理的调用,事实上,在获取开始后,应用程序的性能会明显降低,所以我认为有一个looper正在运行或者其他什么。*
解决方法#2
如果你真的希望从Application#onCreate(我这样做)运行它,这似乎也有效:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
// Run mFirebaseRemoteConfig.fetch(timeout) here, and it works
}
}, 0);
答案 1 :(得分:16)
您可能会在远程配置中点击caching。它的工作方式是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中完成的。
答案 2 :(得分:9)
发现问题。
添加一些日志记录后,我发现从未调用过fetch job onComplete()
。我将应用程序的onCreate
中的fetch移动到片段中,现在它正常工作了!
(Ian Barber,这可能需要查看或澄清,因为日志表明Firebase在应用程序中初始化时没有问题,并且提取是静默失败。)
答案 3 :(得分:4)
我遇到了同样的问题,在我的案例中没有任何解决方法。问题出在测试设备上。我在没有安装Google移动服务的情况下使用了模拟器,因此没有触发Complete事件。我用GMS尝试了手机,一切都很棒。祝你好运。
答案 4 :(得分:2)
在这种情况下,第一件事就是检查你是否有正确的firebase配置并且你已经连接到firebase。如果你有android studio 2.2到了Tools-&gt; Firebase-&gt; RemoteConfig - 连接到Firebase,看看你是否得到通知说已连接。已连接在您的代码中执行以下操作: 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();
}
});
运行您的应用并检查日志&#34; Firebase远程配置获取成功&#34;。如果您看到相同的远程配置已加载并激活。
答案 5 :(得分:2)
我使用了类似@Ian Barber(副本)的代码:
FirebaseRemoteConfigSettings configSettings =
new FirebaseRemoteConfigSettings.Builder()
.setDeveloperModeEnabled(BuildConfig.DEBUG)
.build();
FirebaseRemoteConfig.getInstance().setConfigSettings(configSettings);
我的问题是“BuildConfig.DEBUG”,它返回false。所以它在缓存中取值1h,直到再次获取它为止!
答案 6 :(得分:0)
我有一个问题,即Firebase Remote Config不会使用fetch(0)
来触发OnCompleteListener,而使用fetch()
来触发。
看着FirebaseRemoteConfig.fetch() does not trigger OnCompleteListener every time,我发现第一个答案有时甚至在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(this@MainActivity, "Someting went wrong please try again",
Toast.LENGTH_SHORT).show()
}
}
答案 7 :(得分:0)
我也遇到了这个问题。原来我在Firebase控制台中没有看到“发布”按钮。 :facepalm:
答案 8 :(得分:0)
在我的情况下,我能够在addOnCompleteListener
中接收对fetch方法的控制,但是我在调用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")
}
})
答案 9 :(得分:0)
我正在做一个大项目,问题被埋在一个意想不到的地方。 长话短说:Firebase应用程序ID(通常通过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”中的信息。