fix: [MR-162] enrich sub-app payloads with attribution context#278
fix: [MR-162] enrich sub-app payloads with attribution context#278janfb-codev wants to merge 5 commits into
Conversation
# Conflicts: # app/src/main/java/org/curiouslearning/container/MyApplication.java
… source, hostname and apk_package_name
📝 WalkthroughWalkthroughAttribution values from install referrers and app URLs are stored in ChangesAttribution context and event persistence
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant MainActivity
participant WebApp
participant AppContext
participant DefaultAppEventPayloadHandler
participant Firestore
MainActivity->>AppContext: hydrate source and campaign_id
WebApp->>AppContext: store hostname
DefaultAppEventPayloadHandler->>AppContext: resolve attribution and language
DefaultAppEventPayloadHandler->>Firestore: persist enriched event record
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@app/src/main/java/org/curiouslearning/container/MainActivity.java`:
- Around line 1195-1204: The hydrateAttributionContext method conditionally
preserves stale AppContext values when attribution preferences are empty or
missing. Always write both SOURCE and CAMPAIGN_ID during hydration, using the
retrieved values with their existing empty-string fallbacks, rather than
guarding the AppContext.set calls with non-empty checks.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: bf56d8fe-e89b-47e3-a454-f1f5d38dcf92
📒 Files selected for processing (5)
app/src/main/java/org/curiouslearning/container/MainActivity.javaapp/src/main/java/org/curiouslearning/container/WebApp.javaapp/src/main/java/org/curiouslearning/container/core/context/AppContextKey.javaapp/src/main/java/org/curiouslearning/container/core/subapp/handler/DefaultAppEventPayloadHandler.javaapp/src/main/java/org/curiouslearning/container/core/subapp/payload/AppEventPayload.java
| private void hydrateAttributionContext() { | ||
| SharedPreferences installReferrerPrefs = getSharedPreferences("InstallReferrerPrefs", MODE_PRIVATE); | ||
| String source = installReferrerPrefs.getString("source", ""); | ||
| String campaignId = installReferrerPrefs.getString("campaign_id", ""); | ||
| if (source != null && !source.trim().isEmpty()) { | ||
| AppContext.getInstance().set(AppContextKey.SOURCE, source); | ||
| } | ||
| if (campaignId != null && !campaignId.trim().isEmpty()) { | ||
| AppContext.getInstance().set(AppContextKey.CAMPAIGN_ID, campaignId); | ||
| } |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Clear missing attribution values during hydration.
Because AppContext persists values, these conditional writes leave the previous SOURCE or CAMPAIGN_ID intact when InstallReferrerPrefs contains an empty or missing value. Later Firestore payloads can therefore be attributed to an old campaign/source. Always write the current value or the existing empty-string fallback on every hydration.
Proposed fix
private void hydrateAttributionContext() {
SharedPreferences installReferrerPrefs = getSharedPreferences("InstallReferrerPrefs", MODE_PRIVATE);
String source = installReferrerPrefs.getString("source", "");
String campaignId = installReferrerPrefs.getString("campaign_id", "");
- if (source != null && !source.trim().isEmpty()) {
- AppContext.getInstance().set(AppContextKey.SOURCE, source);
- }
- if (campaignId != null && !campaignId.trim().isEmpty()) {
- AppContext.getInstance().set(AppContextKey.CAMPAIGN_ID, campaignId);
- }
+ AppContext context = AppContext.getInstance();
+ context.set(AppContextKey.SOURCE,
+ source == null || source.trim().isEmpty() ? "" : source.trim());
+ context.set(AppContextKey.CAMPAIGN_ID,
+ campaignId == null || campaignId.trim().isEmpty() ? "" : campaignId.trim());
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| private void hydrateAttributionContext() { | |
| SharedPreferences installReferrerPrefs = getSharedPreferences("InstallReferrerPrefs", MODE_PRIVATE); | |
| String source = installReferrerPrefs.getString("source", ""); | |
| String campaignId = installReferrerPrefs.getString("campaign_id", ""); | |
| if (source != null && !source.trim().isEmpty()) { | |
| AppContext.getInstance().set(AppContextKey.SOURCE, source); | |
| } | |
| if (campaignId != null && !campaignId.trim().isEmpty()) { | |
| AppContext.getInstance().set(AppContextKey.CAMPAIGN_ID, campaignId); | |
| } | |
| private void hydrateAttributionContext() { | |
| SharedPreferences installReferrerPrefs = getSharedPreferences("InstallReferrerPrefs", MODE_PRIVATE); | |
| String source = installReferrerPrefs.getString("source", ""); | |
| String campaignId = installReferrerPrefs.getString("campaign_id", ""); | |
| AppContext context = AppContext.getInstance(); | |
| context.set(AppContextKey.SOURCE, | |
| source == null || source.trim().isEmpty() ? "" : source.trim()); | |
| context.set(AppContextKey.CAMPAIGN_ID, | |
| campaignId == null || campaignId.trim().isEmpty() ? "" : campaignId.trim()); |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@app/src/main/java/org/curiouslearning/container/MainActivity.java` around
lines 1195 - 1204, The hydrateAttributionContext method conditionally preserves
stale AppContext values when attribution preferences are empty or missing.
Always write both SOURCE and CAMPAIGN_ID during hydration, using the retrieved
values with their existing empty-string fallbacks, rather than guarding the
AppContext.set calls with non-empty checks.
Changes
attributionblock to every enriched sub-app payload, carryingcampaign_id,source,hostname, andapk_package_name. It is written to bothuser_sessions_dataandsummary_dataFirestore records.hydrateAttributionContext()inMainActivity, populatingAppContext(SOURCE,CAMPAIGN_ID) fromInstallReferrerPrefshydrated on create, after install-referrer resolution, and on language selection.WebAppnow derivesHOSTNAMEfrom the launched sub-app URL (falling back to"unknown") and stores it inAppContext.AppContextKeywithCAMPAIGN_ID,SOURCE, andHOSTNAME; added theattributionmap field toAppEventPayload.AppContextvalues fall back to defaults so event storage never fails on absent enrichment data.How to test
user_sessions_datadocuments contain anattributionblock (campaign_id,source,hostname,apk_package_name) andmetadata.language.summary_datadocuments contain theattributionblock.hostnameresolves from the sub-app URL and defaults to"unknown"when the URL is missing.Ref: MR-162
Summary by CodeRabbit