RemoteConfigComponent and FirebaseMessaging return null for some users
Step 2: Describe your environment
- Android Studio version: Android Studio Iguana
- Firebase Component: Messaging & Config
- Component version: Firebase BOM 32.7.0
[REQUIRED] Step 3: Describe the problem
https://github.com/firebase/firebase-android-sdk/blob/5ef5cdda14666df3f6727719f4d3344c8286ef32/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java#L87
The code block above returns null for about ~1,500 users a day when we attempt to configure RemoteConfig. We are forced to check if RemoteConfigComponent is available before calling the config-ktx helper function:
firebase.get(RemoteConfigComponent::class.java) != null
and when we dont we see the following crash in production.
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'dbxyzptlk.h41.g dbxyzptlk.h41.k.d()' on a null object reference
at com.google.firebase.remoteconfig.FirebaseRemoteConfig.getInstance(FirebaseRemoteConfig.java:86)
at com.google.firebase.remoteconfig.ktx.RemoteConfigKt.remoteConfig(RemoteConfig.kt:32)
We also see the same behavior when it comes to getting the FirebaseMessaging and do a similar check:
firebase.get(FirebaseMessaging::class.java) != null
I do see the ComponentDiscoveryService have the Registrars populated for Messaging and RemoteConfig as well:
I found a few problems with this issue:
- I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.
- This issue does not seem to follow the issue template. Make sure you provide all the required information.
Hi @wdziemia, thank you for reaching out. I've been trying to reproduce this issue but haven't been successful. Below is how I initialize the RemoteConfig instance.
MainActivity.kt
//Initialization
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_layout)
FirebaseApp.initializeApp(this)
remoteConfig = FirebaseRemoteConfig.getInstance(FirebaseApp.getInstance())
}
Any chance you could provide detailed steps to reproduce the issue or an MCVE where the issue is reproducible? Aside from that, does the issue occur on a specific set of users or devices?
@lehcar09 Hello! Yes we initialize RC similarly. We use dagger though so its a bit more indirect than your example but the calls and flow are the same. I dont know how to reproduce this issue locally but can provide more details:
- Most of our devs run either Emulators or Google Pixels and we did not see any crashes during development (Firebase & RC is initialized on App start) or Alpha users (~100) .
- 75% of users affected are on Samsung devices
- Affects all OS versions we support (Android 8 and above)
We have a more aggressive fetch for Firebase Messaging which uses some exponential backoff with an interval of 10ms delay between checking if Firebase Messaging returns an instance or null. There is a max delay between checks being 1000ms. Ive set up some metrics to track the total duration it takes to return the Messaging component and have some prelim data below. This data should be of Developer & Alpha users (<200). I will update once this build hits beta and prod environments.
Hey @wdziemia. We need more information to resolve this issue but there hasn't been an update in 5 weekdays. I'm marking the issue as stale and if there are no new updates in the next 5 days I will close it automatically.
If you have more information that will help us get to the bottom of this, just add a comment!
Some data over the last 24 hours - Firebase Messaging shows the following:
- About 96K Samples
- Success rate is virtually 100% - so this looks like its Lazily initialized?
Hi @wdziemia, sorry for the hold up. I can't say for sure if this is due to lazy initialization. Based on your description, it seems like you're using Dagger to initialize Firebase. Something like:
@Provides
@Singleton
fun provideFirebaseRC(@ApplicationContext appContext: Context): FirebaseRemoteConfig {
FirebaseApp.initializeApp(appContext)
return FirebaseRemoteConfig.getInstance(FirebaseApp.getInstance())
}
Just to note, FirebaseInitProvider initializes Firebase APIs at app startup time, not being able to initialize them properly (considering the inter-dependency) might cause conflicts. Also, as per the documentation of FirebaseApp:
Any FirebaseApp initialization must occur only in the main process of the app. Use of Firebase in processes other than the main process is not supported and will likely cause problems related to resource contention.
Useful References
Take Control of Your Firebase Init on Android How does Firebase initialize on Android?
Can you share how and when are you calling FirebaseApp.initializeApp() and FirebaseMessaging.getInstance()? Is your app a multi process app?
We are calling it as part of our Dagger object graph creation which is done in Applicaiton.onCreate(), there are no calls to use Firebase / RemoteConfig / Messaging that are outside of dependency injections. I also see no usages of android:process in the codebase.
Messaging shows the following results, with an overall 23.6% success rate in returning an instance, this number is quite a surprise.
Remote Config has about 1300 instances of being unavailable during Application.onCreate() - this is a relatively small number compared to the amount of app starts per day we have (~5 million)