[Analytics] Basic Consent migration control for legacy persisted collection enablement

Aperta
#8,711 3 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
5/5
Tempo stimato
Più di una settimana
Idoneità per principianti
8/100
Tipo di issue
Funzionalità
Chiarezza
Da chiarire
Stato di attività
Attiva
Stack tecnologico
android, java
Ambito
analytics, mobile

Direzione di ricerca

This is a request for a supported migration control, not a code change. The reproduction relies on a fixture ConsentProvider with android:initOrder="1000" beside FirebaseInitProvider (initOrder 100) in the merged Manifest. Start by confirming whether a public startup option exists in the Basic Consent guide. Done means a maintainer answers the three numbered questions in the issue, or a documented limitation is confirmed. Analytics is closed-source here, so an answer from maintainers is the likely outcome.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

api: analytics type: feature request

What feature would you like to see?

A documented, supported pre-initialization migration control for Basic Consent on an Android app upgrade when a previous release persisted setAnalyticsCollectionEnabled(true) and consent grants, but the replacement release requires a new explicit Analytics opt-in.

The Basic Consent guide documents both the Manifest default and the persisted setter taking precedence over that default. We are not claiming that precedence is itself a bug. The missing contract is how to safely migrate an existing installation before automatic-event admission, including when users skip intermediate app releases.

Ideally this would be a documented startup option that temporarily takes precedence over legacy persisted enablement until the application explicitly grants consent in the current process. Alternatively, please point us to an existing supported public-API sequence that provides that boundary. This is a request for SDK/API support, not a backend DebugView troubleshooting request. I understand Analytics implementation is not open source in this repository; please redirect if this SDK feature request belongs in another official tracker.

How would you use it?

Keep optional Analytics available after explicit opt-in in the same app version, while collecting no Analytics events before that new choice. FCM and consent-eligible advertising must remain independent; advertising eligibility is not Analytics consent. Permanent Analytics deactivation and switching silently to Advanced Consent would not meet this requirement.

Environment of the synthetic reproduction
  • Android Studio: not used; command-line Gradle build.
  • JDK 17, Gradle 8.14.3, Android Gradle Plugin 8.12.2.
  • compileSdk/targetSdk 36, minSdk 24.
  • Disposable ARM64 Google APIs/Play Store emulator, API 37.1.
  • Explicit Maven dependency com.google.firebase:firebase-analytics:23.2.0; dependency inspection resolved measurement dependencies to 23.2.0.
  • Also present: firebase-messaging:25.0.2, play-services-ads:25.0.0. No FCM token or ad request was made in the consent-first sequence described below.
  • That run selected the installed Google Play services remote measurement module, whose diagnostic version was 194. This is an internal module label, not a Maven SDK version. Exact bundled-module and older-Android equivalence have not been established.
Reproduction steps
  1. Use a disposable test application with a valid test google_app_id resource and normal Firebase initialization. Never use production user data. Keep the same application ID and signing certificate throughout.
  2. Install seed versionCode 1. Using only public APIs, grant all four consent purposes and call setAnalyticsCollectionEnabled(true). Launch and verify an explicit event and automatic events as positive controls. Force-stop afterward.
  3. Install a higher-version replacement APK using adb install -r without uninstalling or clearing data. Its Manifest has firebase_analytics_collection_enabled=false. A non-exported application ContentProvider with android:initOrder="1000" calls setConsent(all four DENIED) followed by setAnalyticsCollectionEnabled(false) before Application.onCreate. Inspect the merged Manifest: the ordinary FirebaseInitProvider in this fixture had initOrder 100.
  4. Cold-start the replacement without granting the new first-party opt-in. Compare frontend markers and package-attributed measurement-service diagnostics. Enable verbose FA/FA-SVC logs on the disposable emulator; do not rely on DebugView absence as proof of no event collection.
  5. As controls, compare with a legacy-enabled upgrade without the early-denial provider, and separately exercise same-process explicit grant, withdrawal, and denied restart. Restore the seed grants with public APIs before comparing another higher-version upgrade; do not edit SDK preference files.

These are excerpts of the exercised fixture, not an independently re-executed standalone sample project. No public reproduction repository or project configuration is attached.

Manifest excerpt from the consent-first fixture (inside <application>):

<meta-data android:name="firebase_analytics_collection_enabled" android:value="false" />
<meta-data android:name="firebase_messaging_auto_init_enabled" android:value="false" />
<meta-data android:name="com.google.android.gms.ads.DELAY_APP_MEASUREMENT_INIT" android:value="true" />
<provider
    android:name=".ConsentProvider"
    android:authorities="${applicationId}.consentprobe"
    android:exported="false"
    android:initOrder="1000" />

INTERNET permission was retained. Ads SDK configuration used Google's sample app ID. The fixture did not include the four Manifest consent-default keys; denial was applied through the public API on upgrade. Adding those defaults and migrating to other SDK/runtime versions are separate unverified cases, not results claimed here.

Core public-API helper, called with true by the seed and with false by the replacement provider:

static void applyConsent(Context context, boolean granted) {
    FirebaseAnalytics analytics = FirebaseAnalytics.getInstance(context);
    EnumMap<FirebaseAnalytics.ConsentType, FirebaseAnalytics.ConsentStatus> purposes =
        new EnumMap<>(FirebaseAnalytics.ConsentType.class);
    for (FirebaseAnalytics.ConsentType purpose : FirebaseAnalytics.ConsentType.values()) {
        purposes.put(purpose, granted
            ? FirebaseAnalytics.ConsentStatus.GRANTED
            : FirebaseAnalytics.ConsentStatus.DENIED);
    }
    Log.i("ConsentProbe", "before setConsent: " + granted);
    analytics.setConsent(purposes);
    analytics.setAnalyticsCollectionEnabled(granted);
    Log.i("ConsentProbe", "both public calls returned: " + granted);
}

Replacement provider excerpt (the other required ContentProvider overrides are no-ops):

@Override public boolean onCreate() {
    applyConsent(getContext(), false);
    return true;
}

All-purpose seed grants/denials are a synthetic diagnostic contrast, not a recommendation to couple advertising and Analytics choices in an application.

Observed ordering and limits

In the consent-first no-clear upgrade capture, taking the application's “both public calls returned: false” marker as T+0:

Relative time Observation
T+817 ms Frontend storage-denial processing log
T+939 ms Frontend collection-disabled processing log
T+956 ms Measurement service logs automatic app_update
T+1071 ms Measurement service logs package storage denial
T+1089 ms Measurement service logs DMA denial

Explicit application event markers afterward were rejected. The legacy-enabled positive control logged app_update. A later explicit grant admitted application markers; withdrawal rejected subsequent explicit markers, although already-accrued engagement was logged after withdrawal. A bounded denied-restart capture rejected explicit markers; that absence is not a universal no-collection proof.

These observations establish diagnostic event logging/admission order, not transmission of the pre-opt-in event, backend receipt, production-user impact, or an identifier leak. Network transport was not the acceptance measure. No raw user-device logs, project identifiers, credentials, or production configuration are attached.

Issue #5697 discusses events under storage-denied consent and DebugView visibility. This request differs: it concerns Basic collection disabled on a no-clear upgrade from persisted enabled/granted state, rather than expecting Advanced Consent to suppress all events.

Requested clarification / acceptance contract
  1. Is there a supported public startup/migration control that applies before measurement initialization reads a legacy persisted collection grant, without private preference writes, reflection, undocumented Bundle keys, or a custom ClassLoader?
  2. If an early public getter/setter is the supported approach, what guarantees ordering across the frontend and the Play services measurement process, and how should an app verify that boundary?
  3. If this is not supported today, could you add a migration option or document the limitation and the supported alternative? The solution should allow same-release explicit grant/withdraw/restart and users skipping intermediate releases, without disabling unrelated Firebase products.
Lingua principale
Java
Stelle
2.6k
Fork
733
Merge medio
2g 15h
PR unite (30g)
72

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di firebase/firebase-android-sdk

Tutte le issue di firebase/firebase-android-sdk

Issue simili

Altre issue su Java

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.