Skip to content

InAppMessageStreamManager shouldIgnoreCache path does not refresh cached campaigns #7526

@Kennems

Description

@Kennems

Environment

  • Android Studio version: Android Studio Narwhal 3 Feature Drop | 2025.1.3
  • Firebase Component: Firebase In-App Messaging (firebase-inappmessaging)
  • Component version: main (HEAD) of this repository

Problem

When InAppMessageStreamManager.shouldIgnoreCache(eventName) returns true (e.g., app fresh install foreground event or test device), the code path fetches campaigns from the service but never writes the response back to CampaignCacheClient. If a stale campaign response already exists in the cache, it continues to be served on subsequent triggers even though the service just returned a newer campaign list.

Steps to reproduce:

  1. Build the SDK from this repository and integrate it into a sample app (or simply depend on the official Maven release).
  2. In the Firebase console, create FIAM campaigns that trigger on existing events such as old_event_a / old_event_b. Install and launch the app; confirm it fetches and caches these campaigns (logcat shows Successfully fetched N messages from backend).
  3. Without clearing the app’s data, go back to the console and add or modify campaigns so that they trigger on a brand-new event new_event_c.
  4. In the app, trigger ON_FOREGROUND (or any event that makes shouldIgnoreCache return true). Logcat now shows Successfully fetched ..., indicating the latest campaigns were retrieved from the service — but this branch does not push the response into the cache.
  5. Next, trigger new_event_c. The logs still read Attempting to fetch campaigns using cacheFetched from cache - messages count: N (only the old campaigns). selectThickContent yields empty, so the newly added campaign is never considered.
  6. Only after clearing app data or waiting for the cache to expire does the SDK fetch the updated campaign list, at which point the new event is finally honored.

Log excerpt:

Forcing fetch from service rather than cache. Test Device: false | App Fresh Install: true
Successfully fetched 1 messages from backend
Updating contextual triggers for the following analytics events: [eventName]

... later ...

Attempting to fetch campaigns using cache
Fetched from cache - messages count: 0
selectThickContent returned empty (no matching message)

Relevant Code:

// In InAppMessageStreamManager.java
if (shouldIgnoreCache(eventName)) {
  Logging.logi(
      String.format(
          "Forcing fetch from service rather than cache. Test Device: %s | App Fresh Install: %s",
          testDeviceHelper.isDeviceInTestMode(),
          testDeviceHelper.isAppInstallFresh()));
  return alreadySeenCampaigns
      .flatMap(serviceFetch)
      .flatMap(selectThickContent)
      .toFlowable();
}

// The cacheWrite consumer is only invoked on the switchIfEmpty path below.
return cacheRead
    .switchIfEmpty(
        alreadySeenCampaigns
            .flatMap(serviceFetch)
            .doOnSuccess(cacheWrite))
    .flatMap(selectThickContent)
    .toFlowable();

Expected: even when shouldIgnoreCache is true, the successful service response should be persisted via cacheWrite so later events see the updated campaigns.

Actual: the cache is left untouched; subsequent triggers read stale data from CampaignCacheClient.

Potential fix: alreadySeenCampaigns.flatMap(serviceFetch) in the shouldIgnoreCache branch should also call doOnSuccess(cacheWrite) (or share the same cache-refresh logic as the non-ignored path).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions