firebase / firebase/firebase-android-sdk
firebase-auth calls ContextCompat.registerReceiver(Context, BroadcastReceiver, IntentFilter, int) but declares no androidx.core dependency
- Dominant language
- Java
- Stars
- 2.6k
- Forks
- 710
- Avg merge
- 2d 23h
- Merged PRs (30d)
- 34
Description
### [REQUIRED] Step 2: Describe your environment
- Android Studio version: **n/a — Gradle build, AGP 8.12.0 / Gradle 8.14.3**
- Firebase Component: **Auth**
- Component version: **23.2.1 (via firebase-bom 33.15.0); also verified against 24.2.0**
### [REQUIRED] Step 3: Describe the problem
`firebase-auth` calls `ContextCompat.registerReceiver(Context, BroadcastReceiver, IntentFilter, int)` when it sets up the SMS retriever for phone auth. That overload was added in **androidx.core 1.9.0**.
`firebase-auth` does not declare a dependency on `androidx.core` at any version. Its POM declares:
```
androidx.browser:browser:1.4.0
androidx.collection:collection:1.0.0
androidx.credentials:credentials:1.2.0-rc01
androidx.credentials:credentials-play-services-auth:1.2.0-rc01
androidx.fragment:fragment:1.1.0
androidx.localbroadcastmanager:localbroadcastmanager:1.0.0
```
`androidx.fragment:1.1.0` is far too old to pull in a suitable `androidx.core`, so nothing in the declared graph guarantees the method exists. The highest `androidx.core` reachable from `firebase-auth` alone is **1.2.0**, via `play-services-base:18.0.1` / `play-services-basement:18.4.0`.
The result is that any consumer whose dependency graph does not *otherwise* contain `androidx.core >= 1.9.0` gets a hard crash on the first phone auth call.
This is masked for most apps, because `appcompat`, `activity`, Compose and `core-ktx` all bring `androidx.core` 1.13–1.19 and conflict resolution picks those. It is not masked for consumers with a lean graph — in our case an instrumented-test APK for a library that wraps the Firebase SDKs, which depends on `firebase-auth` and `androidx.test` but not on any UI artifact.
#### Steps to reproduce:
1. Create an Android module that depends on `com.google.firebase:firebase-auth` **without** `appcompat`, `activity`, Compose, or `core-ktx`.
2. Confirm the resolved version is old — `./gradlew :module:dependencyInsight --configuration debugRuntimeClasspath --dependency androidx.core:core` reports `androidx.core:core:1.2.0`, selection reason `By conflict resolution: between versions 1.2.0, 1.1.0 and 1.0.0`.
3. Call `PhoneAuthProvider.verifyPhoneNumber(...)`.
4. It crashes as soon as the SMS retriever is registered.
Verified that `androidx.core:core:1.9.0` contains the overload and `1.2.0` does not, by decompiling both:
```
$ javap -classpath androidx.core.content.ContextCompat | grep registerReceiver
public static android.content.Intent registerReceiver(android.content.Context, android.content.BroadcastReceiver, android.content.IntentFilter, int);
public static android.content.Intent registerReceiver(android.content.Context, android.content.BroadcastReceiver, android.content.IntentFilter, java.lang.String, android.os.Handler, int);
$ javap -classpath androidx.core.content.ContextCompat | grep registerReceiver
(no such overload)
```
#### Relevant Code:
```
java.lang.NoSuchMethodError: No static method registerReceiver(Landroid/content/Context;Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;I)Landroid/content/Intent;
in class Landroidx/core/content/ContextCompat; or its super classes
(declaration of 'androidx.core.content.ContextCompat' appears in /data/app/~~-GawQ-mLA-xVH6tujzcrdw==/dev.gitlive.firebase.auth.test-YTNifziXwZqfmlaaSKp6KQ==/base.apk)
at com.google.android.gms.internal.firebase-auth-api.zzafu.zza(com.google.firebase:firebase-auth@@23.2.1:115)
at com.google.android.gms.internal.firebase-auth-api.zzaef.zza(com.google.firebase:firebase-auth@@23.2.1:148)
at com.google.android.gms.internal.firebase-auth-api.zzaee.zza(com.google.firebase:firebase-auth@@23.2.1:9)
at com.google.android.gms.internal.firebase-auth-api.zzafj.run(com.google.firebase:firebase-auth@@23.2.1:3)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)
at com.google.firebase.concurrent.CustomThreadFactory.lambda$newThread$0$com-google-firebase-concurrent-CustomThreadFactory(CustomThreadFactory.java:47)
at com.google.firebase.concurrent.CustomThreadFactory$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0)
at java.lang.Thread.run(Thread.java:1012)
```
#### Suggested fix
Have `firebase-auth` declare the minimum `androidx.core` its code actually requires, either as a dependency or as a constraint:
```
api("androidx.core:core:1.9.0")
```
1.9.0 is the exact floor for the overload in use. Declaring it would let Gradle's conflict resolution do the right thing for lean consumers, while apps that already bring a newer `androidx.core` are unaffected.
We have worked around it locally by pinning `androidx.core` on the affected test source set, so this is not blocking us — filing because the underdeclaration looks unintentional and still applies in 24.2.0.
Contributor guide
Research direction
Start by locating the firebase-auth Gradle dependency declaration and reproduce the issue with the lean dependency graph using dependencyInsight and the phone-auth call described. Done means the graph guarantees androidx.core at least 1.9.0 and the SMS retriever no longer fails with the reported NoSuchMethodError.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- android, java
- Domain
- build-system, mobile
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100