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

Abierto
#8,711 3 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
5/5
Tiempo estimado
Más de una semana
Aptitud para principiantes
8/100
Tipo de issue
Nueva funcionalidad
Claridad
Necesita aclaración
Estado de actividad
Activo
Stack tecnológico
android, java
Área
analytics, mobile

Línea de trabajo

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.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

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.
Lenguaje dominante
Java
Estrellas
2.6k
Forks
733
Merge medio
2 d 15 h
PR fusionados (30 d)
72

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de firebase/firebase-android-sdk

Todos los issues de firebase/firebase-android-sdk

Issues similares

Más issues de Java

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.