FID mode: firebase-functions' legacy firebase-iid dependency makes sends to the FID return UNREGISTERED for minutes to hours after every app update
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 48/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Lĩnh vực
- backend-api-design
Hướng nghiên cứu
Start by reading the firebase-functions dependency declaration and FirebaseContextProvider path described in the report, then trace how the FirebaseInstanceIdInternal token is added to callable requests when FID mode is enabled. Check the existing Functions tests for dependency and request-header behavior. Done when FID-mode apps can use callables without legacy IID registration disrupting FID delivery, with tests covering the behavior.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
[READ] Step 1: Are you in the right place?
Yes: this is a bug in the interaction of firebase-functions and firebase-messaging (FID registration mode) shipped in this repository.
[REQUIRED] Step 2: Describe your environment
- Android Studio version: Rabbit | 2026.2.1
- Firebase Component: Functions + Cloud Messaging (Firebase Installation ID registration mode)
- Component version:
firebase-bom:35.0.0→firebase-functions:23.0.0(transitivelyfirebase-iid:21.1.0),firebase-messaging:26.0.0,firebase-installations:20.0.0; Google Play services 26.37.37; reproduced on an emulator (Pixel 10 Pro Google Play image, API 37) and on a Galaxy S25 (Android 16) with a Play Store build; server sidefirebase-admin14.4.0 (Node) sending with{ fid }.
[REQUIRED] Step 3: Describe the problem
With firebase_messaging_installation_id_enabled=true, every in-place app update (new versionCode, Play Store update or adb install -r) makes FCM answer 404 UNREGISTERED (messaging/installation-id-not-registered) for the device's unchanged FID — immediately at install time (before the app is even started) and then for a long, variable time after the app starts: 10 min, 25 min and once 3 h in our measurements, after which sends succeed again with the same FID without any client action. During that window every direct send to the FID is lost. The app does re-register correctly on start (onRegistered(fid) fires within ~10 s, the SDK cache flips to the new app version, topic subscriptions on fcmregistrations.googleapis.com/.../registrations/<fid> succeed), so this is not a missing re-registration.
Root cause (verified): firebase-functions:23.0.0 still depends on the deprecated legacy firebase-iid:21.1.0 and declares Dependency.requiredProvider(FirebaseInstanceIdInternal). FirebaseContextProvider calls FirebaseInstanceIdInternal.getToken() for every callable to fill the Firebase-Instance-ID-Token header. In FID mode that legacy (app-version-bound) registration conflicts with the FID registration of the same app instance at the FCM backend. With firebase-iid excluded from the build (and a stub FirebaseInstanceIdInternal registered so FunctionsRegistrar is satisfied), the problem disappears completely: two consecutive updates showed no outage at all, the FID stayed routable from the first second. This looks like the Android counterpart of firebase/firebase-js-sdk#10135 (legacy getToken() from a callable invalidates the FID as push target), where a cross-platform fix was announced.
Steps to reproduce:
- App with
firebase_messaging_installation_id_enabled=true,firebase-messaging:26.0.0,firebase-functions:23.0.0, at least onehttpsCallableon start. Register the FID with your server. Verify with the Admin SDK:getMessaging().send({ fid, data: {...} }, /* dryRun */ true)→ OK. - Install an update with a higher
versionCode(adb install -r). Within ~15 s the dry run (and real sends) returnmessaging/installation-id-not-registered, before the app is started. - Start the app. Logcat (
setprop log.tag.FirebaseMessaging VERBOSE):Making new request for: <senderId>→Token successfully retrieved→onRegistered(fid)fires;shared_prefs/com.google.android.gms.appid.xmlshows the newappVersion. Sends keep failing with 404 for 10 min to hours. - Repeat step 2–3 with
firebase-iidexcluded from the classpath (configurations.all { exclude(group = "com.google.firebase", module = "firebase-iid") }plus a no-opFirebaseInstanceIdInternalcomponent): sends succeed from the first poll after the update and the install itself no longer invalidates the registration.
Measurements (one emulator, same FID, dry-run poll every 10–30 s; each row is one in-place update):
| Build | Change | Result |
|---|---|---|
| control 1 | none | 404 for ≥ 10.4 min (31 polls) |
| control 2 | none | 404 for ≥ 10.6 min (41 polls) |
explicit FirebaseMessaging.register() on start |
404 for ≥ 24.7 min; register() joins the same request as the auto sync, no effect |
|
unregister() then register() on start |
404 for ≥ 5 min | |
| update installed, app NOT started | 404 for ≥ 18.8 min, no self-recovery | |
firebase-iid excluded, stub component |
OK 19 s after start (after 22 min of 404 before) | |
second update with firebase-iid excluded |
OK from the first poll, 61/61 over 10 min — no outage | |
third/fourth update with firebase-iid excluded |
OK from the first poll, no outage |
Also ruled out: user interaction, Wi-Fi reconnect (GCM reconnect), Doze/screen state, a second cold start. A real (non-dry-run) data send during the window also returned 404.
Relevant Code:
// AndroidManifest.xml
<meta-data android:name="firebase_messaging_installation_id_enabled" android:value="true" />
// Workaround that removes the outage (app/build.gradle.kts)
configurations.all { exclude(group = "com.google.firebase", module = "firebase-iid") }
// Stub so FunctionsRegistrar's requiredProvider(FirebaseInstanceIdInternal) is satisfied
// (without it Provider.get() is null and every callable fails with an NPE in FirebaseContextProvider.getContext)
internal class NoLegacyInstanceId : FirebaseInstanceIdInternal {
override fun getId(): String? = null
override fun getToken(): String? = null // header omitted; our backend does not read it
override fun getTokenTask(): Task<String> = Tasks.forException(IllegalStateException("legacy IID removed"))
override fun deleteToken(senderId: String, scope: String): Unit = throw IOException("legacy IID removed")
override fun addNewTokenListener(listener: FirebaseInstanceIdInternal.NewTokenListener) = Unit
}
class LegacyInstanceIdShimRegistrar : ComponentRegistrar {
override fun getComponents() = listOf(
Component.builder(FirebaseInstanceIdInternal::class.java).factory { NoLegacyInstanceId() }.build(),
)
}
// registered via <meta-data android:name="com.google.firebase.components:...LegacyInstanceIdShimRegistrar"
// android:value="com.google.firebase.components.ComponentRegistrar"/> inside ComponentDiscoveryService
Expected: firebase-functions should not require the legacy firebase-iid (and should not fetch a legacy registration token) when the app runs FCM in FID mode — e.g. use the FID / FirebaseInstallations for the header, or make the FirebaseInstanceIdInternal dependency optional and null-safe. Alternatively the backend should not let a legacy registration of the same app instance invalidate its FID registration.
- Ngôn ngữ chính
- Java
- Star
- 2.6k
- Fork
- 733
- Merge trung bình
- 2 ngày 15 giờ
- Pull request đã merge (30 ngày)
- 72
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của firebase/firebase-android-sdk
-
api: remoteconfig
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
firebase/firebase-android-sdk#8827 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Crashlytics plugin writes build ID lists in directory listing order, so APKs can differ between machinesCó thể đã có người làm @mrober đã nhận 8 ngày trước. Đang mởapi: crashlytics
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
firebase/firebase-android-sdk#8789 · 1 bình luận · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
-
api: auth
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
firebase/firebase-android-sdk#8505 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 15/100
firebase/firebase-android-sdk#8835 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 25/100
firebase/firebase-android-sdk#8832 ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của firebase/firebase-android-sdk
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
NationalSecurityAgency/ghidra#10220 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 80/100
Maintainer thường phản hồi trong vòng 1 ngày
-
RIS export splits an organization name containing “and” into multiple authorsCó thể đã có người làm @Gautam-aman đã nhận hôm nay. Đang mởstatus: needs-triage
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
JabRef/jabref#17821 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
FailureContext.java rounds down thresholds in lastedAtLeast()Có thể đã có người làm Có pull request liên kết đang mở hoặc đã được merge. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
Maintainer thường phản hồi trong vòng 1 ngày